最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Problem with jumping to application - STM32 Bootloader - Stack Overflow

programmeradmin2浏览0评论

I am making software bootloader for my STM32F407, and i managed to successfully write firmware in flash, starting at address 0x08004000 and I want to jump to it so my board can start executing that firmware.

Here is my code which is not working:

void jumpToApplication(void) {
    // Explicit debug markers
    sendUSART2('D');  // Debug start marker
    sendUSART2('1');  // First debug point

    // Read the initial stack pointer (first 4 bytes of vector table)
    uint32_t* stack_pointer = (uint32_t*)0x08004000;
    
    // Explicit null check
    if (!stack_pointer) {
        sendUSART2('N');  // Null pointer error
        toggleErrorLed();
        return;
    }

    sendUSART2('2');  // Second debug point

    // Explicit value sending with multiple characters
    sendUSART2('S');  // Stack pointer indicator
    sendUSART2('P');  // Prefix for stack pointer value
    
    // Send each byte of the stack pointer value
    uint32_t sp_value = *stack_pointer;
    sendExactValue(sp_value);
    
    sendUSART2('3');  // Third debug point

    // Read the reset vector (address of reset handler, 4 bytes after stack pointer)
    uint32_t* reset_vector = (uint32_t*)(0x08004000 + 4);
    
    // Explicit null check
    if (!reset_vector) {
        sendUSART2('M');  // Null reset vector error
        toggleErrorLed();
        return;
    }

    sendUSART2('4');  // Fourth debug point

    // Send reset vector value
    sendUSART2('R');  // Reset vector indicator
    sendUSART2('V');  // Prefix for reset vector value
    
    // Send each byte of the reset vector value
    uint32_t rv_value = *reset_vector;
    sendExactValue(rv_value);

    sendUSART2('5');  // Fifth debug point

    // Validate stack pointer is in valid RAM range
    if ((sp_value & 0x2FFE0000) != 0x20000000) {
        // Invalid stack pointer
        sendUSART2('I');  // Invalid stack pointer error
        sendUSART2('S');
        toggleErrorLed();
        return;
    }

    sendUSART2('6');  // Sixth debug point

    // Validate reset vector is in valid Flash range
    if ((rv_value & 0xFFF00000) != 0x08000000) {
        // Invalid reset vector (not in Flash memory)
        sendUSART2('I');  // Invalid reset vector error
        sendUSART2('R');
        toggleErrorLed();
        return;
    }

    sendUSART2('7');  // Final debug point

    // Disable all interrupts
    __disable_irq();

    // Set the vector table location
    SCB->VTOR = 0x08004000;

    // Load the stack pointer
    __set_MSP(*stack_pointer);

    // Create function pointer to reset handler
    void (*app_reset_handler)(void) = (void*)(*reset_vector);

    // Jump to application
    app_reset_handler();
}

According to debug I'm getting "invalid stack pointer" error.

I am making software bootloader for my STM32F407, and i managed to successfully write firmware in flash, starting at address 0x08004000 and I want to jump to it so my board can start executing that firmware.

Here is my code which is not working:

void jumpToApplication(void) {
    // Explicit debug markers
    sendUSART2('D');  // Debug start marker
    sendUSART2('1');  // First debug point

    // Read the initial stack pointer (first 4 bytes of vector table)
    uint32_t* stack_pointer = (uint32_t*)0x08004000;
    
    // Explicit null check
    if (!stack_pointer) {
        sendUSART2('N');  // Null pointer error
        toggleErrorLed();
        return;
    }

    sendUSART2('2');  // Second debug point

    // Explicit value sending with multiple characters
    sendUSART2('S');  // Stack pointer indicator
    sendUSART2('P');  // Prefix for stack pointer value
    
    // Send each byte of the stack pointer value
    uint32_t sp_value = *stack_pointer;
    sendExactValue(sp_value);
    
    sendUSART2('3');  // Third debug point

    // Read the reset vector (address of reset handler, 4 bytes after stack pointer)
    uint32_t* reset_vector = (uint32_t*)(0x08004000 + 4);
    
    // Explicit null check
    if (!reset_vector) {
        sendUSART2('M');  // Null reset vector error
        toggleErrorLed();
        return;
    }

    sendUSART2('4');  // Fourth debug point

    // Send reset vector value
    sendUSART2('R');  // Reset vector indicator
    sendUSART2('V');  // Prefix for reset vector value
    
    // Send each byte of the reset vector value
    uint32_t rv_value = *reset_vector;
    sendExactValue(rv_value);

    sendUSART2('5');  // Fifth debug point

    // Validate stack pointer is in valid RAM range
    if ((sp_value & 0x2FFE0000) != 0x20000000) {
        // Invalid stack pointer
        sendUSART2('I');  // Invalid stack pointer error
        sendUSART2('S');
        toggleErrorLed();
        return;
    }

    sendUSART2('6');  // Sixth debug point

    // Validate reset vector is in valid Flash range
    if ((rv_value & 0xFFF00000) != 0x08000000) {
        // Invalid reset vector (not in Flash memory)
        sendUSART2('I');  // Invalid reset vector error
        sendUSART2('R');
        toggleErrorLed();
        return;
    }

    sendUSART2('7');  // Final debug point

    // Disable all interrupts
    __disable_irq();

    // Set the vector table location
    SCB->VTOR = 0x08004000;

    // Load the stack pointer
    __set_MSP(*stack_pointer);

    // Create function pointer to reset handler
    void (*app_reset_handler)(void) = (void*)(*reset_vector);

    // Jump to application
    app_reset_handler();
}

According to debug I'm getting "invalid stack pointer" error.

Share Improve this question asked Mar 28 at 0:54 dinajsdinajs 1181 silver badge6 bronze badges 2
  • It might help for you to edit your question and post a bit of the raw/final firmware data you send (from python). In addition to a dump, what is the expected SP value being sent? Then, what data the loader sends back (e.g SPxxxx and RVyyyy). Yes, you're getting an invalid stack pointer, but what value are you getting? Are you verifying the burn by comparing the ROM data to the packet buffer? Are bytes corrupted/random or are they just out of place? That is, do you see a known/valid value for SP/RV somewhere but at the wrong buffer offset? – Craig Estey Commented Mar 28 at 1:29
  • The code you posted here is correct (AFAICT). I presume this data comes from chunk 0. Per my answer to your prior question: STM32F407 Software Bootloader - Problem with receiving UART data I assume you're [now] verifying that each chunk was burned successfully by comparing it. To test, you could hardwire the correct bytes into the loader and have it compare the data in the ROM area (SP/RV values) to ensure that a subsequent chunk doesn't overwrite the first one at each step. Without your latest full loader code, it's difficult to say more – Craig Estey Commented Mar 28 at 3:07
Add a comment  | 

1 Answer 1

Reset to default 0

Since the STM32F407 has 512kB flash memory, the jump address might shift depending on the memory layout. Had the same problem when I moved to a bigger MCU.

So try using this instead:

    if ((sp_value & 0x2FFC0000) != 0x20000000) 
发布评论

评论列表(0)

  1. 暂无评论