STM32f103VET6 Bootloader jump problem.

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32f103VET6 Bootloader jump problem.

Post by Giovanni »

Post what you think could help on the forum, no guarantee, it is very out of scope of ChibiOS support.

Giovanni
franek.bmw
Posts: 57
Joined: Thu Mar 13, 2014 11:15 am
Has thanked: 2 times

Re: STM32f103VET6 Bootloader jump problem.

Post by franek.bmw »

This is linker script which I use. It is good, when the app works without bootloader and flash offset.

Code: Select all

/*
Default linker script for STM32F10x
Martin Thomas, 9/2009
A heavily modified "Default linker script for STM32F10x_512K_64K"
Copyright RAISONANCE S.A.S. 2008 found in the STM fw-library.
*/

/* Program Entry, set to mark it as "used" and avoid gc */
ENTRY(Reset_Handler)

/* Memory Spaces Definitions */
MEMORY
{
  RAM      (RWX) : ORIGIN = 0x20000000, LENGTH = 64K
  EXTSRAM  (RWX) : ORIGIN = 0x68000000, LENGTH = 0
  FLASH    (RX)  : ORIGIN = 0x08020000, LENGTH = 512K - 128K -2K
  EEMUL    (RWX) : ORIGIN = 0x08020000+512k-128K - 2K, LENGTH = 2k
  FLASHB1  (RX)  : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (RX)  : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (RX)  : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (RX)  : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (RX)  : ORIGIN = 0x00000000, LENGTH = 0
}

/* higher address of the user mode stack */
_estack = ORIGIN(RAM)+LENGTH(RAM);

/* start of the two 1kByte pages used by EEprom emulation at end of flash */
_seemul = ORIGIN(EEMUL);

/* There will be a link error if there is not this amount of RAM free at the end. */
_Minimum_Stack_Size = 0x100 ;

/* Check valid alignment for VTOR */
ASSERT(ORIGIN(FLASH) == ALIGN(ORIGIN(FLASH), 0x80), "Start of memory region flash not aligned for startup vector table");

/* Sections Definitions */

SECTIONS
{

    /* the program code is stored in the .text section, which goes to Flash */
    .text :
    {
        . = ALIGN(0x80); /* PM0056, Rev.1 (4/2009), 4.3.3 */
        _isr_vectorsflash_offs = . - 0x08000000;
        KEEP(*(.isr_vectorsflash)) 
       

      
       . = ALIGN(4);
        *(.text)                   /* code */
        *(.text.*)                 /* remaining code (-ffunction-sections)*/
        *(.stub .gnu.linkonce.t.*)
        *(.rodata .rodata.* .gnu.linkonce.r.*) /* read-only data (constants) */
        *(.glue_7 .glue_7t)        /* redundant for thumb2 ?! */
        _etext = .;
      _sidata = _etext;
        . = ALIGN(4);
   } >FLASH

    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH to RAM. */
    .data  : AT ( _sidata )
    {
        . = .;
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data section */
        _sdata = . ;


      . = ALIGN(4);
      _adresZaWektoremPrzerwan = .;
      KEEP(*(.pFuncArr))                /* functions pointers array */
      
        . = ALIGN(0x80);
        _isr_vectorsram_offs = . - 0x20000000;
        KEEP(*(.isr_vectorsram))
        . = ALIGN(4);

        *(.ramfunc*)
        . = ALIGN(4);
        *(.data .data.* .gnu.linkonce.d.*)
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data section */
        _edata = . ;
    } >RAM


    /* This is the uninitialized data section */
    .bss (NOLOAD):
    {
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .bss section */
        _sbss = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
         /* This is used by the startup in order to initialize the .bss section */
         _ebss = . ;
    } >RAM

    PROVIDE ( end = _ebss );
    PROVIDE ( _end = _ebss );
   
    /* This is the user stack section
    This is just to check that there is enough RAM left for the User mode stack
    It should generate an error if it's full.
     */
    ._usrstack (NOLOAD):
    {
        . = ALIGN(4);
        _susrstack = . ;
        . = . + _Minimum_Stack_Size ;
        . = ALIGN(4);
        _eusrstack = . ;
    } >RAM


    /* this is the FLASH Bank1 */
    /* the C or assembly source must explicitly place the code or data there
    using the "section" attribute */
    .b1text :
    {
        *(.b1text)                   /* remaining code */
        *(.b1rodata)                 /* read-only data (constants) */
        *(.b1rodata*)
    } >FLASHB1
   
    /* this is the EXTMEM */
    /* the C or assembly source must explicitly place the code or data there
    using the "section" attribute */
   
    /* EXTMEM Bank0 */
    .eb0text :
    {
        *(.eb0text)                   /* remaining code */
        *(.eb0rodata)                 /* read-only data (constants) */
        *(.eb0rodata*)
    } >EXTMEMB0
   
    /* EXTMEM Bank1 */
    .eb1text :
    {
        *(.eb1text)                   /* remaining code */
        *(.eb1rodata)                 /* read-only data (constants) */
        *(.eb1rodata*)
    } >EXTMEMB1
   
    /* EXTMEM Bank2 */
    .eb2text :
    {
        *(.eb2text)                   /* remaining code */
        *(.eb2rodata)                 /* read-only data (constants) */
        *(.eb2rodata*)
    } >EXTMEMB2
   
    /* EXTMEM Bank0 */
    .eb3text :
    {
        *(.eb3text)                   /* remaining code */
        *(.eb3rodata)                 /* read-only data (constants) */
        *(.eb3rodata*)
    } >EXTMEMB3
   
   
   
    /* after that it's only debugging information. */
   
    /* remove the debugging information from the standard libraries */
/*    DISCARD :
    {
     libc.a ( * )
     libm.a ( * )
     libgcc.a ( * )
     }
*/

  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3 */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }

  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }
}



/* default stack size(s). These are used by the startup in order to allocate stacks for
the different modes. */
__Stack_Size = 1024 ;

PROVIDE ( _Stack_Size = __Stack_Size ) ;
__Stack_Init = _estack - __Stack_Size ;

/*"PROVIDE" allows to easily override these values from an object file or the commmand line.*/
PROVIDE ( _Stack_Init = __Stack_Init ) ;
franek.bmw
Posts: 57
Joined: Thu Mar 13, 2014 11:15 am
Has thanked: 2 times

Re: STM32f103VET6 Bootloader jump problem.

Post by franek.bmw »

It work with bootloader when I change the size of RAM (from 64K to 60K) in ld script in app. But I don't know why. No idea.
franek.bmw
Posts: 57
Joined: Thu Mar 13, 2014 11:15 am
Has thanked: 2 times

Re: STM32f103VET6 Bootloader jump problem.

Post by franek.bmw »

I found weird thing. When I increase main stack size or process stack size in linker script of chibios bootloader, then my bare metal application work good. So it indirectly depend on main stack size or process stack size in chibios booloader. Also I have to change ram size in app ld from 64k to 63k. Could anyone explain it and help me?

Franek
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32f103VET6 Bootloader jump problem.

Post by Giovanni »

Does your application re-initializes stacks? usually it is done by HW after reset but you need to re-initialize stacks in the application code.

The stack position is initialized by reading the value from the vectors table.

Giovanni
franek.bmw
Posts: 57
Joined: Thu Mar 13, 2014 11:15 am
Has thanked: 2 times

Re: STM32f103VET6 Bootloader jump problem.

Post by franek.bmw »

Did you mean something like this?

Code: Select all

      /* set stack pointer as in application's vector table */
      __set_MSP((u32) (ApplicationAddress[0]));
      Jump_To_Application();


I made this before jump in bootloader code.
But when I comment out function __set_MSP, it work good anyway (with modifications described by me above).
franek.bmw
Posts: 57
Joined: Thu Mar 13, 2014 11:15 am
Has thanked: 2 times

Re: STM32f103VET6 Bootloader jump problem.

Post by franek.bmw »

I think I found the solution. In ChibiOS is used a dual stack mode. I my bare metal app I use only one stack. So I have to disable dual stack mode. In ResetHander from app I add this code:

Code: Select all

   uint32_t reg;

   /* CPU mode initialization. (disable dual stack mode)*/
   reg = 0;
   asm volatile ("msr     CONTROL, %0" : : "r" (reg));
   asm volatile ("isb");


And now all is working correct without any stacks problem.
I have a question. Is this a good way to disable dual stack mode?


Franek
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32f103VET6 Bootloader jump problem.

Post by Giovanni »

Yes, it is. In general you should start the application in an after-reset-like state.

Giovanni
franek.bmw
Posts: 57
Joined: Thu Mar 13, 2014 11:15 am
Has thanked: 2 times

Re: STM32f103VET6 Bootloader jump problem.

Post by franek.bmw »

Is there something else to bring to after-reset-like state?

Franek
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32f103VET6 Bootloader jump problem.

Post by Giovanni »

All peripherals used in the bootloader. If you want to be extra sure then you may reset peripherals after stopping drivers using RCC reset registers. There are also the function rccResetXXX().

In the core you should clear the state of NVIC and Systick.

Giovanni
Post Reply