Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

PendSVC fail on M0 of LPC43xx

2014-06-16
2014-06-16
  • I've spent weeks grinding my way through getting FreeRTOS to actually run on the secondary M0 core of the LPC4350. First was getting the RGU_RESET register polarity right, then determining that NXP neglected to put a SysTick timer on the M0 and completely failed to mention this rather fundamental fact in the documentation.

    At this point I have a "port" of FreeRTOS that will compile and run directly on the main M4 via openocd and gdb. It replaces SysTick with LPC's RITimer, and successfully runs two tasks with vTaskDelay() that flash LEDs. A debug LED confirms that the FreeRTOS RITimer interrupt handler is indeed running as it should.

    FWIW, I have my linker script set to keep everything in SRAM, at 0x10000000. The MEMMAP register for the M4 is set to that (remapping 0x00000000 to 0x10000000) and runs from there.

    Now, I recompile it to target the M0, which means changing compiler parameters as well as the interrupt table (though I can actually cheat since the RITimer is in the same vector slot, and the M4's vector table is longer so it just "wastes" the extra vectors). The M4 loads the binary image into 0x10000000, set's the M0APP REMAP to that address, and starts up the M0.

    At this point, I get the two tasks running and toggling their LEDs, then a set of RITimer interrupts toggling it's debug LED. However, as soon as the first timer expires, the M0 halts. My first attempt at keeping RITimer running was to comment out the trigger of the PendSVC interrupt in xPortSysTickHandler (renamed to xPortRITimerHandler in my "port"), but strangely that didn't do it. I had to comment out the entire block that ran xTaskIncrementTick() and checked its output in order for the RITimer not to stop running.

    Any idea why moving working code from the M4 to the M0 would fail like this? Also, any idea how I can actually get GDB working in such a way as to debug the M0? As it stands I'll have to move around LED debugging lines in order to try to track down what's going on, and that gets old fast.

    I'll post code snippets as requested because there's a lot going on.

    Thanks!

     
  • FWIW I've narrowed it down to failing somewhere during prvAddTaskToReadyList(pxTCB) inside xTaskIncrementTick(), comment / Place the unblocked task into the appropriate ready list. /

    I am unable to get any deeper than that because I don't have any way of single-stepping until I can figure out how to get GDB to work.

    My suspicion is that maybe somehow the memory arrangement is still out of whack. The image loaded is a simple objcopy -O binary of the ELF, which comes to the correct size (including heap and stack, with linker in RAM-only mode) has worked otherwise.

     
  • It sounds like you are trying to run the FreeRTOS Cortex-M3/4 port on a Cortex-M0 part. Is that the case? If so it won't work as the CM0 does not have the basepri register. There is a FreeRTOS Cortex-M0 port layer in FreeRTOS/source/portable/GCC/ARM_CM0, but that won't work either for the reason you already discovered - no SysTick timer.

    However themselves do have their own adapted port for the M0 core of that chip, as well as some examples of how to use it. Have you looked at that? I imagine you will be able to find it somewhere on http://www.lpcware.com.

    Hope that helps.

    Regards,
    Richard Barry.

     
    • No, I am using the M0 port as the base. Switching between the M4 build and M0[APP] build involves altering the Makefile. As it turns out, the M0 port actually works just fine running on the M4 as long as the -mcpu flag is switched, because both SysTick and RITimer are at the same vector.

      I have the LPCOpen port, but it's not very well laid out - they leave the M0 port.c in place with it's SysTick references, then add a file for the RITimer. The rtimer_setup() function is then #defined as the result of prvSetupTimerInterrupt(), except the port.c version of the actual function is still there, which I guess "works". Then they have zero linker scripts or Makefiles, so I have no idea how it's actually supposed to be built.

      I'll keep digging through their code, maybe see if I can figure out how on earth they're supposed to be built and whether that tells me anything new.

      Also, I've confirmed the M0 core is hitting a Hard Fault.