4

I try to create a custom bootloader for an STM32L1 series card, and I need to put my bootloader code at the bottom of my flash memory. Then I can flash my memory properly.

I know it can be specified in the linker script, but I don't know how to do that.

I declared my bootloader section like this:

.bootsection :
{
  . = ALIGN(4);
  KEEP(*(.bootsection)) /* Bootloader code */
  . = ALIGN(4);
} >FLASH

And my memory is set like this:

MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 80K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
}

What is the command?

9
  • Maybe try changing >FLASH to >FLASH AT> FLASH Commented Jun 11, 2015 at 12:01
  • something like >FLASH AT 0x0...? Commented Jun 11, 2015 at 12:03
  • That's not proper linker script syntax... I think doing that will give you a syntax error. Commented Jun 11, 2015 at 12:04
  • Also, I feel like your question is a little unclear. Can you please explain why your current linker script is not working? Also, what's up with the MEMORY_B1? Why is it's length 0? Commented Jun 11, 2015 at 12:05
  • this linker script is working , i did not gave you all the script code . I don't know what is this MEMORY_B1, i think i can delete it. Commented Jun 11, 2015 at 12:11

1 Answer 1

2

Here is my linker script. I tried something with a new memory section.

MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 510K
  MEM_BOOT (rx)   : ORIGIN = 0x0807CFFE, LENGTH = 2K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 80K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH


  .bootsection :
  {
    . = ALIGN(4);
    KEEP(*(.bootsection)) /* Bootloader code */
    . = ALIGN(4);
  } >MEM_BOOT

Here's my boot code. I wrote the flash program, but the erase program is not written yet.

#define MY_BL_FUNCTIONS __attribute__((section(".bootsection")))

void BootLoader(void) MY_BL_FUNCTIONS;
uint8_t Flash_Write(uint32_t StartAddress, uint8_t *p, uint32_t Size) MY_BL_FUNCTIONS;

void BootLoader(void)
{
    char buffer[1000];
    int i = 0;
    /* Test if we enter the bootloader. Toggle the LED and
       send a string to the USART */
    GPIO_ToggleBits(GPIOA, GPIO_Pin_5);
    do
    {
        buffer[i] = Uart2ReadChar();
        i++;
    } while (buffer[i] != '\0');

    SendString(buffer, USART2);
}

uint8_t Flash_Write(uint32_t StartAddress, uint8_t *p, uint32_t Size)
{
    uint32_t idx;
    uint32_t Address;
    __IO FLASH_Status status = FLASH_COMPLETE;

    Address = StartAddress;

    /* Unlock the FLASH program memory */
    FLASH_Unlock();

    /* Clear all pending flags */
    FLASH_ClearFlag(FLASH_FLAG_EOP     |
                    FLASH_FLAG_WRPERR  |
                    FLASH_FLAG_PGAERR  |
                    FLASH_FLAG_SIZERR  |
                    FLASH_FLAG_OPTVERR);

    while (Address < StartAddress + Size)
    {
        status = FLASH_FastProgramWord(Address, *(uint32_t *)p);
        Address = Address + 4;
        p = p + 4;
        if (status != FLASH_COMPLETE)
            return status;
    }

    /* Lock the flash program memory */
    FLASH_Lock();

    return (uint8_t)status;
    }
Sign up to request clarification or add additional context in comments.

1 Comment

There seems to be a bug in your Flash_Write() code. If the function FLASH_FastProgramWord() return a different value of FLASH_COMPLETE, your function exits and leave flash memory unlocked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.