Bootloader Update Error

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Bootloader Update Error

2,570 Views
jonathan_guinta
Contributor I

Hi,

I'm having issues implementing a bootloader update.

Specs: CPU: MKL15Z128VFT4

OS: BareMetal

IDE: KDS 3.0.0

Drivers Used:

C90TFS Flash Driver

SPI Driver

Scenario:

I'm fetching 1kB at a time from SPI flash and writing 1KB (1 sector) to uC program flash.

My bootloader is from 0x0000_0000 to 0x6C00

My appcode is from 0x0000_7200 to 0x0001_FFFF

I know this isn't the best use of space, right now I'm just trying to debug the process to see if I can get consistent reads from SPI flash and writes to the uC program memory location.

In the code process here's sequence

move C90TFS function FlashCommandSequence to RAM

//each read/write is for 1kB

for(i = 0; i < numReads; i++)

{

1. read 1 kB from SPI flash

2. Enter Critical section - shut off Interrupts (ie OSA_EnterCritical(kCriticalDisableInt))

3. Disable OSA interrupt (ie SysTick->CTRL = mask & 0xFFFD)

4. erase 1kB sector on uC app area starting at 0x0000_6C01

5. verify erase section

6  program 1 kB sector

7. program check 1kB sector

8. Enable OSA interrupt

9. Exit critical section

}

I've moved the C90TFS function FlashCommandSequence to RAM to avoid access violations. When I run through the loop I'm always able to get through 2 iterations and the program craps out when I try to do a SPI read on the 3rd iteration.

1st iteration: write to 0x7200 of uC program flash

2nd iteration: write to 0x7600 of uC program flash

3rd iteration: 0x7A00 target address - the program fails at the location where I set the baud rate in the SPI_HAL_SetBaud method of the SPI peripheral. This is part of the SPI_DRV_MasterTransferBlocking method of the SPI peripheral. All values of the equation look correct, but the debugger console shows the message WARNING: T-bit of XPSR is 0 but should be 1. The initial error is Cannot read register 15 (R15) while CPU is running. Target halted PC = 0x0000_0000

Does any one have any thoughts I what is going on that would cause this to happen? Am I having a memory access issue here? I had thought that the FlashCommandSequence method doesn't return until the CCIF bit is cleared, so I can't imagine a uC program flash write is occurring that this time.

Message was edited by: Jonathan Guinta Additional information: I've also added the code suggested by https://community.freescale.com/docs/DOC-103951 for the ESFC bit since I'm using an ARM M0+ https://community.freescale.com/thread/372923 and turned on and off the interrupts via OSA_EnterCritical and OSA_Exit critical right before and after the flash routines. To turn off the SysTick interrupt. I'm using this for the OSA_TimeDelay method. I'm now able to run the flash programming successfully for about 7 kB of flash and then it crashes again when I enter the SPI_TransferBlocking method where it crashes at the OSA_SemaWait (the semaphore wait routine). This problem still appears to be related to the SysTick timer issue. Does anyone have any suggestions on this one? I'm trying to switch between the flash programming and fetching the flash data from SPI flash, which I was using the SysTick timer for. Are the shutting on and off of (INT_SYS_DisableIRQGlobal and INT_SYS_EnableIRQGlobal) not consistent for the SysTick interrupt routine? Is there an issue with shutting on and off these Interrupts for every 1kB of programming? I know every time you turn on a critical section the context needs to be put on the stack. Any recommendations would be awesome, thanks!

Labels (1)
0 Kudos
Reply
7 Replies

1,452 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Jonathan Guinta:

The issue you have seems to be an unpredictable behavior.

I am curious about your mentions of SysTick. Are you using Processor Expert?

By default the OSA layer for baremetal mode in KSDK uses the LPTMR, only PEx lets you select between LPTMR and SysTick.

- I would first use the LPTMR for OSA timing to confirm that the SPI transfers work as expected.

- Then I don't know the SPI baudrate you use but if it is high then another test would be to reduce it and see if the problem is diminished.

Let us know about further findings.


Best Regards!
Jorge Gonzalez

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

1,452 Views
jonathan_guinta
Contributor I

Hey Jorge,

I placed the RelocateFunction in the loop that fetches 1kB from SPI flash and writes 1kB to internal program memory. This allows me to continually read from SPI flash at all addresses and write to the internal flash at a single address (overwriting the previous values fetched from spi flash at each iteration), but only at a single address internal program flash address. The addresses I've tried for the internal flash that work are 0x10000 and 0x11000. Address 0x12000 write failure manifests itself as:  I can write to it successfully, but when I try to read from spi flash again, the program crashes (hits DefaultIRQ). I've looked at the map file and nothing stood out to me as overlapping the addresses of the bootloader fw. Here's the linker file for the bootloader:

. BootloaderError4.png

I must be doing something dumb, but I'm not sure what else to do at this point. I'm at a loss.

Just to reiterate specs:

chip MKL15Z128VFT4

I tried wrapping internal flash methods with Enter and Exit Critical. I had MCM_PLACR |= MCM_PLACR_ESFC_MASK. I copied FlashCommandSequence to RAM every iteration of the loop, not sure why this would be necessary, but appears to help. I'm using the LPTMR for the OS BareMetal.

Is there anything else I may be missing that you see?

Regards,

Jon

I've attached the code for reference.

0 Kudos
Reply

1,452 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hi Jonathan:

I cannot understand your algorithm well and you have some wrapper functions not shown (like m_flashController.readData) but at first sight I cannot see what is wrong.

However what called my attention is that both __ram_func[ ] and g_FlashLaunchCommand should be global and it seems in your code they are not. Try defining those as global.

Another thing that comes to my mind is compiler optimizations. If you have any optimizations enabled, try to disable them. Sometimes the compiler being "smart" causes headaches.

Regards!
Jorge Gonzalez

0 Kudos
Reply

1,452 Views
jonathan_guinta
Contributor I

Hi Jorge,

So I was able to get to the bottom of it. In the structure provided by the C90TFS driver, the FLASH_SSD_CONFIG struct, the .PFlashBase should be at 0x00 and the .PFlashSize should be at 131072U (128kB). I had no idea these values were supposed to reflect the whole range of the program flash. I had thought they were provided for the programmer to specify within the program flash region where they wanted to program the application code, the subregion. I guess not, this appeared to be the source of the problem.

Jon

0 Kudos
Reply

1,452 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Jonathan:

I am glad to know you found the root cause. You are right, the configuration structure for the C90TFS driver is a description of the whole Flash memory, not only the used space.

I hope you are moving forward. In any further case please do not hesitate to ask.

Regards!

Jorge Gonzalez

0 Kudos
Reply

1,452 Views
jonathan_guinta
Contributor I

Hi Jorge,

I've made __ram_func global and g_FlashLaunchCommand global. I've also checked the compiler optimization settings and have these turned on right now:

Optimization Level: None- O0

Message Length - checked

'char' is signed - checked

Function sections - checked

Data sections - checked

Right now I've removed the spi read from the code and I'm now just trying to implement writing a 1kB sector of zeros to each sector from 64kB to 128kB of program memory. So I start at address 0x10000.

Experiment 1: (with your changes implemented for global variables)

I can completely write up through addres 0x12400 and then the program crashes when I try to enter critical section before executing the flash methods in the iteration of the loop. So that's 9 successful writes. (it complains about not being able to read the registers while the cpu is running)

Exeriment 2: (with enter and exit critical wrappers for flash methods removed)

I can completely write up through address 0x13400 and then the program crashes when I try to program sector @ 0x13800. So that's 13 successful writes and then a crash. (it complains about not being able to read the registers while the cpu is running)

In the attached files, just like before, the Flash_Manager I'm using for writing to internal flash and calling the method to read from spi flash. The Flash.cpp is the wrapper for reading and writing to spi flash. At this point I've removed the spi flash read/write from the equation and I'm exclusively doing the writing of 1kB sectors of zeros to the internal program flash. Any thing else you may think of that I'm doing wrong here?

Regards,

Jon

0 Kudos
Reply

1,452 Views
jonathan_guinta
Contributor I

Update:

I tried switching to LPTMR for the User Timer for the BareMetal OS. No improvement. I also tried slowing the SPI driver down to 11.7 kHz from what it was originally at 3.49 MHz, and no improvement. I'm now trying what I did before where I read from the same address in SPI flash continually and writing to subsequent addresses in internal uC program flash using the C90TFS driver and I'm no longer able to successfully make writes completely from 64kB-128kB region of program flash. I also tried changing my buffer to a pointer and putting it on the heap to see if it would help at all with stack overflow, no improvement. I'm at a loss, not sure what else to do. At present, I have the exitCritical and enterCritical removed from the code and also have the initialization and de-initialization of the SPI driver removed from the code in between instances of writing to the internal uC program flash.

I can't imagine no one has ever done this before: writing from external peripheral to internal flash using C90TFS driver. Unfortunately none of the examples I could find include this, so I don't have a point of comparison.

If you have any other suggestions please let me know! I've been working on this for days.... and the project needs to get done for work.

0 Kudos
Reply