STM32G0xx

Installation

The Paulus bootloader is delivered as zip-archive. After unzip, the following directory structure is available:

Figure 1: directory structure

The bootloader Paulus for the processor STM32G0xx was developed with the STM32 Cube IDE V1.8 on the Nucleo G0B1RE board using the HAL library V1.6.0 for STM32G0xx.

Memory

Shared RAM

The shared RAM for data exchange between bootloader and application program starts at address 0x2001FFF0. The size of the shared RAM is specified in stm32g0xx/bl_interface.h by the compiler-define BL_JUMPCODE_SIZE. The shared memory is installed in the linker script Paulus_stm32g0xx_stm32CubeIde/Paulus_stm32g0xx/STM32G0B1RETX_FLASH.ld as follows:

 

  /* placing RAM section for jumpcode at given address: */

  .myBufBlock 0x2001FFF0 (NOLOAD):

  {

    KEEP(*(.blRAMSection)) /* keep my variable even if not referenced */

  } > RAM

 

The bootloader Paulus supports the keywords APPL and BOOT for the jump code, see /Paulus_man/. The keyword is placed in byte 0-3 of the jump code.

Flash

The total flash size of the STM32G0B1RET6 processor is 512kb. Figure 2 shows the default flash memory map.

Figure 2: flash memory map

The area of configuration data is used for the nonvolatile storage of the CANopen network by the service LSS store.

The area of device data contains the values for object 1018h/1-4. The storage of the values is manufacturer-specific. The bootloader Paulus does not provide a function for the storage of the identity object.

The interrupt vectors for the application program must be placed at an address that is a multiple of 200h. The area <free> results from this condition and the header size of the application program. The application program can have a maximal size of 475 kb.

Linker script

The compiler-project of the bootloader Paulus includes the link to the linker script Paulus_stm32g0xx_stm32CubeIde/Paulus_stm32g0xx/ STM32G0B1RETX_FLASH.ld.

Figure 3: configuration of linker script in the compiler-project for BM

Adaptation to target hardware

In order to integrate the bootloader Paulus on a manufacturer-specific target hardware, some adaptations may be necessary.

CAN controller

The STM32G0B1RET6 processor provides two FDCAN controllers. Paulus uses only one CAN controller. The number of the used CAN controller can be set in stm32g0xx/bl_config.h via the compiler-define CONFIG_CAN_CONTROLLER_NUMBER. FDCAN1 is used by default.

CAN clock

The frequencies used by the bootloader Paulus are documented in stm32g0xx/Readme.txt. The CAN controller is clocked with 64 MHz by default. The clock settings are located in stm32g0xx/stm32g0xx_init.c in function CLOCK_Configration(). Additionally the compiler-define CONFIG_CAN_T_CLK in stm32g0xx/bl_config.h must be changed.

CAN bit timing

The CAN bit timing depends on the CAN clock. The compiler-defines with the CAN bit timing values are specified in stm32g0xx/stm32g0xx_can.c. These values must be replaced for CAN clocks unequal 64 MHz. The values for the CAN bit timing can be determined via https://www.port.de/en/bit-timing.html . Select the CAN controller type ST Microelectronics bxCAN, set the desired CAN clock in the entry field CAN Rate and calculate the CAN bit timing table.

Note: The FDCAN controller uses the same equations for the CAN bit timing calculation as the bxCAN controller.

The value for segment 2 in bttable[] in the module stm32g0xx/stm32g0xx_can.c is FFh for unsupported CAN bit rates.

CAN bus lines

The CAN bus lines are connected to the processor via GPIO pins. The following GPIO pins are used on the Nucleo G0B1RE board:

CAN controller

CAN TX

CAN RX

CAN controller

CAN TX

CAN RX

FDCAN1

PC5

PC4

FDCAN2

PC3

PC2

Table 1: FDCAN GPIO pins

The GPIO pins for the CAN controller can be adjusted in stm32g0xx/stm32g0xx_init.c in the function GPIO_Configuration().

User interface

Bootloader configuration

The bootloader Paulus can be configured via compiler-defines listed in stm32g0xx/bl_config.h.

Node-ID

The node-ID depends on the device on which the bootloader Paulus is running. The user has to return the active node-ID in function getNodeId() in the module stm32g0xx/stm32g0xx_init.c. The node-ID value must be in the range 1-127. If the bootloader Paulus supports the service LSS configure node-ID, the node-ID can also be 255 to mark a non-configured CANopen device.

A fixed default value for the node-ID is configurable via the compiler-define BL_FIXED_NODEID in stm32g0xx/bl_config.h.

CAN bit rate

The CAN bit rate depends on the CANopen network. The user has to return the table index for the active CAN bit rate in function getBitRate() in the module stm32g0xx/stm32g0xx_init.c. The table index is the row number of the CAN bit rate in the CiA CAN bit timing table according to /CiA-305/.

The default CAN bit rate is configurable via the compiler-define BL_USED_BITRATE_INDEX in stm32g0xx/bl_config.h.

Adaptations of the application program

If the application program is used together with the bootloader Paulus, the following modifications to the application program are necessary:

  • change the start address of the application program (mandatory),

  • move the interrupt vectors for the application program (mandatory),

  • specify the address of the shared RAM and implement the jump from AM to BM (optional) and

  • create a downloadable application program (mandatory).

An example for an application program which works together with the bootloader Paulus is delivered in examples/hello_stm32g0xx.

Memory

Shared RAM

The shared RAM is specified in the linker script of the application program as described in main-chapter “Memory”.

Flash

The flash start address of the application program is set in the linker script:

MEMORY

{

  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 144K

  FLASH    (rx)    : ORIGIN = 0x8009200,   LENGTH = 512K

}

Linker script

The compiler-project of the example includes the link to the linker script examples/hello_stm32g0xx/ hello_stm32g0xx/ hello_stm32g0xx/STM32G0B1RETX_FLASH.ld:

Figure 4: configuration of linker script in the compiler-project for AM

It is important that the bootloader Paulus and the application program use the same addresses.

Interrupt vectors

The interrupt vectors for the application program must be moved to address 0800 9200h. The first instruction in main.c shall be:

SCB->VTOR = ((uint32_t)(FLASH_PROGRAM_REAL_START_ADR) & SCB_VTOR_TBLOFF_Msk);

 The vector table must be placed at an address that is a multiple of 200h.

Jump from AM to BM

The jump from AM to BM requires the jump code interface in the application program. The following files from the bootloader Paulus are copied to the application:

  • bl_config.h,

  • bl_flash.h,

  • bl_interface.c,

  • bl_interface.h and

  • bl_type.h.

In examples/hello_stm32g0xx the jump to BM is implemented in examples/hello_stm32g0xx/main.c:

BOOTLOADER_JUMP(APPL);

Normally the jump from BM to AM is initiated by a CANopen Manager. An CANopen application program must include an object for receiving the request from the CANopen Manager. We prefer to implement object 1F51h with sub-index 1.  The writing of value 1 to object 1F51h/1 can be interpreted as start bootloader program.  A possible implementation could be:

  1. create a global variable in main.c:

UNSIGNED8 progCtrlCmd;

progCtrlCmd = 0xFF;  /* invalid program control command */

  1. receive SDO write request to object 1F51h/1: The user function usr_301.c/sdoWrInd() is call.

extern UNSIGNED8 progCtrlCmd;

RET_T sdoWrInd(…)

{

RET_T coRetVal;   /* CANopen Library return value */

UNSIGNED32 size;  /* object size */

     coRetVal = CO_OK;

    if ((0x1F51 == index) & (1 == subIndex))

    {

        coRetVal = getObjEntry(0x1F51, 1, &progCtrlCmd, &size,

            CO_TRUE);

        if ((CO_OK != coRetVal) || (1 != progCtrlCmd))

        {

            progCtrlCmd = 0xFF;

        }

    }

    return(coRetVal);

}

  1. execute jump from AM to BM in the main loop:

main()

{

    …

    while(1)

    {

        FlushMbox();

        …

        if (1 == progCtrlCmd)

        {

            BOOTLOADER_JUMP(APPL);

        }

    }

}

Downloadable application program

The following steps are necessary to create a downloadable application program:

  1. create the application program in binary format:

Figure 5: enable generation of application program in binary format

  1. call the bootloader tool paulus_cksum to generate the header for the application program and to assemble the header and the application program to the downloadable application program

The tool paulus_cksum can be called as post-build command in the compiler-project:

Figure 6: post-build setting

The command line is:

..\..\..\..\..\tools\paulus_cksum.exe -C -l 256 -x 0x08009200 hello_stm32g0xx.bin -O hello_stm32g0xx_download.bin

 The used options are:

C - enable generation of CRC

l - length of the application header in bytes

x - start address of application program (without header)

O - downloadable application program

 The tool paulus_cksum can also be called in the command line window of Windows.

The tool Paulus_cksum is described in /Paulus_CRC/ in detail. Details to the application header are described in /Paulus_man/.

Example for an application program

This example hello_stm32g0xx only toggles the green LED LD4 on the Nucleo G0B1RE board and jumps to BM after 5 s automatically. It is not a CANopen device.

The structure of the example is shown in Figure 7.

The generated binary application program hello_stm32g0xx.bin and the downloadable application program hello_stm32g0xx_download.bin are in examples\hello_stm32g0xx\hello_stm32g0xx\hello_stm32g0xx\Debug.

Figure 7: structure of example for application program

Debugging

The serial interface USART2 is prepared for debug outputs. The debug outputs can be enabled via the compiler-defines DEBUG and X_DEBUG in stm32g0xx/bl_config.h.

The USART2 interface is configured for asynchronous mode with the following characteristics:

  • 115200 baud,

  • word length 8 bits,

  • 1 stop bit,

  • no parity and

  • hardware flow control (RTS and CTS signals) disabled.

The USART2 is initialized in stm32g0xx/stm32g0xx_init.c in function UART_Configuration().

Information can be output using the macro PRINTF() in printf() C syntax, for example:

PRINTF(“NodeId: %u\n”, nodeId);

 The compiler-define X_DEBUG outputs the results of the used HAL library functions additional to the DEBUG outputs.

Special adaptations

The requirements of the bootloader Paulus and the application program can lead to conflicts. This chapter describes possible conflicts and their resolution.

Flash addressing

The bootloader Paulus is located as first program in the flash memory and occupies only the necessary memory space. If the application program uses flash areas for other purposes as assumed in chapter 2, the flash addressing must be adapted.

To be considered are:

  • the linker script of the bootloader Paulus,

  • the linker script of the application program and

  • the compiler-defines shown in Figure 2 in the bootloader sources and the copied files to the application program.

Shared RAM addressing

If the shared RAM is used for application-specific purposes, the address must be changed in:

  • the linker script of the bootloader Paulus and

  • the linker script of the application program.

LSS store

If the application program also supports the service LSS store, the storage of the CANopen network parameters may be different in:

  • the application stores only one CANopen network parameter in opposite to the bootloader Paulus which stores both CANopen network parameters,

  • the application stores the CAN bit rate in kbit/s instead of the table index,

  • the application uses a different flash memory mapping as the bootloader Paulus or

  • the application uses a different method to save the CANopen network parameters in flash.

The following functions of the bootloader Paulus must be adapted:

  • stm32g0xx/stm32g0xx_flash.c/flashWrConfData(),

  • stm32g0xx/stm32g0xx_init.c/getNodeId() and

  • stm32g0xx/ stm32g0xx_init.c/getBitRate().

Paulus initialization

The device initialization requires additional target-specific initialization steps. The additional target-specific initialization steps can be added in the function iniDevice() in stm32g0xx/stm32g0xx_init.c.

Glossary

AM

Application Mode, corresponds to application program

BM

Bootloader Mode, corresponds to bootloader program

CiA

CAN in Automation, manufacturer and user association

References

/CiA-305/: standard CiA-305 “CANopen Layer Setting Services and Protocols”

/Paulus_CRC/: manual “Paulus Checksum Tool”, see file tools/manual_cksum.pdf

/Paulus_man/: manual “Paulus User Manual”, see file UserMan_Paulus_Bootloader_e.pdf