AnsweredAssumed Answered

Crossworks Implementation of In-Application Bootloader for STM32 High-Density Devices

Question asked by mcgilvra.albert on Aug 30, 2012
Latest reply on Sep 17, 2012 by mcgilvra.albert
ST's AN2557 app note explains In-Application Programming using a USART.  Unfortunately, the example software that comes with the app note does not include a Crossworks implementation.  Many good lessons have been learned in creating this one, with much help from Michael Johnson of Rowley Associates.  I hope you can benefit from it.
       
  1. Pertinent Items:        
             
    1. Properties - To set a property, right-click on the Project name (not Solution) and select Properties.                
                   
      1. Load Offset - under Debugger
      2.            
      3. Load Offset Symbol Limit - under Debugger
      4.            
      5. Emit Relocations - under Linker
      6.            
      7. Additional Output Format - under Linker
      8.            
      9. Memory Map File - under Build
      10.            
      11. Section Placement File - under Build
      12.        
             
    2.        
    3. Memory-Map file                
                   
      1. This defines the SRAM and Flash segment addresses.
      2.            
      3. Default location is "C:\Users\Albert\AppData\Local\Rowley Associates Limited\CrossWorks for ARM\packages\targets\ST_STM32F10x\ST_STM32F103VE_MemoryMap.xml"  
      4.            
      5. You can make a copy of the default file in your project directory, edit it, and point to it with the Memory Map File property.
      6.        
             
    4.        
    5. Section-Placement file                
                   
      1. This defines what program sections (.text, .data, etc.) get put in what segments defined in the Memory-Map file. 
      2.            
      3. Default location is "C:\Program Files (x86)\Rowley Associates Limited\CrossWorks for ARM 2.1\targets\flash_placement.xml"
      4.            
      5.  You should not need to edit this file but if you do, make a copy in your project folder and point to it with the Section Placement property.
      6.        
             
    6.    
       
  2.    
  3. Relocation.  In order to implement a bootloader you will have to place the bootloader at a different memory location than the target app (that which the bootloader will load).          
             
    1. It's arbitrary weather the bootloader is below or above the target app in memory.  But above seems better to me because then an existing app can be downloaded as is with the bootloader.  Also, on power-up or reset you would usually want your target app to run.  By default code location begins at 0x08000000, the bottom of flash, so a power-on or reset will go there and execute your target app instead of your bootloader.
    2.        
    3. To relocate code you have two options:
    4.        
    5. Option 1 (Preferred) - Edit the Memory-Map file, err... a copy of it.  Use NotePad++ or similar to edit.                
                   
      1. At the bottom of the file you will see:  <MemorySegment size="0x80000" access="ReadOnly" name="FLASH" start="0x08000000"/>
      2.            
      3. Change to:  <MemorySegment size="0x70000" access="ReadOnly" name="FLASH" start="0x08010000"/> if you want to relocate at 0x08010000.  Note that "start" must be a multiple of 0x800 because that's the flash page size.
      4.            
      5. Note, you must reduce "size" by whatever you have added to "start".
      6.            
      7. This is the preferred method because it also puts the relocation info in the .bin output file which is the file that will get downloaded with the bootloader.
      8.        
             
    6.        
    7. Option 2 - Set the Load Offset related properties                
                   
      1. Set the Load Offset property to the desired load address offset, so if you want to load 0x10000 above beginning of flash, set it to 0x10000.  Note that Load Offset must be a multiple of 0x800 because that's the flash page size.
      2.            
      3. Set the Load Offset Symbol Limit to 0x08080000, i.e., top of flash.  This limits the offsetting to within flash.  If you don't set this, the offsetting will also be applied to SRAM addresses which start at 0x20000000.  With only 64K of SRAM an offset approaching 0x10000 will relocate SRAM accesses outside the 64K limit and a bus-fault / hard-fault will be generated. 
      4.            
      5. Set Emit Relocations property to Yes.  This tells the linker to pay attention to the Load Offset properties.
      6.            
      7. This is not the preferred method because the .bin file will not contain the relocation info.  You can capture a .bin with the relocation info by loading the program area into a Memory window in Crossworks, the right-click Save to Binary.  The size can be determined from the generated .bin file with HexEdit or similar.
      8.        
             
    8.    
       
  4.    
  5. Generating the target app.          
             
    1. Assuming your target app will be loaded into the bottom of flash, no project changes are needed other than to set the Additional Output Format property to bin.  
    2.        
    3. If your target app will go into higher memory then certain things must be done:                
                   
      1. Relocation of target app by one of the above methods.
      2.            
      3. ApplicationAddress in bootloader common.h will have to be changed from 0x08000000 to the higher place you want the target app loaded to.
      4.            
      5. ST's application note AN2557 also says you should relocate the vector table at the target app load address using the "NVIC_SetVectorTable"function or the VECT_TAB_OFFSET definition inside the "system_stm32f10x.c".  I have not found this to be necessary and don't understand enough to know why.
      6.        
             
    4.    
       
  6.    
  7. Examples          
             
    1. ETM IAP is the example bootloader.
    2.        
    3. ETM Base is the example target app.  This target app jumps back to the bootloader after a few seconds so you can play around without continually resetting.
    4.    
       
  8.    
  9. Notes        
             
    1. When the IAP code wants to jump to the downloaded target code, it must add 0x235 to the target's load address.  The entry point is actually 0x234 from the beginning but only odd jump addresses are allowed in ARM so you must add one.  It will resolve to 0x234 and jump correctly.
    2.        
    3. The simplest way is to allow your target app to load at the default zero offset (0x08000000), then you don't need to worry about relocating it.  Now for the IAP bootloader, relocate it someplace well above the end of your target app (look at target app.bin to see how far it goes in flash).
    4.        
    5. If you load only the example IAP bootloader, then power-cycle or reset with no code down at 0x08000000 then nothing will happen.  The bootloader will not run because the power-on/reset vector defaults to the bottom of flash.  You must load some code at the bottom that will jump to the bootloader.  Normally the target app would have some sort of Hyperterminal user interface that would allow the user to select Re-Flash, then the target would jump to the bootloader.  Alternatively, you could use the state of a GPIO connected to a (pushbutton or jumper) in your target app to control whether it runs or jumps to bootloader on startup.
    6.    
       

Attachments

Outcomes