Skip to main content
matteochen
Associate II
August 27, 2021
Question

Ethernet Init fail with sbsfu bootloader

  • August 27, 2021
  • 2 replies
  • 3793 views

Hello everyone!

I am testing my own firmware with the sbsfu bootloader (stm32h723). I have the problem that when the MCU is trying to set up the ethernet the board will die.

The ETH region is protected by MPU and before enabling it in my app I disable the sbsfu's 8 MPU regions.

Switching off the MPU protection in sbsfu I can see that the code stops when calling "HAL_GPIO_Init" from "HAL_ETH_MspInit".

Following my MPU set up:

void MPU_Config(void)
{
	MPU_Region_InitTypeDef MPU_InitStruct;
 
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER0;
	MPU_InitStruct.BaseAddress = 0x24020000; //netxduo packages
	MPU_InitStruct.Size = MPU_REGION_SIZE_64KB;
	MPU_InitStruct.SubRegionDisable = 0x0;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	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_CACHEABLE;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER1;
	MPU_InitStruct.BaseAddress = 0x24020000; //eth tx and rx
	MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
	MPU_InitStruct.SubRegionDisable = 0x0;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	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);
 
	/* Enables the MPU */
	HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

and main driver:

int main(void)
{
#ifdef RELOAD_IWDG
 IWDG1->KR = IWDG_KEY_RELOAD;
#endif
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
 
 /* MPU Configuration--------------------------------------------------------*/
 Deactivate_SBSFU_MPU_Regions();
 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();
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* Flash driver initialization*/
 FLASH_If_Init();
 
 BSP_LED_Init(LED1);
 BSP_LED_Init(LED3);
 
 MX_GPIO_Init();
 MX_USART3_UART_Init();
 
#ifdef RELOAD_IWDG
 IWDG1->KR = IWDG_KEY_RELOAD;
#endif
 
 /* Configure Communication module */
 COM_Init();
 
 /* Configure button */
 //BUTTON_INIT();
 
 FW_APP_Run();
 
 /* USER CODE END 3 */
}

Thank you!

This topic has been closed for replies.

2 replies

alister
Senior III
August 28, 2021

> when the MCU is trying to set up the ethernet the board will die.

What is it trying to do when it dies?

Same as I'd posted to https://community.st.com/s/question/0D53W00000hOpz5SAC, check https://developer.arm.com/documentation/dui0646/c/cortex-m7-peripherals/optional-memory-protection-unit/updating-an-mpu-region etc, main is executing in privileged mode, and any MPU regoins that are being reconfigured are disabled before writing new settings.

matteochen
Associate II
August 30, 2021

Hello!

Thank you for your response. As I have pointed out in the question, I can see that with the MPU protection disabled in the sbsfu the code stops when the function [HAL_GPIO_Init] from [HAL_ETH_MspInit] from [HAL_ETH_Init] is called.

For the MPU regions, I disable every MPU region that the bootloader sets up before setting my custom regions, is this whare are you referring to?

My MPU protection is applied to ETH descriptors and NetxDuo packages.

Thank you!

alister
Senior III
August 30, 2021

I am wondering

  1. How does your boot code disable MPU protection before jumping to the app. Does all your boot code execute as privileged, or are you calling the SE to disable it AND to jump to the app?
  2. Does your app execute fine if it is launched in the debugger without your boot code executing? To answer that decisively you may need to erase your boot code first as a debugger reset may execute it briefly.
Jocelyn RICARD
ST Employee
September 22, 2021

Hello @matteochen​ 

Did you find the issue you have ?

Regarding MPU configuration, SBSFU is setting up all regions for its own protection and then disables MPU just before jumping to application.

On thing SBSFU is not doing is deactivating the cache. In another post, one issue was related to this point as activating the cache in user application when the cache is already activated can lead to wrong behaviour.

Solution is in SBSFU SFU_MPU_SVC_Handler() in sfu_mpu_isolation.c

#if defined(SFU_MPU_PROTECT_ENABLE)
 SCB_InvalidateICache();
 SCB_DisableICache(); <= To be added
 SCB_CleanDCache();
 SCB_DisableDCache(); <== To be added
#endif /* SFU_MPU_PROTECT_ENABLE */

Besides, setting up MPU in your application, on point to address is the speculative accesses to flash areas mapped to external memories that can very seldom lead to MCU stuck.

You have a video explaining this here

Solution is to add a first region 0 that protects those memory areas from being accessed by speculative process.

Something like this

	HAL_MPU_Disable();
	/** Initializes and configures the Region and the memory to be protected
	*/
	// Set Default configuration
 
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER0;
	MPU_InitStruct.BaseAddress = 0;
	MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
	MPU_InitStruct.SubRegionDisable = 0x87;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
	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);

Last point, you may also face an issue related to re-enabling the MPU related to the FPU, that can appear depending on the compiler used.

FPU is already used in SBSFU but in non privileged mode.

It is possible to have an exception is a FPU register previously accessed in non privileged mode in now accessed in privileged mode.

Adding following code at beginning of your application should solve the issue:

 // Clear Floating point Unit flags
 {
	 register uint32_t fpscr_val = 0;
	 fpscr_val = __get_FPSCR();
	 fpscr_val &= (uint32_t)~0x8F; // Clear all exception flags
	 __set_FPSCR(fpscr_val);
 }

I hope this will help

Best regards

Jocelyn

matteochen
Associate II
September 24, 2021

Hello @Jocelyn RICARD​ , thank you very much for your response and the hints that you have given!

I have noticed that disabling the

#define SFU_WRP_PROTECT_ENABLE

protection in app_sfu.h has solved the issue that I had so I have cotinued with my development with other implementations in the meantime.

I will check these suggestions that you have given and will report to you.

Thank you very much!