cancel
Showing results for 
Search instead for 
Did you mean: 

memory map adjust SBSFU on a STM32G474

dominik
Senior

Hi

I'm using the dual image function on a 512kB STM32G474. I like to adjust the bootloader size to 32kb because my user App is too big.

In the AN5056 there is a note how to adjust it, but I'm not sure if this lines in the file low_level_security.h are correct? Can anybody help me please?

#define SFU_PROTECT_MPU_EXEC_SE_RGNV  MPU_REGION_NUMBER7
#define SFU_PROTECT_MPU_EXEC_SE_START FLASH_BASE           /*!< Flash memory area */
#define SFU_PROTECT_MPU_EXEC_SE_SIZE  MPU_REGION_SIZE_16KB //eud MPU_REGION_SIZE_32KB
#if defined (__GNUC__)
#define SFU_PROTECT_MPU_EXEC_SE_SREG  0xE0U                /*!< 32 Kbytes / 8 * 5 ==> 20 Kbytes */
#elif defined(__CC_ARM)
#define SFU_PROTECT_MPU_EXEC_SE_SREG  0x80U                /*!< 32 Kbytes / 8 * 7 ==> 28 Kbytes */
#else
#define SFU_PROTECT_MPU_EXEC_SE_SREG  0xC0U                /*!< 32 Kbytes / 8 * 6 ==> 24 Kbytes */
#endif /* (__GNUC__) */
#define SFU_PROTECT_MPU_EXEC_SE_PERM  MPU_REGION_PRIV_RO
#define SFU_PROTECT_MPU_EXEC_SE_EXECV MPU_INSTRUCTION_ACCESS_ENABLE
#define SFU_PROTECT_MPU_EXEC_SE_TEXV  MPU_TEX_LEVEL0
#define SFU_PROTECT_MPU_EXEC_SE_B     MPU_ACCESS_NOT_BUFFERABLE
#define SFU_PROTECT_MPU_EXEC_SE_C     MPU_ACCESS_CACHEABLE

Is the setting for SFU_PROTECT_MPU_EXEC_SE_SREG the same like before?

thanks

/*###ICF### Set of symbols used in SE and SB_SFU projects ****/
 
/* Slots Regions must be aligned on 4096 bytes (0x1000) */
 
/* swap region (8 Kbytes) */
define exported symbol  __ICFEDIT_region_SWAP_start__  = 0x08042000;
define exported symbol  __ICFEDIT_region_SWAP_end__    = 0x08043FFF;
 
/* slot 0 region (232 Kbytes) */
define exported symbol  __ICFEDIT_region_SLOT_0_start__= 0x08008000;
define exported symbol  __ICFEDIT_region_SLOT_0_end__  = 0x08041FFF;
 
/* slot 1 region (232 KBytes) */
define exported symbol  __ICFEDIT_region_SLOT_1_start__= 0x08044000;
define exported symbol  __ICFEDIT_region_SLOT_1_end__  = 0x0807DFFF;
 
/* firmware images regions definition */
define region SWAP_region   = mem:[from __ICFEDIT_region_SWAP_start__ to __ICFEDIT_region_SWAP_end__];
define region SLOT_0_region = mem:[from __ICFEDIT_region_SLOT_0_start__ to __ICFEDIT_region_SLOT_0_end__];
define region SLOT_1_region = mem:[from __ICFEDIT_region_SLOT_1_start__ to __ICFEDIT_region_SLOT_1_end__];
/* SE Startup: call before enabling protected area */
define exported symbol __ICFEDIT_SE_Startup_region_ROM_start__    = __ICFEDIT_SE_Key_region_ROM_end__ + 1;
define exported symbol __ICFEDIT_SE_Code_nokey_region_ROM_start__ = __ICFEDIT_SE_Startup_region_ROM_start__ + 0x100;
/* Aligned SE End at the end of the 1st 12Kbytes of flash, MPU protection isolation constraints */
define exported symbol __ICFEDIT_SE_Code_region_ROM_end__         = 0x08002FFF;
 
/* SE IF ROM: used to locate Secure Engine interface code out of protected area */
define exported symbol __ICFEDIT_SE_IF_region_ROM_start__         = __ICFEDIT_SE_Code_region_ROM_end__ + 1;
define exported symbol __ICFEDIT_SE_IF_region_ROM_end__           = __ICFEDIT_SE_IF_region_ROM_start__ + 0x5FF;
 
/* SBSFU Code region */
define exported symbol __ICFEDIT_SB_region_ROM_start__            = __ICFEDIT_SE_IF_region_ROM_end__ + 1;
/* Aligned SBSFU end at the end of the 1st 32Kbytes of FLASH, MPU protection isolation constraints */
define exported symbol __ICFEDIT_SB_region_ROM_end__              = 0x08007FFF;

20 REPLIES 20
dominik
Senior

@Jocelyn RICARD​ 

The last free user data part I can delete, or for what is this used?

I changed the icf file to the following settings:

/*###ICF### Set of symbols used in SE and SB_SFU projects ****/
 
/* Slots Regions must be aligned on 4096 bytes (0x1000) */
 
/* swap region (4 Kbytes) */
define exported symbol  __ICFEDIT_region_SWAP_start__  = 0x08043000;
define exported symbol  __ICFEDIT_region_SWAP_end__    = 0x08043FFF;
 
/* slot 0 region (236 Kbytes) */
define exported symbol  __ICFEDIT_region_SLOT_0_start__= 0x08008000;
define exported symbol  __ICFEDIT_region_SLOT_0_end__  = 0x08042FFF;
 
/* slot 1 region (236 KBytes) */
define exported symbol  __ICFEDIT_region_SLOT_1_start__= 0x08044000;
define exported symbol  __ICFEDIT_region_SLOT_1_end__  = 0x0807EFFF;
 
/* firmware images regions definition */
define region SWAP_region   = mem:[from __ICFEDIT_region_SWAP_start__ to __ICFEDIT_region_SWAP_end__];
define region SLOT_0_region = mem:[from __ICFEDIT_region_SLOT_0_start__ to __ICFEDIT_region_SLOT_0_end__];
define region SLOT_1_region = mem:[from __ICFEDIT_region_SLOT_1_start__ to __ICFEDIT_region_SLOT_1_end__];

The SWAP area is now 4kB instead of 8kB, Slot Region 236kB instead of 232kb. Usable in the Compiler is 232kB, start in the Map file is @0x08009000, why this 0x1000 (4kB) offset?

0693W000007CtQ6QAK.jpg 

Jocelyn RICARD
ST Employee

Hi Dominik,

About your sentence

" You are talking about this node like in the picture, right?

Like I understand, I need change this node everytime when I generate a new GCM key for a Bootloader/Application, right?"

I'm sorry I don't catch your question or the relation you make between GCM key and these adaptations.

What I said is that each time you generate a new firmware update, the nonce file should be changed. Basically recreated with a random.

Actually, if you delete the file, it is automatically rebuilt with random.

Regarding Free for user data, this is at it says: Free :). So, you can adapt your mapping to use it for your the swap and extent your slot size.

This area is in the example to show that you can use a part of the flash to write data that will not be erased by a firmware update.

This is usually to made to store device specific settings, tuning etc ...

Best regards

Jocelyn

dominik
Senior

Hi Jocelyn

What I said is that each time you generate a new firmware update, the nonce file should be changed. Basically recreated with a random.

Actually, if you delete the file, it is automatically rebuilt with random.

-> Yes, with the CBC setup on a rebuild I got a new sfb file on every rebuild. With the GCM setup a rebuild of the application without a change in the code doesn't change the sfb file. Maybe if I rebuild the bootloader aswell, I will try tomorrow, thanks.

About the free user data its clear now, thanks 🙂

But I'm not sure why the start in the Map file is @0x08009000 and not 0x08008000, why this 0x1000 (4kB) offset? Can you explain this in a few words?

Regards, Dominik

dominik
Senior

@Jocelyn RICARD​ 

The project is running now, but I have a HradFault because my Stack is full. Whats the maximum size of the stack which is possible to setup?

In the sbsf.icf file I have the setting from FFF until 1FFF which is 0x1000:

/******************************************************************************/
/*                              RAM section                                   */
/*                                                                            */
/******************************************************************************/
 
/* SE RAM1 region protected area */
/* SE stack is placed 1st in RAM, stack overflow does not write on other RAM area */
define exported symbol __ICFEDIT_SE_region_RAM_start__     = 0x20000000;
define exported symbol __ICFEDIT_SE_region_RAM_stack_top__ = 0x20000400; /* Secure Engine's private stack */
define exported symbol __ICFEDIT_SE_region_RAM_end__       = 0x20000FFF;
 
/* SBSFU RAM1 region */
define exported symbol __ICFEDIT_SB_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1;
define exported symbol __ICFEDIT_SB_region_RAM_end__   = 0x2001FFFF;

In the file "stm32g474xx_flash.icf" the stack and heap are defined like in the following lines:

/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;

This setting is too low, but whats the maximum size for the cstack and heap?

I think STM32G474VE has 96kb RAM?

Thanks a lot

Jocelyn RICARD
ST Employee

Hi Dominik,

I'm not sure which stack you are talking about.

On G4 project stack size of SBSFU it 0x5000.

Best regards

Jocelyn

dominik
Senior

Hi @Jocelyn RICARD​ 

I'm talking about the 2Images UserApp stack and the definition in the file stm32g474xx_flash.icf.

The original setting in this file is:

/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;

But with this setting my own application runs into a hard fault because of a stack overflow. When I change the settings in this file to

/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_heap__   = 0x1000;

the init of my project is running, but as soon as my application is switching to running mode and is doing some work on the processor which needs some variables, arrays and so on, I have again a hard fault... So I changed my functions to improve the stack usage but I'm not able to reduce it as much as no HardFault is generated. Also I use the compiler setting with the highest optimization on size, which is maybe also not the best solution to cover this problem, but without the optimization my code is too big for the 2image bootloader. If there is no other possibility, I have to switch to the 1image solution and check if its working with a lower optimization level, who knows... But the main point is the stack and heap setting in the project. You wrote the available stack is 0x5000. If I use the 0x5000 I need to set this size in the linker file. But do I need to modify the other linker file because of the protected regions? (in the folder linker common)?

Or do I need to modify the regions in the file "sfu_low_level_security.h" in the SBSFU project? I was thinking that maybe these settings are blocking my RAM usage in the application project because of the entries in the "Enable the read/write operation in privileged mode"?

-> Enable the read/write operation in privileged mode for Secure Engine RAM area.

Best Regards

Dominik

Jocelyn RICARD
ST Employee

Hello Dominik,

ok, I understand now. Your application can use the RAM you need. There is no limitation, except the first 4kB.

So, you can increase the stack size to the needed value.

Best regards

Jocelyn

dominik
Senior

Hi Ricard

I found the bug. I changed the stack to 0x4000. But still receiving a hard fault.

define symbol __ICFEDIT_size_cstack__ = 0x4000;

This is my HardFault.

0693W000007DYeTQAW.jpg0693W000007DYesQAG.jpg0693W000007DYfMQAW.jpgI found out that I have a problem in the bfsr:

0693W000007DZFKQA4.jpgBut now I know where is the root cause:

I have a UART running in parallel which is receiving a lot of communication. This I check in the mainloop with a ringbbuffer from @Tilen MAJERLE​ .

void CheckUsart1RXMessage (void)
{
    static data_message_t rx_data;
    if (ringbuff_get_full(&usart1_rx_dma_ringbuff) >= 1)
    {
        rx_data.data_length = ringbuff_get_full(&usart1_rx_dma_ringbuff);
        -> This causes the ERROR!    ringbuff_read(&usart1_rx_dma_ringbuff,&rx_data.data_a, rx_data.data_length);
        //rx_message_f(&rx_data);
    }
}

When I disable the "ringbuff_read()", the HardFault is not happening anymore. If I enable the function, the ST is running until my statemachine gets running -> I gues a stack overflow or something like this.

@Tilen MAJERLE​ : can we have a remote session about this topic?

Regards, Dominik

dominik
Senior

@Tilen MAJERLE​ , @Jocelyn RICARD​ 

The problem is solved, thaks a lot for your answers.

The bug was that I made a mistake when receiving the UART data with DMA and got an Array overflow which resulted in a HardFault.

The code to handle the ringbuffer is now like this

void CheckUsart1RXMessage (void)
{
    size_t len;
    uint8_t *data;
 
    if ((len = ringbuff_get_linear_block_read_length(&usart1_rx_dma_ringbuff)) > 0)
    {
        data = ringbuff_get_linear_block_read_address(&usart1_rx_dma_ringbuff);
        //check the message
        rx_message_f(data, len);
        /* Now skip sent bytes from buffer = move read pointer */
        ringbuff_skip(&usart1_rx_dma_ringbuff, len);
    }
}
 

the RAM is defined with 0x1FFFF (128kb) and I calculated with 0x1FFF (8kb). So this is not a problem anymore, I use now 0x4000 Stack size (16kb) and 0x1000 (4kb) Heap size. This is more than enough.

Thanks and best Regards, Dominik

dominik
Senior

@Jocelyn RICARD​ 

I'm coming back to the config of the Images because I'm not able to use the 2 Image version anymore.

The bootloader and application is running now on the 1 image solution with the new SBSFU_V2.4.0.

Now Its not possible anymore to do a firmware update in the application, only in the bootloader. In thedmeo code there is the possibility to press the user button during booting to get a new firmware. I have no button and like to trigger the feature in the bootloader from the application. I will receive some commands in the application and do a NVIC_SystemReset();. Is there a possibility to set some variable in the ST Flash before rebooting, check this entry in the bootloader and switch to the local loader in the bootloader if this falsh entry was setted? Then it would be possible to "trigger" the Firmware Download in the application without button. Is there a feature like this already implemented or an application note available?

Thanks a lot