2021-04-08 05:16 AM
Hello,
I want to implement my own UserApp (just a blinking LED for the moment but it will implement FreeRTOS and LwIP in future) on Nucleo-H753ZI. I followed Youtube tutorials for SBSFU especially Security Part6 - 04 Experience SBSFU benefits. Then, I managed to run successfully the SBSFU example like in Security Part6 - 02 Building the SBSFU.
I made my linker script like this:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of "RAM_D1" Ram type memory */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x800 ; /* required amount of stack */
/* Memories definition */
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ISR_VECTOR (rx) : ORIGIN = 0x8020000 + 0x400, LENGTH = 0x400
FLASH (rx) : ORIGIN = 0x8020000 + 0x800, LENGTH = 0x8100000 - 0x8020800
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(8);
KEEP(*(.isr_vector)) /* Startup code */
FILL(0);
. = ORIGIN(ISR_VECTOR) + LENGTH(ISR_VECTOR) - 1;
BYTE(0)
. = ALIGN(8);
} >ISR_VECTOR
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(8);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(8);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data into "FLASH" Rom type memory */
.rodata :
{
. = ALIGN(8);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(8);
} >FLASH
.ARM.extab : {
. = ALIGN(8);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(8);
} >FLASH
.ARM : {
. = ALIGN(8);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(8);
} >FLASH
.preinit_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(8);
} >FLASH
.init_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(8);
} >FLASH
.fini_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(8);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM_D1" Ram type memory */
.data :
{
. = ALIGN(8);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
/**(.RamFunc)*/ /* .RamFunc sections */
/**(.RamFunc*)*/ /* .RamFunc* sections */
. = ALIGN(8);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH
/* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) and H7 flash writing unit (32 bytes)*/
.align32 :
{
. = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 32 bytes: add 1 byte gap */
. = ALIGN(32) - 1; /* increment the location counter until next 32 bytes aligned address (-1 byte) */
BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 32 bytes */
} > FLASH
/* Uninitialized data section into "RAM_D1" Ram type memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM_D1
/* User_heap_stack section, used to check that there is enough "RAM_D1" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM_D1
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
I also defined VECT_TAB_OFFSET in system_stm32h7xx.c like this:
#define VECT_TAB_OFFSET 0x08020400
Here my main function:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ETH_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
IWDG1->KR = IWDG_KEY_RELOAD;
HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
HAL_Delay(50);
}
/* USER CODE END 3 */
}
I manage to build the binary with the SBSFU and my app. SBSFU accepts my app and try to run it until Watchdog reset error. The LED never blinks. Then, it seems that SBSFU jump to my app does not work as I expect.
Regards
Kevyn
2021-04-08 01:18 PM
Hi Kevyn,
I don't see obvious reason for your issue from your code.
I guess you didn't change the slots mapping.
I would suggest deactivating the protections in the app_sfu.h and check with debugger what happens.
Best regards
Jocelyn
2021-04-09 01:53 AM
Hello Jocelyn,
Thank you for your answer and your help.
If I remove Ethernet connectivity it is working ! Same thing, if I remove MPU protection from app_sfu.h. It seems then there is a conflict between Ethernet connectivity and MPU protection.
Here my Ethernet connectivity configuration:
Have you any idea of the reason of the conflict ? Thank you.
Regards
Kevyn
2021-08-26 04:03 AM
Hello!
have you solved this issue? I am facing the same problem with the ethernet and watchdog reset!
Thanks
2021-08-27 05:23 AM
Hello
Yes, I have solved this issue. I did several things to make it works.
Firstly, I moved MPU_Config and the Cache activation on USER CODE 2
/* USER CODE BEGIN 2 */
MPU_Config();
SCB_EnableICache();
SCB_EnableDCache();
/* USER CODE END 2 */
I also disabled ICache and DCache in sfu_mpu_isolation.c
#if defined(SFU_MPU_PROTECT_ENABLE)
SCB_InvalidateICache();
SCB_CleanDCache();
SCB_DisableICache();
SCB_DisableDCache();
#endif /* SFU_MPU_PROTECT_ENABLE */
And I have this MPU Config in my app for LwIP on SRAM2
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30044000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER5;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER6;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER7;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER8;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER9;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER10;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER11;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER12;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER13;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER14;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Enable = MPU_REGION_DISABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER15;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
I imagine there is a better way to do it (not sure that everything is required to make it works) but it works for me. I hope it will help you.
Regards
Kevyn
2021-08-27 08:56 AM
Hello!
thank you for your information, but your solution unfortunately has not solved my issue, I have seen that before these changes if you had disabled the MPU protection in app_sfu.h the board is functioning even though the ethernet is on; this is not valid for me so maybe there is something different that breaks the FW.
I have created a dedicated thread if you want to see more details
Thanks!
2021-08-27 09:40 PM
>I made my linker script like this
These are not stopping this code from working. Just areas for improvement.
>I also defined VECT_TAB_OFFSET in system_stm32h7xx.c like this
Another area for improvement.
Your linker script describes where things are located.
Add a symbol in your .isr_vector output section immediately before its loading the .isr_vector input section:
isr_vector_start = .
Then declare that and use its address in your .c:
extern uint32_t isr_vector_start;
#define VECT_TAB_OFFSET ((uint32_t)&isr_vector_start)
>Here my main function
That should be fine.
>Yes, I have solved this issue. I did several things to make it works.
I cannot see the root cause of the problem from your changes.
Perhaps post the boot source code that launches your app.
Without your changes, does the app work if you load and execute it the debugger, i.e. without the SBSFU? To test that decisively, erase your boot code's sector in STM32CubeProgrammer before debugging the app.
>And I have this MPU Config in my app for LwIP on SRAM2
Post the value your SBSFU configures the MPU_CTRL register.
See https://developer.arm.com/documentation/dui0646/c/cortex-m7-peripherals/optional-memory-protection-unit/updating-an-mpu-region or ST's PM0253. A region should be disabled before writing new settings if it has been previously configured.
Also note MPU registers are accessible in privileged mode only.
2021-08-30 01:46 AM
Hello! is the Ethernet workin after these changes?