cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet Init fail with sbsfu bootloader

matteochen
Associate II

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!

11 REPLIES 11
alister
Lead

> 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.

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!

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.

The boot code disables the MPU only (as a ST employee has pointed out in an other thread) before jumping to the User App, the regions deactivation is done inside my user app before the assignment of the new custom regions (is this wrong?). I have left all the secure part as default so SE in privilege mode and SBSFU in unprivilege mode (exploiting SVC to call the SE).

Yes, the FW is well tested outside the bootlaoder and it runs smoothly.

If you need any further info just let me know.

Thank you.

If your boot code is privileged only in the ST and you are disabling the MPU protections outside of the SE, I do not see how your app could be executing at all.

If unprivileged software could disable the MPU, it could not provide any protection.

From ARM DUI 0646C: Attempting to access a privileged register from unprivileged software results in a BusFault.

If the app is really executing, perhaps bus faults are disabled or the bus fault priority is lower than the base priority somehow.

You should be able to debug the boot code to confirm it jumps to the app.

Maybe I am missing some information about the entire process (I am sure I am) but forgive me, I am quite new to this world.

I have followed this hint for adding my custom MPU regions; after disabling all the regions and then set up my custom regions the FW is being correctly booted by the boorloader; the presumed fault occurs at the ETH Init stage.

The regions disablingis "real" becasue without this stage, the bootloader can't boot the FW (so setting directly my MPU regions).

I am quite sure that I am not accessing to the "user protected area" at the start of the flash which would cause a bus fault (I have defined in the linker script where my FW must begin and so the vectiors) and I use a different RAM region compared to the one that the bootloader uses for its activities.

The only protection that I have disabled only for test purposes is the MPU and IWDG in the "app_sfu.h".

https://community.st.com/s/question/0D53W000011vQGr does not share enough code to know all the details.

>the presumed fault occurs at the ETH Init stage

Don't "presume". Debug your boot code, step into your app code, load your app's debug symbols and keep debugging, or (assuming gcc) code a breakpoint in your app's hard fault handler with asm("bkpt # 0"); and just let it run to fail and check registers there, e.g. SCB->CFSR, SCB->HFSR, SCB->BFAR. Turn on generate list file in your build (if they're not on already) and nail that line of source code that faulted.

>The regions disablingis "real" becasue without this stage, the bootloader can't boot the FW (so setting directly my MPU regions).

Much of the app could execute without a privilege violation if the SBSFU's protections were not cleared properly.

>I am not accessing to the "user protected area" at the start of the flash which would cause a bus fault

Not saying that. Refer table 4-48 in ARM DUI 0646C or table 84 in PM0253. The MPU registers can only be accessed by privileged software.

>The only protection that I have disabled only for test purposes is the MPU and IWDG in the "app_sfu.h".

Be sensible to disable all protections during debug.

Be sensible to use different secret keys during debug too.

>Maybe I am missing some information

Possibly something at https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet may help.

@alister​ thank you very much for your hints, I really appreciate your support! I'll investigate further.