This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Keil RTX based bootloader launching Keil RTX based FW

Hello. I inherited a project that is running on a TI TM4C1230H6PM microcontroller and I've run into a bit of a snag.

We have a bootloader running Keil RTX that starts at address 0x0000 which ultimately launches FW running Keil RTX starting at address 0x8000. After adding lots of new functionality to the FW (including several new tasks) I found that we were encountering random stack overflow issues.

After some heavy debugging, I discovered that the Main Stack Pointer (MSP) was overrunning the stack of one of my new tasks and causing the error. Essentially, what I see happening is that when the code jumps over from the bootloader to the FW the MSP is loaded with the initial stack pointer from the bootloader (0x20003EB8) loaded from address 0x0000. This, apparently, never caused an issue in the past, but I now have a task whose stack ends at 0x20003E38. So, not only is the main stack not where it should be, but it's dangerously close to the top of a process stack.

The original code to jump from the bootloader to the firmware looked as follows

jump(*(U32 *)code_start, *(U32 *)(code_start + 4));

; jump to application code
        AREA    asm_func, CODE, READONLY
        EXPORT  jump
jump
        MOV     R13, R0
        BX      R1
      END

The problem I found here is that this executes in User context and so R13 refers to the PSP rather than the MSP.

I tried several different ways of resolving this issue by loading the contents (0x20007280) of address 0x8000 into the MSP register prior to branching, but no matter what I do I get a hardware fault almost immediately after the FW begins to run.

Can anyone shed some light on what's going on here?

Any assistance in solving this would be greatly appreciated.

Parents
  • The code I used to jump to application FW from bootloader is listed below:

    typedef    void (*pFunction)(void);
    uint32_t   timingdelay;
    pFunction  Jump_To_Application;
    uint32_t   JumpAddress;
    
    
    // function which never returns,
    // if conditions not met, return with 0
    
    BOOL JumpToFirmware(void)
    {
       int USER_FLASH_FIRST_PAGE_ADDRESS;
    
       USER_FLASH_FIRST_PAGE_ADDRESS = 0x08020200;
    
       // Check if valid stack address (RAM address) then jump to user application
       if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000) {
          // Jump to user application
          JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
          Jump_To_Application = (pFunction) JumpAddress;
    
          // Initialize user application's Stack Pointer
          __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
          Jump_To_Application();
       }
    
       return 0;
    }
    

    Georg

Reply
  • The code I used to jump to application FW from bootloader is listed below:

    typedef    void (*pFunction)(void);
    uint32_t   timingdelay;
    pFunction  Jump_To_Application;
    uint32_t   JumpAddress;
    
    
    // function which never returns,
    // if conditions not met, return with 0
    
    BOOL JumpToFirmware(void)
    {
       int USER_FLASH_FIRST_PAGE_ADDRESS;
    
       USER_FLASH_FIRST_PAGE_ADDRESS = 0x08020200;
    
       // Check if valid stack address (RAM address) then jump to user application
       if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000) {
          // Jump to user application
          JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
          Jump_To_Application = (pFunction) JumpAddress;
    
          // Initialize user application's Stack Pointer
          __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
          Jump_To_Application();
       }
    
       return 0;
    }
    

    Georg

Children