2021-08-27 08:52 AM
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!
2021-09-22 08:36 AM
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
2021-09-24 12:43 AM
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!