AnsweredAssumed Answered

Issues running MQX in DDR on K70

Question asked by avm on Nov 27, 2013
Latest reply on Mar 13, 2015 by Pravin Falcao

Happy Thanksgiving to all!


I'm trying to develop an MQX application that is a bootloader that resides in internal flash. It uses eGUI to initialize the LCDC and display status messages on the LCD screen, searches for an MQX application image on the SD card, loads it into DDR memory, and runs it. I'm close, but I'm running into problems: the loaded application starts up, and gets through MQX initialization, then crashes on the first interrupt.


Using the information from this thread, I have a simple MQX test application that the debugger can load into DDR memory, and it runs perfectly that way:


But it doesn't run properly when launched by my bootloader. The BSPs for both the bootloader and application are configured to place the interrupt vectors in RAM. The application BSP has been modified according to the thread referenced above to not re-initialize the clock and DDR controller. I have verified that the bootloader properly loads the image into RAM by comparing the loaded RAM contents with the original image file contents. The bootloader transfers to the application by disabling interrupts, loading LR with 0xffffffff, loading SP with the initial value from the application's start vector, and branching to the PC from the application's start vector.


My board has a buzzer, and I added a little test code to the loaded application to sound the alarm before it starts up MQX. I do get the beep during startup when the bootloader loads the code then launches the application, so I know it's getting that far. (If I use the full BSP that doesn't have the clock and DDR initialization sections trimmed out as per the above thread, then this beep doesn't happen: presumably re-initializing the clock and/or DDR controller affects the DDR refresh and corrupts the memory.)


If I step through the MQX initialization function _mqx(), I can see that the interrupt vectors gets properly set up, and the VTOR register points to them. Everything appears to initialize properly, all the way through creating the auto-start tasks. At the end of _mqx(), once everything is initialized, it calls _sched_start_internal() which simply executes an SVC instruction to generate a software interrupt to enter the scheduler. It is right around here where the application crashes, and interestingly, this is where I see the first difference in behavior between running this application directly from the debugger, and running it from the bootloader.


When running from the debugger, the SVC call properly jumps through the SVCall vector to the _svc_handler() function. But when I step through the SVC call when launched by the bootloader, it either crashes immediately, or it reaches the CPSID instruction to disable interrupts at the beginning of _int_kernel_isr(), and stepping through that instruction causes a crash. So, when launched by the debugger, the SVC instruction reaches _svc_handler() as expected, but when launched from the bootloader it reaches the general interrupt ISR.


Looking at the ICSR register just before stepping through the SVC call, I see it has the value 0x00400000 (ISRPENDING) when launched from the debugger, and 0x0440f000 (PENDSTSET + ISRPENDING + exception 15 pending) when launched from the bootloader. So it looks like a SysTick interrupt is pending when the SVC instruction is executed, so it goes to process that interrupt first? But why does that cause a crash?


Thinking that perhaps it can't handle an interrupt until the first time through the scheduler (maybe a different stack must be selected?) I tried clearing all of the SysTick registers to stop the counter before launching the application. It doesn't make any difference, the application still doesn't seem to get any farther than before. (Trying to step the debugger through the transition from the bootloader in flash to the application in DDR is not completely reliable, and since I've stopped the SysTick counter, I've not been able to step to the SVC call to see what difference that has had in the ICSR register.)


I've reached a brick wall, and have not been able to get past this point for many days.


Does anyone see anything I'm missing or something I'm doing wrong? Anybody got any ideas what I should try next or what I should look at?


Edit: I probably should've mentioned that it's MXQ 4.0 and Code Warrior 10.2, using a custom BSP on a custom board. The DDR memory configuration is identical to that on the K70 Tower board. The custom BSP is derived from the twrk70f120 BSP.