Difference between revisions of "SEGGER Flash Loader"

From SEGGER Wiki
Jump to: navigation, search
(Stack usage)
 
(199 intermediate revisions by 12 users not shown)
Line 1: Line 1:
  +
== SEGGER Flash Loader ==
<div class="toclimit-2">
 
  +
The SEGGER Flash Loader (SFL) is part of the [[J-Link_Device_Support_Kit | J-Link Device Support Kit (DSK)]] and allows users to add flash programming support for a new device on their own.
__TOC__
 
</div>
 
=Open Flash Loader=
 
==Introduction==
 
As the number of devices being available is steadily growing and sometimes in an early stage of the MCU development only a few samples/boards are available that may not be provided to third parties (e.g. SEGGER) to add support for a new device. Also the existence of the device may have confidential status, so it might not be mentioned as being supported in public releases yet. Therefore it might be desirable to be able to add support for new devices on your own, without depending on SEGGER and a new release of the J-Link Software & Documentation package being available.
 
   
  +
=== Minimum supported J-Link software version ===
The J-Link DLL allows customers to add support for new devices on their own. It is also possible to edit / extend existing device support by for example adding new flash banks (e.g. to add support for internal EEPROM programming or SPIFI programming). This article explains how new devices can be added to the DLL and how existing ones can be edited / extended.
 
  +
If not stated otherwise for a specific function / feature / etc., the minimum supported J-Link software version is V7.80.
   
  +
== Supported CPU architectures ==
==General Procedure==
 
  +
The SEGGER Flash Loader (SFL) is available for the following architectures:
By default, the J-Link DLL comes with a build-in device database that defines which device names are known and therefore officially supported by the J-Link DLL and software that uses the J-Link DLL. This list can also be viewed on our website: https://www.segger.com/downloads/supported-devices.php
 
  +
* ARMv4/v5
  +
** ARM720T, ARM7TDMI, ARM7TDMI-S
  +
** ARM920T, ARM922T, ARM926EJ-S, ARM946E-S, ARM966E-S
  +
* ARMv6-M
  +
** Cortex-M0, Cortex-M0+, Cortex-M1
  +
* ARMv7-M
  +
** Cortex-M3, Cortex-M4, Cortex-M7
  +
* ARMv8-M
  +
** Cortex-M23, Cortex-M33, Cortex-M55, Cortex-M85
  +
* ARMv7-A
  +
** Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A12, Cortex-A15, Cortex-A17
  +
* ARMv7-R
  +
** Cortex-R4, Cortex-R5, Cortex-R7, Cortex-R8
  +
* ARMv8-R
  +
** Cortex-R52
  +
* RISC-V RV32
   
  +
{{Note|1=
Additionally, the build-in device database can be extended by specifying devices in an XML file, named JLinkDevices.xml. It is also possible to edit / extend an device from the built-in device database via this XML file. There are different places where the JLinkDevices.xml can be referenced from (see list below). In case of several JLinkDevices.xml files are used, supplement each other as in the order specified below:
 
  +
Architectures / cores not listed here must be assumed as being not supported.<br>
#In the same directory as the J-Link DLL (JLinkARM.dll)
 
  +
While they may work by chance, no support is provided for problems in regards to getting SEGGER Flash Loaders running on non-listed architectures.<br>
#In the same directory as the J-Link settings file. The location of the settings file depends on the IDE / software being used.
 
  +
In case of doubt, please feel free to contact SEGGER.
#In the directory specified using the J-Link Command String ''JLinkDevicsXMLPath = <Path>''
 
  +
}}
   
  +
== Supported flash types ==
==Extending an Existing Device==
 
  +
Because a SEGGER Flash Loader programs the flash via the MCU it runs on, basically any flash (or other non-volatile memories) can be supported.<br>
In order to edit/extend a device that is already in the built-in device database of the J-Link DLL, the following needs to be added to the JLinkDevices.xml:
 
  +
This applies to flash that is memory mapped accessible by the MCU (internal flash, external QSPI NOR flash, ...) as well as to non-memory mapped flashes (external I2C EEPROM, external NAND flash, ...)<br>
<Database>
 
<Device>
 
<ChipInfo Vendor="..." Name="..." />
 
<FlashBankInfo Name="..." BaseAddr="..." MaxSize="..." Loader="..." LoaderType="..." AlwaysPresent="..." />
 
</Device>
 
</Database>
 
The attribute Name of the tag ''<ChipInfo>'' must specify exactly the same name as the device in the built-in device database specifies. In case the value of the attribute ''BaseAddr'' specifies an address of an existing flash bank for the existing device, in the built-in device database, the flash bank from the built-in database is replaced by the one from the XML file.
 
   
  +
For non-memory-mapped flashes, the following additional entry functions must be implemented in an SFL:
When adding new flash banks or if the device in the built-in database does not specify any flash banks so far, the same attribute requirements as for adding a new device, apply. For more information, please refer to Adding a new device.
 
  +
* SEGGER_FL_CheckBlank()
  +
* SEGGER_FL_Verify()
  +
* SEGGER_FL_Read()
  +
* SEGGER_FL_CalcCRC()
   
  +
== Entry functions overview ==
In order to add more than one flash bank, just repeat the ''<FlashBankInfo … />'' tag structure from above, inside the same <Device> tag. For more information about the tags and their attributes, please refer to XML Tags and Attributes.
 
   
  +
The following table gives an overview about the mandatory and optional entry functions, of a SEGGER Flash Loader:
==Adding a New Device==
 
  +
{| class="seggertable"
In order to add support for a new device to the J-Link DLL, the following needs to be added
 
  +
|-
to the JLinkDevices.xml :
 
  +
! Entry function !! Type
<Database>
 
  +
|-
<Device>
 
  +
| [[#SEGGER_FL_Prepare | SEGGER_FL_Prepare()]] || Mandatory
<ChipInfo Vendor="..." Name="..." WorkRAMAddr="..." WorkRAMSize="..." Core="..." />
 
  +
|-
<FlashBankInfo Name="..." BaseAddr="..." MaxSize="..." Loader="..." LoaderType="..." AlwaysPresent="..." />
 
  +
| [[#SEGGER_FL_Restore | SEGGER_FL_Restore()]] || Mandatory
</Device>
 
  +
|-
</Database>
 
  +
| [[#SEGGER_FL_Program | SEGGER_FL_Program()]] || Mandatory
When adding a new device, the following attributes for the <ChipInfo> tag are mandatory:
 
  +
|-
*Vendor
 
  +
| [[#SEGGER_FL_Erase | SEGGER_FL_Erase()]] || Mandatory
*Name
 
  +
|-
*Core
 
  +
| [[#SEGGER_FL_EraseChip | SEGGER_FL_EraseChip()]] || Optional
In case a ''<FlashBankInfo>'' tag is also added, the following attributes in addition to the ones mentioned before, become mandatory:
 
  +
|-
'''ChipInfo-Tag'''
 
  +
| [[#SEGGER_FL_CheckBlank | SEGGER_FL_CheckBlank()]] || Optional
*WorkRAMAddr
 
  +
|-
*WorkRAMSize
 
  +
| [[#SEGGER_FL_Verify | SEGGER_FL_Verify()]] || Optional
*FlashBankInfo
 
  +
|-
'''FlashBankInfo-Tag'''
 
  +
| [[#SEGGER_FL_Read | SEGGER_FL_Read()]] || Optional
*Name
 
  +
|-
*BaseAddr
 
  +
| [[#SEGGER_FL_CalcCRC | SEGGER_FL_CalcCRC()]] || Optional
*MaxSize
 
  +
|-
*Loader
 
  +
| [[#SEGGER_FL_Start | SEGGER_FL_Start()]] || Optional
*LoaderType
 
  +
|-
*AlwaysPresent
 
  +
| [[#SEGGER_FL_GetFlashInfo | SEGGER_FL_GetFlashInfo()]] || Optional
For more information about the tags and their attributes, please refer to XML Tags and
 
  +
|}
Attributes .
 
In order to add more than one device to the device database, just repeat the <Device> …
 
</Device> tag structure from above for each device.
 
   
  +
=== SEGGER_FL_Prepare ===
==JLinkDevices.xml Tags and Attributes==
 
  +
'''Prototype'''<br>
  +
<source lang="c">int SEGGER_FL_Prepare(U32 PreparePara0, U32 PreparePara1, U32 PreparePara2);</source>
   
  +
'''Function description'''<br>
  +
Mandatory function. Must be present to make SFL detected as valid.<br>
  +
Prepares SFL for further usage. Very first function of SFL to be called.<br>
  +
Can rely on not being called multiple times in a row without a SEGGER_FL_Restore() in between.<br>
  +
This function may be used for example to initialize the PLL of the device before flash programming starts, to improve flash programming performance.<br>
  +
The following is a valid series of calls:
  +
<source>
  +
SEGGER_FL_Prepare()
  +
SEGGER_FL_Erase()
  +
SEGGER_FL_Program()
  +
SEGGER_FL_Restore()
  +
SEGGER_FL_Prepare()
  +
SEGGER_FL_Erase()
  +
SEGGER_FL_Restore()
  +
</source>
   
  +
'''Parameters'''<br>
XML Tags and Attributes
 
  +
{| class="seggertable"
In the following, the valid XML tags and their possible attributes are explained.
 
  +
|-
General rules
 
  +
! Parameter !! Description
• Attributes may only occur inside an opening tag
 
  +
|-
• Attribute values must be enclosed by quotation marks
 
  +
| PreparePara0 || Reserved for future use. Always == 0 for now
Tag Description
 
  +
|-
  +
| PreparePara1 || Reserved for future use. Always == 0 for now
  +
|-
  +
| PreparePara2 || Reserved for future use. Always == 0 for now
  +
|-
  +
|}
   
  +
'''Return value'''<br>
{| class="wikitable"
 
  +
{| class="seggertable"
!|Tag
 
!|Description
 
 
|-
 
|-
  +
! Value !! Meaning
|''<Database>''
 
|Opens the XML file top-level tag.
 
 
|-
 
|-
  +
| >= 0 || OK
|''<Device>''
 
|Opens the description for a new device.
 
 
|-
 
|-
  +
| == 0 || OK, Clock speed of core not changed
|''<ChipInfo>''
 
|Specifies basic information about the device to be added, like the core it incorporates etc.
 
 
|-
 
|-
  +
| > 0 || New clock speed in [Hz](!) of core
|''<FlashBankInfo>''
 
  +
|-
|Specifies a flash bank for the device.
 
  +
| < 0 || Error
 
|}
 
|}
   
====<Database>====
+
=== SEGGER_FL_Restore ===
  +
'''Prototype'''<br>
Opens the XML file top-level tag. Only present once per XML file.
 
  +
<source lang="c">int SEGGER_FL_Restore(U32 RestorePara0, U32 RestorePara1, U32 RestorePara2);</source>
'''Valid attributes'''
 
This tag has no attributes
 
'''Notes'''
 
*Must only occur once per XML file
 
*Must be closed via </Database>
 
====<Device>====
 
Opens the description for a new device.
 
'''Valid attributes'''
 
This tag has no attributes
 
'''Notes'''
 
*Must be closed via </Device> .
 
*May occur multiple times in an XML file
 
====<ChipInfo>====
 
Specifies basic information about the device to be added, like the core it incorporates etc.
 
'''Valid attributes'''
 
   
  +
'''Function description'''<br>
  +
Mandatory function. Must be present to make SFL detected as valid.<br>
  +
Restores SFL after work is done. Very last function of SFL to be called.<br>
  +
This function may be used for example to restore the PLL settings of the device after flash programming is done.<br>
  +
This is for example needed when using the [https://www.segger.com/products/debug-probes/j-link/technology/flash-breakpoints/ unlimited number of breakpoints in flash] feature of J-Link.<br>
   
  +
'''Parameters'''<br>
{| class="wikitable"
 
  +
{| class="seggertable"
!|Parameter
 
!|Meaning
 
 
|-
 
|-
  +
! Parameter !! Description
|''Vendor''
 
|String that specifies the name of the vendor of the device. This attribute is mandatory. E.g. Vendor=“ST”.
 
 
|-
 
|-
  +
| RestorePara0 || Reserved for future use. Always == 0 for now
|''Name''
 
|Name of the device. This attribute is mandatory. E.g. Name=“STM32F407IE”
 
 
|-
 
|-
  +
| RestorePara1 || Reserved for future use. Always == 0 for now
|''WorkRAMAddr''
 
|Hexadecimal value that specifies the address of a RAM area that can be used by J-Link during flash programming etc. Should not be used by any DMAs on the device. Cannot exist without also specifying WorkRAMSize. If no flash banks are added for the new device, this attribute is optional. E.g. WorkRAMAddr=“ 0x20000000 ”
 
 
|-
 
|-
  +
| RestorePara2 || Reserved for future use. Always == 0 for now
|''WorkRAMSize''
 
|Hexadecimal value that specifies the size of the RAM area that can be used by J-Link during flash programming etc. Cannot exist without also specifying WorkRAMAddr. If no flash banks are added for the new device, this attribute is optional. E.g. WorkRAMSize=“ 0x10000 ”
 
 
|-
 
|-
  +
|}
|''Core''
 
  +
|Specifies the core that the device incorporates. If a new device added, this attribute is mandatory. E.g. Core=“ JLINK_CORE_CORTEX_M0 ”For a list of valid attribute values, please refer to Attribute values - Core.
 
  +
'''Return value'''<br>
  +
{| class="seggertable"
 
|-
 
|-
  +
! Value !! Meaning
|''JLinkScriptFile''
 
  +
|-
|String that specifies the path to a J-Link script file if required for the device. Path can be relative or absolute. If path is
 
  +
| >= 0 || OK
relative, is relative to the location of the JLinkDevices.xml file. This attribute is mandatory. E.g. JLinkScriptFile=“ST/Example.jlinkscript”
 
  +
|-
  +
| < 0 || Error
 
|}
 
|}
'''Notes'''
 
*No separate closing tag.
 
Directly closed after attributes have been specified: ''<ChipInfo … />''
 
*Must not occur outside a ''<Device>'' tag.
 
====Attribute values - Core====
 
The following values are valid for the ''Core'' attribute:
 
*JLINK_CORE_CORTEX_M1
 
*JLINK_CORE_CORTEX_M3
 
*JLINK_CORE_CORTEX_M3_R1P0
 
*JLINK_CORE_CORTEX_M3_R1P1
 
*JLINK_CORE_CORTEX_M3_R2P0
 
*JLINK_CORE_CORTEX_M3_R2P1
 
*JLINK_CORE_CORTEX_M0
 
*JLINK_CORE_CORTEX_M_V8BASEL
 
*JLINK_CORE_ARM7
 
*JLINK_CORE_ARM7TDMI
 
*JLINK_CORE_ARM7TDMI_R3
 
*JLINK_CORE_ARM7TDMI_R4
 
*JLINK_CORE_ARM7TDMI_S
 
*JLINK_CORE_ARM7TDMI_S_R3
 
*JLINK_CORE_ARM7TDMI_S_R4
 
*JLINK_CORE_CORTEX_A8
 
*JLINK_CORE_CORTEX_A7
 
*JLINK_CORE_CORTEX_A9
 
*JLINK_CORE_CORTEX_A12
 
*JLINK_CORE_CORTEX_A15
 
*JLINK_CORE_CORTEX_A17
 
*JLINK_CORE_ARM9
 
*JLINK_CORE_ARM9TDMI_S
 
*JLINK_CORE_ARM920T
 
*JLINK_CORE_ARM922T
 
*JLINK_CORE_ARM926EJ_S
 
*JLINK_CORE_ARM946E_S
 
*JLINK_CORE_ARM966E_S
 
*JLINK_CORE_ARM968E_S
 
*JLINK_CORE_ARM11
 
*JLINK_CORE_ARM1136
 
*JLINK_CORE_ARM1136J
 
*JLINK_CORE_ARM1136J_S
 
*JLINK_CORE_ARM1136JF
 
*JLINK_CORE_ARM1136JF_S
 
*JLINK_CORE_ARM1156
 
*JLINK_CORE_ARM1176
 
*JLINK_CORE_ARM1176J
 
*JLINK_CORE_ARM1176J_S
 
*JLINK_CORE_ARM1176JF
 
*JLINK_CORE_ARM1176JF_S
 
*JLINK_CORE_CORTEX_R4
 
*JLINK_CORE_CORTEX_R5
 
*JLINK_CORE_RX
 
*JLINK_CORE_RX62N
 
*JLINK_CORE_RX62T
 
*JLINK_CORE_RX63N
 
*JLINK_CORE_RX630
 
*JLINK_CORE_RX63T
 
*JLINK_CORE_RX621
 
*JLINK_CORE_RX62G
 
*JLINK_CORE_RX631
 
*JLINK_CORE_RX65N
 
*JLINK_CORE_RX21A
 
*JLINK_CORE_RX220
 
*JLINK_CORE_RX230
 
*JLINK_CORE_RX231
 
*JLINK_CORE_RX23T
 
*JLINK_CORE_RX24T
 
*JLINK_CORE_RX110
 
*JLINK_CORE_RX113
 
*JLINK_CORE_RX130
 
*JLINK_CORE_RX71M
 
*JLINK_CORE_CORTEX_M4
 
*JLINK_CORE_CORTEX_M7
 
*JLINK_CORE_CORTEX_M_V8MAINL
 
*JLINK_CORE_CORTEX_A5
 
*JLINK_CORE_POWER_PC
 
*JLINK_CORE_POWER_PC_N1
 
*JLINK_CORE_POWER_PC_N2
 
*JLINK_CORE_MIPS
 
*JLINK_CORE_MIPS_M4K
 
*JLINK_CORE_MIPS_MICROAPTIV
 
*JLINK_CORE_EFM8_UNSPEC
 
*JLINK_CORE_CIP51
 
====<FlashBankInfo>====
 
Specifies a flash bank for the device. This allows to use the J-Link flash download functionality with IDEs, debuggers and other software that uses the J-Link DLL (e.g. J-Link Commander) for this device. The flash bank can then be programmed via the normal flash download functionality of the J-Link DLL. For more information about flash download, please refer to Flash download . For possible limitations etc. regarding newly added flash banks, please refer to Add. Info / Considerations / Limitations .
 
'''Valid attributes'''
 
   
  +
'''Notes'''<br>
{| class="wikitable"
 
  +
{{Note|1=
!|Parameter
 
  +
Can rely on not being called multiple times in a row without a SEGGER_FL_Prepare() in between.<br>
!|Meaning
 
  +
The following is a valid (but unlikely) series of calls:<br>
  +
* SEGGER_FL_Prepare()
  +
* SEGGER_FL_Erase()
  +
* SEGGER_FL_Program()
  +
* SEGGER_FL_Restore()
  +
* SEGGER_FL_Prepare()
  +
* SEGGER_FL_Erase()
  +
* SEGGER_FL_Restore()
  +
}}
  +
  +
=== SEGGER_FL_Program ===
  +
'''Prototype'''<br>
  +
<source lang="c">int SEGGER_FL_Program(U32 DestAddr, U32 NumBytes, U8 *pSrcBuff);</source>
  +
  +
'''Function description'''<br>
  +
Mandatory function. Must be present to make SFL detected as valid.<br>
  +
Programs flash. The block passed to this function is always a multiple of what is indicated as page size by FlashDevice.PageSize.<br>
  +
This function can rely on only being called with destination addresses and NumBytes that are aligned to FlashDevice.PageSize.
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
 
|-
 
|-
  +
! Parameter !! Description
|''Name''
 
|String that specifies the name of the flash bank. Only used for visualization. Can be freely chosen. This attribute is mandatory. E.g. Name=“SPIFI flash”
 
 
|-
 
|-
  +
| DestAddr || Destination address. Always aligned to FlashDevice.PageSize
|''BaseAddr''
 
|Hexadecimal value that specifies the start address of the flash bank. The J-Link DLL uses this attribute together with MaxSize to determine which memory write accesses performed by the debugger, shall be redirected to the flash loader instead of being written directly to the target as normal memory access. This attribute is mandatory. E.g. BaseAddr=“ 0x08000000 ”
 
 
|-
 
|-
  +
| NumBytes || Number of bytes to be programmed (always a multiple of FlashDevice.PageSize)
|''MaxSize''
 
|Hexadecimal value that specifies the max. size of the flash bank in bytes. For many flash loader types the real bank size may depend on the actual flash being connected (e.g. SPIFI flash where the loader can handle different SPIFI flashes so size may differ from hardware to hardware). Also, for some flash loaders the sectorization is extracted from the flash loader at runtime. The real size of the flash bank may be smaller than MaxSize but must never be bigger. The J-Link DLL uses this attribute together with BaseAddr to determine which memory write accesses performed by the debugger, shall be redirected to the flash loader instead of being written directly to the target as normal memory access. This attribute is mandatory. E.g. MaxSize=“ 0x80000 ”
 
 
|-
 
|-
  +
| pSrcBuff || Pointer to the data to be programmed
|''Loader''
 
  +
|}
|String that specifies path to the ELF file that holds the flash loader. Path can be relative or absolute. If path is relative, it
 
  +
is relative to the location of the JLinkDevices.xml file. This attribute is mandatory. E.g. Loader=“ST/MyFlashLoader.elf” For CMSIS flash loaders the file extension is usually FLM, however any extension is accepted by the J-Link DLL.
 
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| == 0 || O.K.
 
|-
 
|-
  +
| == 1 || Error
|''LoaderType''
 
|Specifies the type of the loader specified by Loader. This attribute is mandatory. E.g. LoaderType=“ FLASH_ALGO_TYPE_OPEN ” For a list of valid attribute values, please refer to Attribute values LoaderType.
 
 
|-
 
|-
  +
| == 2 || O.K., already performed implicit verify of block that was just programmed
|''AlwaysPresent''
 
|Specifies if a flash bank is always present (e.g. internal flash). If this element is set to one, this flash bank will be affected by the “erase” command. This attribute is optional. E.g. AlwaysPresent=“1”.
 
 
|}
 
|}
   
  +
=== SEGGER_FL_Erase ===
'''Notes'''
 
  +
'''Prototype'''<br>
*No separate closing tag. Directly closed after attributes have been specified:
 
  +
<source lang="c">int SEGGER_FL_Erase(U32 SectorAddr, U32 SectorIndex, U32 NumSectors);</source>
<FlashBankInfo … />
 
*Must not occur outside a <Device> tag
 
====Attribute values - LoaderType====
 
The following values are valid for the LoaderType attribute:
 
*FLASH_ALGO_TYPE_OPEN
 
Describes that the used algorithm is an Open Flashloader algorithm. CMSIS based
 
algorithms are also supported via the Open Flashloader concept. For additional
 
information, see Add. Info / Considerations / Limitations .
 
   
  +
'''Function description'''<br>
==Example JLinkDevices.xml file==
 
  +
Mandatory function. Must be present to make SFL detected as valid.<br>
==Add. Information / Considerations / Limitations ==
 
  +
Erases flash. For one-time programmable memories (OTP), this function may check if the passed sector is still erased/not programmed and throw an error in case it already is programmed.
   
  +
'''Parameters'''<br>
=Create a Flash Loader=
 
  +
{| class="seggertable"
This article describes how to create a flash loader using the template projects (Cortex-M and Cortex-A/R) for SEGGER Embedded Studio.
 
== Debug Configurations ==
 
The example project contains two debug configurations:
 
*Debug
 
*Release
 
=== Debug configuration ===
 
This configuration allows to debug the flash algorithm in Embedded Studio. The configuration includes a main.c containing the typical function call order, executed by the J-Link DLL during flash programming. The optimization level for this configuration is set to "none".
 
=== Release configuration ===
 
This configuration does not allow debugging but creates the output elf file which can be referenced from within the JLinkDevices.xml file as "''Loader''". The optimization level is set to 3 (highest).
 
== Included files ==
 
{| class="wikitable"
 
 
|-
 
|-
! Filename !! Content
+
! Parameter !! Description
 
|-
 
|-
  +
| SectorAddr || Address of the first sector to be erased.
| '''FlashDev.c''' || Flash device description for the ST STM32F205RC
 
 
|-
 
|-
  +
| SectorIndex || Index of the start sector to be erased. Counting starts at 0 (first sector reported by FlashDevice.SectorInfo[0])
| '''FlashOS.h''' || Function prototypes, definitions and structures
 
 
|-
 
|-
  +
| NumSectors || Number of sectors to be erased. It is the responsibility of this function to track the sector size in case a device provides multiple sector sizes.
| '''FlashPrg.c''' || Flash algorithm itself (e.g. ProgramPage(), EraseSector()
 
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
 
|-
 
|-
  +
! Value !! Meaning
| '''main.c''' || Flash algorithm debug code (used by debug configuration, only)
 
 
|-
 
|-
  +
| == 0 || O.K.
| '''Cortex_M_Startup.s'''<br>'''ARM_Startup.s''' || Cortex-M startup code (used by debug configuration, only) <br> Cortex-A/R startup code (used by debug configuration, only)
 
 
|-
 
|-
  +
| == 1 || Error
| '''MemoryMap.xml''' || Memory map of the ST STM32F205RC
 
  +
|}
  +
  +
=== SEGGER_FL_EraseChip ===
  +
'''Prototype'''<br>
  +
<source lang="c">int SEGGER_FL_EraseChip(void);</source>
  +
  +
'''Function description'''<br>
  +
Optional function. May be present to speed up erase procedure under special circumstances
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
 
|-
 
|-
  +
! Parameter !! Description
| '''Placement_debug.xml''' || Debug configuration section placement file.
 
 
|-
 
|-
  +
| colspan="2" | None
| '''Placement_release.xml''' || Release configuration section placement file.
 
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
 
|-
 
|-
  +
! Value !! Meaning
| '''thumb_crt0.s'''<br>'''crt0.s''' || Initialization file for Cortex-M (used by debug configuration, only)<br>Initialization file for Cortex-A/R(used by debug configuration, only)
 
  +
|-
  +
| == 0 || O.K.
  +
|-
  +
| == 1 || Error
 
|}
 
|}
== Embedded Studio Template Projects ==
 
The template projects below have been tested with SEGGER Embedded Studio V3.10.
 
*[[File:OpenFlashLoader_CortexM_Template_EmbeddedStudio.zip]]
 
*[[File:OpenFlashLoader_CortexAR_Template_EmbeddedStudio.zip]]
 
   
  +
=== SEGGER_FL_CheckBlank ===
== Step-By-Step Instruction ==
 
  +
'''Prototype'''<br>
This step-by-step instruction explains how to create your own flash loader using the template projects for Embedded Studio and how to use add a new flash bank for an existing or new device to the J-Link DLL, so that it can be used from within any application using the DLL.
 
  +
<source lang="c">int SEGGER_FL_CheckBlank(U32 Addr, U32 NumBytes, U8 BlankValue);</source>
#Adapt the template project
 
##'''FlashDev.c''': Modify the FlashDevice structure according to your device
 
##'''FlashPrg.c''': Implement the flash routines Init(), UnInit(), EraseSector() and ProgramPage()
 
##'''MemoryMap.xml''': Enter RAM base address and RAM size
 
##'''main.c''': Make sure that the define ''_FLASH_BASE_ADDR'' defines the correct flash base address
 
#Test the debug configuration
 
##Connect the target to the J-Link and the J-Link to the PC
 
##Switch to the '''Debug''' configuration in Embedded Studio ('''Build''' -> '''Set Active Build Configuration''' -> '''Debug''')
 
##Build the project by pressing '''F7'''
 
##Start the debug session by pressing '''F5'''
 
##PC should be halted at main. Now debug the flash algorithm and make sure that it behaves as expected.
 
#Build the flash loader using the release configuration
 
##Switch to the '''Release''' configuration in Embedded Studio ('''Build''' -> '''Set Active Build Configuration''' -> '''Release''')
 
##Build the project by pressing '''F7''' --> The flash loader file can be found here: $PROJ_DIR$\Output\Release\Exe\*.elf
 
#JLinkDevices.xml
 
##Create or adapt the '''JLinkDevices.xml''' (described in the J-Link User Manual (UM08001)).
 
##Place the '''JLinkDevices.xml''' file at the correct location (described in the J-Link User Manual (UM08001)).
 
Now you can select and use the created or adapted device which uses the new flash bank in any J-Link DLL based application (e.g. J-Link Commander / IDE / ...).
 
== Frequently Asked Questions ==
 
In which order does the J-Link DLL call the function during flash programming?
 
#Compare
 
##Init()
 
##Compare()<br>Memory is accessed so it has to be initialized during Init() so that it can be memory mapped accessed here. If it is not initialized correctly, the read access may results in confusing the MCU.
 
##UnInit()
 
# Erase
 
## Init()
 
## Erase()
 
## UnInit()
 
# Program
 
## Init()
 
## Program()
 
## UnInit()
 
== Troubleshoot ==
 
This section provides assistance in case of issues pops up when using custom added flash bank. The section assumes that the functionality has been verified using the debug configuration in Embedded Studio.
 
#Get the latest version of the template project
 
#Follow the Step-By-Step instructions expect of 2.1 FlashPrg.c --> Functions should not contain any code that accesses any SFRs
 
#Build the flash loader using the release configuration
 
#Perform a flash download using J-Link Commander. Flash download should report an error during verify
 
#Implement EraseSector() and retry the flash download test. J-Link Commander should still report verify failed but effected flash memory region should be empty. If not, check EraseSector().
 
#Implement ProgramPage() and retry the flash download test. Expected result: Test reports O.K. --> Programmed successfully. If not, check ProgramPage() code.
 
   
  +
'''Function description'''<br>
== Frequently Problems ==
 
  +
Optional function. May not be present.<br>
=== PC has unexpected value after flash download ===
 
  +
Checks if a memory region is blank / erased / unprogrammed.<br>
  +
Mainly used to speed up flash programming as it allows J-Link to skip calls to SEGGER_FL_Erase() before calling SEGGER_FL_Program(), in case a sector is already erased.
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Parameter !! Description
  +
|-
  +
| Addr || Address where checking for blank / erased data should start
  +
|-
  +
| NumBytes || Number of bytes to be checked
  +
|-
  +
| BlankValue || Blank (erased) value of flash (Most flashes have 0xFF, some have 0x00, some do not have a defined erased value)
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| >= 0 || OK
  +
|-
  +
| == 0 || OK, complete region is blank
  +
|-
  +
| == 1 || OK, not the complete region is blank
  +
|-
  +
| < 0 || Error
  +
|}
  +
  +
=== SEGGER_FL_Verify ===
  +
'''Prototype'''<br>
  +
<source lang="c">U32 SEGGER_FL_Verify(U32 Addr, U32 NumBytes, U8* pData);</source>
  +
  +
'''Function description'''<br>
  +
Optional function. May not be present. Not present for most memory-mapped accessible flash memories.<br>
  +
Verifies a given range by comparing the provided data versus the data in the flash.<br>
  +
Mainly used for non-memory mapped flashes in case flash is not simply read-accissble for the core at a certain address.
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Parameter !! Description
  +
|-
  +
| Addr || Address where verify should start
  +
|-
  +
| NumBytes || Number of bytes to verify
  +
|-
  +
| pBuff || Pointer to data to compare flash contents to
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| xxx || End address of verification.<br> ReturnVal == Addr+NumBytes indicates successful verification<br> ReturnVal != Addr+NumBytes indicates an error and gives the address where verification failed
  +
|}
  +
  +
=== SEGGER_FL_Read ===
  +
'''Prototype'''<br>
  +
<source lang="c">int SEGGER_FL_Read(U32 Addr, U32 NumBytes, U8 *pDestBuff);</source>
  +
  +
'''Function description'''<br>
  +
Optional function. May not be present.<br>
  +
Not needed for memory-mapped flashes that can be just read by the MCU core as RAM or other memories. Mainly used for non-memory mapped flashes where a virtual addres has been assigned to make J-Link flash download work.<br>
  +
If this function is present, J-Link will call it to read flash memory instead of reading it directly via the core.
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Parameter !! Description
  +
|-
  +
| Addr || Address to start reading flash at
  +
|-
  +
| NumBytes || Number of bytes to read
  +
|-
  +
| pBuff || Pointer to buffer where to store read data to
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| >= 0 || OK, number of bytes read (usually == NumBytes)
  +
|-
  +
| < 0 || Error
  +
|}
  +
  +
=== SEGGER_FL_CalcCRC ===
  +
'''Prototype'''<br>
  +
<source lang="c">U32 SEGGER_FL_CalcCRC(U32 CRC, U32 Addr, U32 NumBytes, U32 Polynom);</source>
  +
  +
'''Function description'''<br>
  +
Optional function, may not be present.<br>
  +
If present, J-Link may call this function to speed up the verification because not all data must be read + transferred back to the host but instead only the CRC (calculated by the SFL) is transferred to the host.<br>
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Parameter !! Description
  +
|-
  +
| CRC || Start value of CRC
  +
|-
  +
| Addr || Address where calculation of CRC starts
  +
|-
  +
| NumBytes || Number of bytes to calculate CRC on
  +
|-
  +
| Polynom || Polynom to use for CRC calculation
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| xxx || Calculated CRC
  +
|}
  +
  +
'''Notes'''<br>
  +
{{Note|1=
  +
# If an SFL implements this function, it is recommended to simply call SEGGER_OFL_Lib_CalcCRC() from the SEGGER_SFL_Lib.a library and pass its return value to the caller.
  +
}}
  +
  +
=== SEGGER_FL_Start ===
  +
'''Prototype'''<br>
  +
<source lang="c">void SEGGER_FL_Start(volatile struct SEGGER_FL_CMD_INFO* pInfo);</source>
  +
  +
'''Function description'''<br>
  +
Optional function, may not be present.<br>
  +
If present and target architecture supports turbo mode, J-Link will use this entry function to start turbo mode which will lead to a big performance gain in flash programming.<br>
  +
If an SFL implements this function, it should simply call SEGGER_OFL_Lib_StartTurbo() from the SEGGER_SFL_Lib.a library. The exact operation of SEGGER_OFL_Lib_StartTurbo() is not disclosed.
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Parameter !! Description
  +
|-
  +
| pInfo || Pointer to command info for SEGGER_OFL_Lib_StartTurbo()
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| colspan="2" | None
  +
|}
  +
  +
=== SEGGER_FL_GetFlashInfo ===
  +
'''Prototype'''<br>
  +
<source lang="c">int SEGGER_FL_GetFlashInfo(SEGGER_FL_FLASH_INFO* pInfo, U32 InfoAreaSize);</source>
  +
  +
'''Function description'''<br>
  +
Optional function. May not be present.<br>
  +
Only needed for flash loaders where the exact sectorization is determined at runtime.<br>
  +
This is for example the case for some loaders for external QSPI NOR flash, where different users may have different QSPI flashes connected to their hardware.<br>
  +
This allows to have only 1 loader to serve many different setups.<br>
  +
  +
'''Parameters'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Parameter !! Description
  +
|-
  +
| pInfo || Points to info area which is used to store the flash info.
  +
|-
  +
| InfoAreaSize || Indicates how big the area pointed to by SEGGER_FL_FLASH_INFO really is.<br>May be used to extend pInfo->aRangeInfo[] in case more elements are needed for the detected flash memory.
  +
|}
  +
  +
'''Return value'''<br>
  +
{| class="seggertable"
  +
|-
  +
! Value !! Meaning
  +
|-
  +
| >= 0 || OK, number of bytes read (usually == NumBytes)
  +
|-
  +
| < 0 || Error
  +
|}
  +
  +
'''Notes'''<br>
  +
{{Note|1=
  +
# If present, this function is called before any erase, program, verify operation but after Preare().<br>
  +
# If present, this function overrides the information provided by FlashDevice.TotalSize and FlashDevice.SectorInfo[]
  +
}}
  +
  +
== FlashDevice struct ==
  +
The FlashDevice structure variable contains all the static information about the flash algorithm like sectorization of the flash, programming chunk size, ...<br>
  +
In the following, the structure elements are explained in detail to give a good idea about what needs to be filled in for a new flash loader.
  +
  +
<source lang="c">
  +
struct FlashDevice {
  +
U16 AlgoVer;
  +
U8 Name[128];
  +
U16 Type;
  +
U32 BaseAddr;
  +
U32 TotalSize;
  +
U32 PageSize;
  +
U32 Reserved;
  +
U8 ErasedVal;
  +
U32 TimeoutProg;
  +
U32 TimeoutErase;
  +
struct SECTOR_INFO SectorInfo[MAX_NUM_SECTORS];
  +
};
  +
</source>
  +
  +
{| class="seggertable"
  +
|-
  +
! Member !! Explanation
  +
|-
  +
| AlgoVer || Set to 0x0101. Do not set to anything else!
  +
|-
  +
| Name || Name of the flash bank this flash loader handles. (E.g. "internal flash", "QSPI", ...). Must not exceed 127 characters (last character reserved for string termination). NEVER change the size of this array!
  +
|-
  +
| Type || Flash device type. Currently ignored. Set to 1 to get max. compatibility.
  +
|-
  +
| BaseAddr || Flash base address. It is recommended to always use the real address of the flash here, even if the flash is also available at other addresses (via an alias / remap), depending on the current settings of the device.
  +
|-
  +
| TotalSize || Total flash device size in bytes. This describes the total size of the flash that is achieved when summing up all sector info from <SectorInfo>. If the flash is 512 KB in size, <TotalSize> must be 0x80000 (524,288 => 512 KB)
  +
|-
  +
| PageSize || This field describes in what chunks J-Link feeds the flash loader. The SEGGER_FL_Program() function will be called with a data chunk of multiple of <PageSize> bytes. For example if the flash requires to be programmed in multiple of 128 bytes, <PageSize> should be set to 128. If the flash can be programmed 4 byte wise, <PageSize> should be set to 4.
  +
|-
  +
| Reserved || Set this element to 0
  +
|-
  +
| ErasedVal || Most flashes have an erased value of 0xFF (set this element to 0xFF in such cases). However, some flashes have different erased value like for example 0x00 (set element to 0x00 for such cases)
  +
|-
  +
| TimeoutProg || Timeout in milliseconds (ms) to program one chunk of <PageSize>. <br> Since SEGGER_FL_Program can handle multiple pages at once, the J-Link software calculates how many pages should be programmed and accordingly calculates the total timeout for one call of SEGGER_FL_Program. Therefore the total programming timeout for one call of SEGGER_FL_Program is NumPagesAtOnce * TimeoutProg.
  +
|-
  +
| TimeoutErase || Timeout in milliseconds (ms) to erase one sector. <br> Since SEGGER_FL_Erase can handle multiple sectors at once, the J-Link software calculates how many sectors should be erased and accordingly calculates the total timeout for one call of SEGGER_FL_Erase. Therefore the total erase timeout for one call of SEGGER_FL_Erase is NumSectorsAtOnce * TimeoutErase.
  +
|-
  +
| SectorInfo ||
  +
This element is actually a list of '''different sector sizes''' present on target flash.<br>
  +
Having a flash with uniform sectors will result in only SectorInfo[0] being used for sectorization information.<br>
  +
In case the initial number of [4] regions is not sufficient, the array may be expanded up to [8] by the user when writing the flash algorithm.<br>
  +
For more information, see the example below.
  +
|}
  +
  +
'''Example for SectorInfo[] member'''<br>
  +
<source lang="c">
  +
// Example device with 256 KB divided into:
  +
// 4 * 16 KB sectors
  +
// 1 * 64 KB sectors
  +
// 1 * 128 KB sectors
  +
//
  +
// FlashDevice.TotalSize:
  +
// 0x40000
  +
//
  +
// FlashDevice.SectorInfo[]:
  +
// {
  +
// SectSize StartAddr
  +
// { 0x00004000, 0x00000000 }, // 4 * 16 KB = 64 KB
  +
// { 0x00010000, 0x00010000 }, // 1 * 64 KB = 64 KB
  +
// { 0x00020000, 0x00020000 }, // 1 * 128 KB = 128 KB
  +
// { 0xFFFFFFFF, 0xFFFFFFFF } // Indicates the end of the flash sector layout. Must be present.
  +
// }
  +
//
  +
//
  +
// Example device with 256 KB divided into:
  +
// 256 * 1 KB sectors
  +
//
  +
// FlashDevice.TotalSize:
  +
// 0x40000
  +
//
  +
// FlashDevice.SectorInfo[]:
  +
// {
  +
// SectSize StartAddr
  +
// { 0x00000400, 0x00000000 }, // 256 * 1 KB = 256 KB
  +
// { 0xFFFFFFFF, 0xFFFFFFFF } // Indicates the end of the flash sector layout. Must be present.
  +
// }
  +
//
  +
</source>
  +
  +
== Integrate SFL in J-Link software ==
  +
For more information about how to actually integrate the resulting SFL binary into the J-Link software and connect it with support for your new device, please refer to the [[J-Link_Device_Support_Kit | J-Link DSK wiki article]]
  +
  +
== Stack usage ==
  +
J-Link reserves 512 bytes stack for the SEGGER Flash Loader. This value is fixed and cannot be changed. If 512 bytes cannot be allocated (e.g. for devices with small RAM areas), 256 bytes are used as fallback.
  +
  +
== Section layout ==
  +
The J-Link software expects a special layout when it comes to RO code, RO data, RW data placement in the SFL binary.<br>
  +
The reference algorithms and templates provided with the J-Link DSK already take care of that layout, so there is nothing special to be considered by the user.
  +
  +
The section layout is as expected:
  +
<source lang="c">
  +
section PrgCode // Marks the start of the SFL. Must be the very first section
  +
sections .text, .rodata, ... // In any order
  +
section PrgData // Marks the end of the code + rodata region (functions, const data, ...) and the start of the data region (static + global variables)
  +
sections .textrw, .data, .fast, ... // In any order
  +
section DevDscr // Marks the location of the <FlashDevice> structure variable and also the end of the loader. Must(!!!) be the very last section
  +
</source>
  +
  +
== Templates ==
  +
There are templates as well as functioning reference loaders available in source. These are part of the [[J-Link_Device_Support_Kit| J-Link Device Support Kit (DSK)]].
  +
  +
== Troubleshooting ==
  +
'''General considerations'''<br>
  +
# Get the latest version of the template project
  +
# Follow the Step-By-Step instructions except of 1.2 FlashPrg.c --> Functions should not contain any code that accesses any SFRs
  +
# Build the flash loader using the release configuration
  +
# Perform a flash download using J-Link Commander. Flash download should report an error during verify
  +
# Implement SEGGER_FL_Erase() and retry the flash download test. J-Link Commander should still report verify failed but effected flash memory region should be empty. If not, check SEGGER_FL_Erase().
  +
# Implement SEGGER_FL_Program() and retry the flash download test. Expected result: Test reports O.K. --> Programmed successfully. If not, check SEGGER_FL_Program() code.
  +
  +
'''PC has unexpected value after flash download'''<br>
 
This error may have different root causes:
 
This error may have different root causes:
*Watchdog is enabled but not fed in the flash loader functions. This may result in a watchdog timeout pops up during RAMCode execution. The behavior is different but usually a reset will be triggered.
+
* Watchdog is enabled but not fed in the flash loader functions. This may result in a watchdog timeout pops up during RAMCode execution. The behavior is different but usually a reset will be triggered.
*Accessing not enabled / clocked special function registers / peripherals
+
* Accessing not enabled / clocked special function registers / peripherals
*Accessing invalid memory regions (reserved)
+
* Accessing invalid memory regions (reserved)
  +
===(Q)SPI flashes===
 
  +
'''External flash pin init'''<br>
*The Init() code has to make sure that the (Q)SPI pins as well as the (Q)SPI controller are configured so that the flash can be memory mapped (read) accessed. This is necessary as the J-Link DLL reads the data before programming to check if flash content does already match. This can be validated by setting the compare method in J-Link Commander to "skip" (exec SetCompareMode 0). Now start flash download. J-Link Commander should report a verify error but the flash should be memmory mapped accessible from now. If not, check the Init() code.
 
  +
The SEGGER_FL_Prepare() code has to make sure that the (QSPI) pins as well as the (QSPI) controller are configured so that the flash is memory-mapped read-accessible.<br>
  +
This is necessary as the J-Link software by default compares flash contents before starting the flash programming, to save time in case large portions of the flash are already identical to the programming data.<br>
  +
This can be validated by setting the compare method in J-Link Commander to "skip" (exec SetCompareMode 0). Now start flash download.<br>
  +
J-Link Commander should report a verify error but the flash should be memmory mapped accessible from now. If not, check the Init() code.<br>
  +
  +
'''I get build errors in release build config'''<br>
  +
If you get build errors when switching from "Debug" to "Release" build in the template project the main cause is that third party libraries are used.<br>
  +
The SEGGER Flash Loader interface expects all program parts to be linked to sections PrgCode and PrgData.<br>
  +
Third party libraries often use statically linked program parts which will not be put in the aforementioned sections which will cause a build or linker error.<br>
  +
Generally we recommend not using any third party libraries when creating Flash loaders as they will increase the Flash loader size drastically while usually slowing down the maximum possible Flash loader speed.<br>
  +
If you happen to have to use an external library in your project it is user responsibility to make sure this external library is linked to the aforementioned sections for all application parts.
  +
  +
== SFL FAQ ==
  +
'''Q:''' Do I need a valid Embedded Studio license when using the SEGGER Flash Loader in a commercial scope?<br>
  +
'''A:''' Basically, any usage of ES in a commercial scope requires a valid license. However, the SEGGER Flash Loader is an exception. The evaluation license suffice; a valid license is not required.<br><br>
  +
'''Q:''' How is the *.elf file that is the result from building the SLF executed?<br>
  +
'''A:''' The *.elf file is loaded into the RAM of the target device and executed on its processor.<br><br>
  +
'''Q:''' How are the functions like "SEGGER_FL_Program()" called and executed on the target?<br>
  +
'''A:''' The J-Link DLL analyzes the ELF file to determine the function entry points and then calls those functions.<br><br>
  +
'''Q:''' What does the "SEGGER_FL_Lib_<CORE>_LE.a" file contain and how are they used by SEGGER flash loader?<br>
  +
'''A:''' The file contains generic (not device specific) logic which interacts with the custom Flashloader functions SEGGER_FL_*. It needs to be included in any build.<br><br>
  +
'''Q:''' There are two files "SEGGER_FL_Lib_<CORE>_'''LE'''.a" and "SEGGER_FL_Lib_<CORE>_'''BE'''.a". Which one do I have to use?<br>
  +
'''A:''' "SEGGER_FL_Lib_<CORE>_'''LE'''.a" is used for '''L'''ittle '''E'''ndian targets while "SEGGER_FL_Lib_<CORE>_'''BE'''.a" is used for '''B'''ig '''E'''ndian targets.<br><br>
  +
'''Q:''' My flash loader uses interrupts. It works when debugging, but does not work when inegrated with J-Link software. How can this be solved?<br>
  +
'''A:''' Before calling the flash loader functions, J-Link will disable interrupts on the device. If you require interrupts, you will need to reenable those e.g. in SEGGER_FL_Prepare().

Latest revision as of 14:59, 20 November 2023

SEGGER Flash Loader

The SEGGER Flash Loader (SFL) is part of the J-Link Device Support Kit (DSK) and allows users to add flash programming support for a new device on their own.

Minimum supported J-Link software version

If not stated otherwise for a specific function / feature / etc., the minimum supported J-Link software version is V7.80.

Supported CPU architectures

The SEGGER Flash Loader (SFL) is available for the following architectures:

  • ARMv4/v5
    • ARM720T, ARM7TDMI, ARM7TDMI-S
    • ARM920T, ARM922T, ARM926EJ-S, ARM946E-S, ARM966E-S
  • ARMv6-M
    • Cortex-M0, Cortex-M0+, Cortex-M1
  • ARMv7-M
    • Cortex-M3, Cortex-M4, Cortex-M7
  • ARMv8-M
    • Cortex-M23, Cortex-M33, Cortex-M55, Cortex-M85
  • ARMv7-A
    • Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A12, Cortex-A15, Cortex-A17
  • ARMv7-R
    • Cortex-R4, Cortex-R5, Cortex-R7, Cortex-R8
  • ARMv8-R
    • Cortex-R52
  • RISC-V RV32
Note:

Architectures / cores not listed here must be assumed as being not supported.
While they may work by chance, no support is provided for problems in regards to getting SEGGER Flash Loaders running on non-listed architectures.

In case of doubt, please feel free to contact SEGGER.

Supported flash types

Because a SEGGER Flash Loader programs the flash via the MCU it runs on, basically any flash (or other non-volatile memories) can be supported.
This applies to flash that is memory mapped accessible by the MCU (internal flash, external QSPI NOR flash, ...) as well as to non-memory mapped flashes (external I2C EEPROM, external NAND flash, ...)

For non-memory-mapped flashes, the following additional entry functions must be implemented in an SFL:

  • SEGGER_FL_CheckBlank()
  • SEGGER_FL_Verify()
  • SEGGER_FL_Read()
  • SEGGER_FL_CalcCRC()

Entry functions overview

The following table gives an overview about the mandatory and optional entry functions, of a SEGGER Flash Loader:

Entry function Type
SEGGER_FL_Prepare() Mandatory
SEGGER_FL_Restore() Mandatory
SEGGER_FL_Program() Mandatory
SEGGER_FL_Erase() Mandatory
SEGGER_FL_EraseChip() Optional
SEGGER_FL_CheckBlank() Optional
SEGGER_FL_Verify() Optional
SEGGER_FL_Read() Optional
SEGGER_FL_CalcCRC() Optional
SEGGER_FL_Start() Optional
SEGGER_FL_GetFlashInfo() Optional

SEGGER_FL_Prepare

Prototype

int SEGGER_FL_Prepare(U32 PreparePara0, U32 PreparePara1, U32 PreparePara2);

Function description
Mandatory function. Must be present to make SFL detected as valid.
Prepares SFL for further usage. Very first function of SFL to be called.
Can rely on not being called multiple times in a row without a SEGGER_FL_Restore() in between.
This function may be used for example to initialize the PLL of the device before flash programming starts, to improve flash programming performance.
The following is a valid series of calls:

SEGGER_FL_Prepare()
SEGGER_FL_Erase()
SEGGER_FL_Program()
SEGGER_FL_Restore()
SEGGER_FL_Prepare()
SEGGER_FL_Erase()
SEGGER_FL_Restore()

Parameters

Parameter Description
PreparePara0 Reserved for future use. Always == 0 for now
PreparePara1 Reserved for future use. Always == 0 for now
PreparePara2 Reserved for future use. Always == 0 for now

Return value

Value Meaning
>= 0 OK
== 0 OK, Clock speed of core not changed
> 0 New clock speed in [Hz](!) of core
< 0 Error

SEGGER_FL_Restore

Prototype

int SEGGER_FL_Restore(U32 RestorePara0, U32 RestorePara1, U32 RestorePara2);

Function description
Mandatory function. Must be present to make SFL detected as valid.
Restores SFL after work is done. Very last function of SFL to be called.
This function may be used for example to restore the PLL settings of the device after flash programming is done.
This is for example needed when using the unlimited number of breakpoints in flash feature of J-Link.

Parameters

Parameter Description
RestorePara0 Reserved for future use. Always == 0 for now
RestorePara1 Reserved for future use. Always == 0 for now
RestorePara2 Reserved for future use. Always == 0 for now

Return value

Value Meaning
>= 0 OK
< 0 Error

Notes

Note:

Can rely on not being called multiple times in a row without a SEGGER_FL_Prepare() in between.
The following is a valid (but unlikely) series of calls:

  • SEGGER_FL_Prepare()
  • SEGGER_FL_Erase()
  • SEGGER_FL_Program()
  • SEGGER_FL_Restore()
  • SEGGER_FL_Prepare()
  • SEGGER_FL_Erase()
  • SEGGER_FL_Restore()

SEGGER_FL_Program

Prototype

int SEGGER_FL_Program(U32 DestAddr, U32 NumBytes, U8 *pSrcBuff);

Function description
Mandatory function. Must be present to make SFL detected as valid.
Programs flash. The block passed to this function is always a multiple of what is indicated as page size by FlashDevice.PageSize.
This function can rely on only being called with destination addresses and NumBytes that are aligned to FlashDevice.PageSize.

Parameters

Parameter Description
DestAddr Destination address. Always aligned to FlashDevice.PageSize
NumBytes Number of bytes to be programmed (always a multiple of FlashDevice.PageSize)
pSrcBuff Pointer to the data to be programmed

Return value

Value Meaning
== 0 O.K.
== 1 Error
== 2 O.K., already performed implicit verify of block that was just programmed

SEGGER_FL_Erase

Prototype

int SEGGER_FL_Erase(U32 SectorAddr, U32 SectorIndex, U32 NumSectors);

Function description
Mandatory function. Must be present to make SFL detected as valid.
Erases flash. For one-time programmable memories (OTP), this function may check if the passed sector is still erased/not programmed and throw an error in case it already is programmed.

Parameters

Parameter Description
SectorAddr Address of the first sector to be erased.
SectorIndex Index of the start sector to be erased. Counting starts at 0 (first sector reported by FlashDevice.SectorInfo[0])
NumSectors Number of sectors to be erased. It is the responsibility of this function to track the sector size in case a device provides multiple sector sizes.

Return value

Value Meaning
== 0 O.K.
== 1 Error

SEGGER_FL_EraseChip

Prototype

int SEGGER_FL_EraseChip(void);

Function description
Optional function. May be present to speed up erase procedure under special circumstances

Parameters

Parameter Description
None

Return value

Value Meaning
== 0 O.K.
== 1 Error

SEGGER_FL_CheckBlank

Prototype

int SEGGER_FL_CheckBlank(U32 Addr, U32 NumBytes, U8 BlankValue);

Function description
Optional function. May not be present.
Checks if a memory region is blank / erased / unprogrammed.
Mainly used to speed up flash programming as it allows J-Link to skip calls to SEGGER_FL_Erase() before calling SEGGER_FL_Program(), in case a sector is already erased.

Parameters

Parameter Description
Addr Address where checking for blank / erased data should start
NumBytes Number of bytes to be checked
BlankValue Blank (erased) value of flash (Most flashes have 0xFF, some have 0x00, some do not have a defined erased value)

Return value

Value Meaning
>= 0 OK
== 0 OK, complete region is blank
== 1 OK, not the complete region is blank
< 0 Error

SEGGER_FL_Verify

Prototype

U32 SEGGER_FL_Verify(U32 Addr, U32 NumBytes, U8* pData);

Function description
Optional function. May not be present. Not present for most memory-mapped accessible flash memories.
Verifies a given range by comparing the provided data versus the data in the flash.
Mainly used for non-memory mapped flashes in case flash is not simply read-accissble for the core at a certain address.

Parameters

Parameter Description
Addr Address where verify should start
NumBytes Number of bytes to verify
pBuff Pointer to data to compare flash contents to

Return value

Value Meaning
xxx End address of verification.
ReturnVal == Addr+NumBytes indicates successful verification
ReturnVal != Addr+NumBytes indicates an error and gives the address where verification failed

SEGGER_FL_Read

Prototype

int SEGGER_FL_Read(U32 Addr, U32 NumBytes, U8 *pDestBuff);

Function description
Optional function. May not be present.
Not needed for memory-mapped flashes that can be just read by the MCU core as RAM or other memories. Mainly used for non-memory mapped flashes where a virtual addres has been assigned to make J-Link flash download work.
If this function is present, J-Link will call it to read flash memory instead of reading it directly via the core.

Parameters

Parameter Description
Addr Address to start reading flash at
NumBytes Number of bytes to read
pBuff Pointer to buffer where to store read data to

Return value

Value Meaning
>= 0 OK, number of bytes read (usually == NumBytes)
< 0 Error

SEGGER_FL_CalcCRC

Prototype

U32 SEGGER_FL_CalcCRC(U32 CRC, U32 Addr, U32 NumBytes, U32 Polynom);

Function description
Optional function, may not be present.
If present, J-Link may call this function to speed up the verification because not all data must be read + transferred back to the host but instead only the CRC (calculated by the SFL) is transferred to the host.

Parameters

Parameter Description
CRC Start value of CRC
Addr Address where calculation of CRC starts
NumBytes Number of bytes to calculate CRC on
Polynom Polynom to use for CRC calculation

Return value

Value Meaning
xxx Calculated CRC

Notes

Note:
  1. If an SFL implements this function, it is recommended to simply call SEGGER_OFL_Lib_CalcCRC() from the SEGGER_SFL_Lib.a library and pass its return value to the caller.

SEGGER_FL_Start

Prototype

void SEGGER_FL_Start(volatile struct SEGGER_FL_CMD_INFO* pInfo);

Function description
Optional function, may not be present.
If present and target architecture supports turbo mode, J-Link will use this entry function to start turbo mode which will lead to a big performance gain in flash programming.
If an SFL implements this function, it should simply call SEGGER_OFL_Lib_StartTurbo() from the SEGGER_SFL_Lib.a library. The exact operation of SEGGER_OFL_Lib_StartTurbo() is not disclosed.

Parameters

Parameter Description
pInfo Pointer to command info for SEGGER_OFL_Lib_StartTurbo()

Return value

Value Meaning
None

SEGGER_FL_GetFlashInfo

Prototype

int SEGGER_FL_GetFlashInfo(SEGGER_FL_FLASH_INFO* pInfo, U32 InfoAreaSize);

Function description
Optional function. May not be present.
Only needed for flash loaders where the exact sectorization is determined at runtime.
This is for example the case for some loaders for external QSPI NOR flash, where different users may have different QSPI flashes connected to their hardware.
This allows to have only 1 loader to serve many different setups.

Parameters

Parameter Description
pInfo Points to info area which is used to store the flash info.
InfoAreaSize Indicates how big the area pointed to by SEGGER_FL_FLASH_INFO really is.
May be used to extend pInfo->aRangeInfo[] in case more elements are needed for the detected flash memory.

Return value

Value Meaning
>= 0 OK, number of bytes read (usually == NumBytes)
< 0 Error

Notes

Note:
  1. If present, this function is called before any erase, program, verify operation but after Preare().
  2. If present, this function overrides the information provided by FlashDevice.TotalSize and FlashDevice.SectorInfo[]

FlashDevice struct

The FlashDevice structure variable contains all the static information about the flash algorithm like sectorization of the flash, programming chunk size, ...
In the following, the structure elements are explained in detail to give a good idea about what needs to be filled in for a new flash loader.

struct FlashDevice  {
  U16 AlgoVer;
  U8  Name[128];
  U16 Type;
  U32 BaseAddr;
  U32 TotalSize;
  U32 PageSize;
  U32 Reserved;
  U8  ErasedVal;
  U32 TimeoutProg;
  U32 TimeoutErase;
  struct SECTOR_INFO SectorInfo[MAX_NUM_SECTORS];
};
Member Explanation
AlgoVer Set to 0x0101. Do not set to anything else!
Name Name of the flash bank this flash loader handles. (E.g. "internal flash", "QSPI", ...). Must not exceed 127 characters (last character reserved for string termination). NEVER change the size of this array!
Type Flash device type. Currently ignored. Set to 1 to get max. compatibility.
BaseAddr Flash base address. It is recommended to always use the real address of the flash here, even if the flash is also available at other addresses (via an alias / remap), depending on the current settings of the device.
TotalSize Total flash device size in bytes. This describes the total size of the flash that is achieved when summing up all sector info from <SectorInfo>. If the flash is 512 KB in size, <TotalSize> must be 0x80000 (524,288 => 512 KB)
PageSize This field describes in what chunks J-Link feeds the flash loader. The SEGGER_FL_Program() function will be called with a data chunk of multiple of <PageSize> bytes. For example if the flash requires to be programmed in multiple of 128 bytes, <PageSize> should be set to 128. If the flash can be programmed 4 byte wise, <PageSize> should be set to 4.
Reserved Set this element to 0
ErasedVal Most flashes have an erased value of 0xFF (set this element to 0xFF in such cases). However, some flashes have different erased value like for example 0x00 (set element to 0x00 for such cases)
TimeoutProg Timeout in milliseconds (ms) to program one chunk of <PageSize>.
Since SEGGER_FL_Program can handle multiple pages at once, the J-Link software calculates how many pages should be programmed and accordingly calculates the total timeout for one call of SEGGER_FL_Program. Therefore the total programming timeout for one call of SEGGER_FL_Program is NumPagesAtOnce * TimeoutProg.
TimeoutErase Timeout in milliseconds (ms) to erase one sector.
Since SEGGER_FL_Erase can handle multiple sectors at once, the J-Link software calculates how many sectors should be erased and accordingly calculates the total timeout for one call of SEGGER_FL_Erase. Therefore the total erase timeout for one call of SEGGER_FL_Erase is NumSectorsAtOnce * TimeoutErase.
SectorInfo

This element is actually a list of different sector sizes present on target flash.
Having a flash with uniform sectors will result in only SectorInfo[0] being used for sectorization information.
In case the initial number of [4] regions is not sufficient, the array may be expanded up to [8] by the user when writing the flash algorithm.
For more information, see the example below.

Example for SectorInfo[] member

// Example device with 256 KB divided into:
//   4 *  16 KB sectors
//   1 *  64 KB sectors
//   1 * 128 KB sectors
//
// FlashDevice.TotalSize:
//   0x40000
//
// FlashDevice.SectorInfo[]:
//   {
//       SectSize    StartAddr
//     { 0x00004000, 0x00000000 },   // 4 *  16 KB =  64 KB
//     { 0x00010000, 0x00010000 },   // 1 *  64 KB =  64 KB
//     { 0x00020000, 0x00020000 },   // 1 * 128 KB = 128 KB
//     { 0xFFFFFFFF, 0xFFFFFFFF }    // Indicates the end of the flash sector layout. Must be present.
//   }
//
//
// Example device with 256 KB divided into:
// 256 *   1 KB sectors
//
// FlashDevice.TotalSize:
//   0x40000
//
// FlashDevice.SectorInfo[]:
//   {
//       SectSize    StartAddr
//     { 0x00000400, 0x00000000 },   // 256 *  1 KB =  256 KB
//     { 0xFFFFFFFF, 0xFFFFFFFF }    // Indicates the end of the flash sector layout. Must be present.
//   }
//

Integrate SFL in J-Link software

For more information about how to actually integrate the resulting SFL binary into the J-Link software and connect it with support for your new device, please refer to the J-Link DSK wiki article

Stack usage

J-Link reserves 512 bytes stack for the SEGGER Flash Loader. This value is fixed and cannot be changed. If 512 bytes cannot be allocated (e.g. for devices with small RAM areas), 256 bytes are used as fallback.

Section layout

The J-Link software expects a special layout when it comes to RO code, RO data, RW data placement in the SFL binary.
The reference algorithms and templates provided with the J-Link DSK already take care of that layout, so there is nothing special to be considered by the user.

The section layout is as expected:

section PrgCode                     // Marks the start of the SFL. Must be the very first section
sections .text, .rodata, ...        // In any order
section PrgData                     // Marks the end of the code + rodata region (functions, const data, ...) and the start of the data region (static + global variables)
sections .textrw, .data, .fast, ... // In any order
section DevDscr                     // Marks the location of the <FlashDevice> structure variable and also the end of the loader. Must(!!!) be the very last section

Templates

There are templates as well as functioning reference loaders available in source. These are part of the J-Link Device Support Kit (DSK).

Troubleshooting

General considerations

  1. Get the latest version of the template project
  2. Follow the Step-By-Step instructions except of 1.2 FlashPrg.c --> Functions should not contain any code that accesses any SFRs
  3. Build the flash loader using the release configuration
  4. Perform a flash download using J-Link Commander. Flash download should report an error during verify
  5. Implement SEGGER_FL_Erase() and retry the flash download test. J-Link Commander should still report verify failed but effected flash memory region should be empty. If not, check SEGGER_FL_Erase().
  6. Implement SEGGER_FL_Program() and retry the flash download test. Expected result: Test reports O.K. --> Programmed successfully. If not, check SEGGER_FL_Program() code.

PC has unexpected value after flash download
This error may have different root causes:

  • Watchdog is enabled but not fed in the flash loader functions. This may result in a watchdog timeout pops up during RAMCode execution. The behavior is different but usually a reset will be triggered.
  • Accessing not enabled / clocked special function registers / peripherals
  • Accessing invalid memory regions (reserved)

External flash pin init
The SEGGER_FL_Prepare() code has to make sure that the (QSPI) pins as well as the (QSPI) controller are configured so that the flash is memory-mapped read-accessible.
This is necessary as the J-Link software by default compares flash contents before starting the flash programming, to save time in case large portions of the flash are already identical to the programming data.
This can be validated by setting the compare method in J-Link Commander to "skip" (exec SetCompareMode 0). Now start flash download.
J-Link Commander should report a verify error but the flash should be memmory mapped accessible from now. If not, check the Init() code.

I get build errors in release build config
If you get build errors when switching from "Debug" to "Release" build in the template project the main cause is that third party libraries are used.
The SEGGER Flash Loader interface expects all program parts to be linked to sections PrgCode and PrgData.
Third party libraries often use statically linked program parts which will not be put in the aforementioned sections which will cause a build or linker error.
Generally we recommend not using any third party libraries when creating Flash loaders as they will increase the Flash loader size drastically while usually slowing down the maximum possible Flash loader speed.
If you happen to have to use an external library in your project it is user responsibility to make sure this external library is linked to the aforementioned sections for all application parts.

SFL FAQ

Q: Do I need a valid Embedded Studio license when using the SEGGER Flash Loader in a commercial scope?
A: Basically, any usage of ES in a commercial scope requires a valid license. However, the SEGGER Flash Loader is an exception. The evaluation license suffice; a valid license is not required.

Q: How is the *.elf file that is the result from building the SLF executed?
A: The *.elf file is loaded into the RAM of the target device and executed on its processor.

Q: How are the functions like "SEGGER_FL_Program()" called and executed on the target?
A: The J-Link DLL analyzes the ELF file to determine the function entry points and then calls those functions.

Q: What does the "SEGGER_FL_Lib_<CORE>_LE.a" file contain and how are they used by SEGGER flash loader?
A: The file contains generic (not device specific) logic which interacts with the custom Flashloader functions SEGGER_FL_*. It needs to be included in any build.

Q: There are two files "SEGGER_FL_Lib_<CORE>_LE.a" and "SEGGER_FL_Lib_<CORE>_BE.a". Which one do I have to use?
A: "SEGGER_FL_Lib_<CORE>_LE.a" is used for Little Endian targets while "SEGGER_FL_Lib_<CORE>_BE.a" is used for Big Endian targets.

Q: My flash loader uses interrupts. It works when debugging, but does not work when inegrated with J-Link software. How can this be solved?
A: Before calling the flash loader functions, J-Link will disable interrupts on the device. If you require interrupts, you will need to reenable those e.g. in SEGGER_FL_Prepare().