cancel
Showing results for 
Search instead for 
Did you mean: 

why am I getting a hardfault when running the MPU_Config exactly as it appears in the example code?

GreenGuy
Lead

Evaluation Board STM32H743i-EVAL

Example from STM32H735G-DK - NetXDuo - Nx_WebServer

AZRTOS-H7 V 2.1.0

I am trying to build a Nx Webserver like the one referenced for the H743i. I have begun with trying to set up the memory as it is configured in the 735G example since the memory layout between the two processors is the same. I have not ported any other code yet. I set-up the CubeMX parameters for the same as the 735G .ioc. I have compared the code generated with the main.c code in the example and it is a match. It looks like this:

void MPU_Config(void)
{
  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 = 0x0;
  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);
 
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x24030000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  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;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Number = MPU_REGION_NUMBER2;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
  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.Number = MPU_REGION_NUMBER3;
  MPU_InitStruct.BaseAddress = 0x24030100;
  MPU_InitStruct.Size = MPU_REGION_SIZE_8KB;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_HARDFAULT_NMI);
 
}

when line 56 executes, the MPU ends up in the Hard fault handler.

Has this ever worked or been tested?

1 ACCEPTED SOLUTION

Accepted Solutions
GreenGuy
Lead

Fixed it.

Using HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); at the end of the MPU_Config is very cool.

When a memory issue occurs it puts you into the MemManage_Handler() instead of HardFault_Handler(void). And in the process the debugger has the stack preserved so you can see exactly what was going on before the fault. It turns out the LCD utilities were being used to draw the header and footer to the screen. Going through examples of code used for drawing images to the screen I could see that SDRAM was being configured in the MPU_Config. So I added the SDRAM as a region just like the examples and voila.

I have no idea why this worked. I cannot see anywhere in the code the reference to 0xD0000000 or any part of that region.

View solution in original post

2 REPLIES 2
GreenGuy
Lead

Seems I missed the last statement difference between the example project and mine. In the example, the argument in the HAL_MPU_Enable should be MPU_PRIVILEGED_DEFAULT. Using this does not crash to the hardware fault when executing line 56. However, the program hangs on the invocation of SCB_EnableDCache();. If I comment out the cache enables my program doesn't crash to the hardware fault but eventually ends up in the MemManage_Handler and the stack is preserved. If I comment out the MPU_Config() and use D and I Cache everything runs without fault.

Also don't like the idea that I had to figure out how CubeMX creates the MPU_PRIVILEGED_DEFAULT argument by trying each of the 4 choices for MPU Control Mode until the desired argument appeared in the code. It is not obvious that "Background Region Privileged accesses only + MPU Disable during hard fault, NMI and FAULTMASK handlers" = MPU_PRIVILEGED_DEFAULT. Could ST have made it more difficult?

Anyway the MPU control still does not work.

GreenGuy
Lead

Fixed it.

Using HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); at the end of the MPU_Config is very cool.

When a memory issue occurs it puts you into the MemManage_Handler() instead of HardFault_Handler(void). And in the process the debugger has the stack preserved so you can see exactly what was going on before the fault. It turns out the LCD utilities were being used to draw the header and footer to the screen. Going through examples of code used for drawing images to the screen I could see that SDRAM was being configured in the MPU_Config. So I added the SDRAM as a region just like the examples and voila.

I have no idea why this worked. I cannot see anywhere in the code the reference to 0xD0000000 or any part of that region.