cancel
Showing results for 
Search instead for 
Did you mean: 

Hardfault randomly when I do sprintf

Nickjmas
Associate III

Hello everyone,

I'm developing a firmware for an STM32F767 and I have a problem that happens randomly and I can't figure out why. From what I could analyze looking at the stack I think the problem comes when doing a sprintf and I have the hypothesis that it could be an overflow problem.

According to the fault analyzer, when the error is caught I have this context:

Hard Fault Details: Bus, memory management or usage fault (FORCED)

Bus Fault Details: Precise data access violation (PRECISERR) BFAR: 0x30333531

Register Content During Fault Exception:

  • sp(PSP): 0x20013480
  • r0: 0x30333531
  • r1: 0x0
  • r2: 0x18
  • r3: 0x20040fe0
  • r12: 0x819bc400
  • lr: 0x813dc81
  • pc: 0x813f6fa
  • xpsr: 0x2100000

It is curious since the BFAR and r0 register contains part of the value to be formatted by sprintf (the number is 15300), which further strengthens the hypothesis that there may be an overflow problem somewhere.

MPU and cache is used with the next configuration:

/* Configure the MPU attributes for the frontbuffer to normal memory (800px x 600px * 16bpp) */
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress = 0xC0000000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_2MB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER1;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
	/* Configure the MPU attributes for the backbuffer to normal memory (800px x 600px * 16bpp) */
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress = 0xC0200000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_2MB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER1;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 
	/* Configure the MPU attributes as device for NOR (Strongly Ordered Memory) */
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress = 0x60000000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
	MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER3;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress = 0x60000000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER4;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
	HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress = 0x20000000;
	MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
	MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
	MPU_InitStruct.Number = MPU_REGION_NUMBER5;
	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
	HAL_MPU_ConfigRegion(&MPU_InitStruct);

I have tried increasing stacks, heaps and stacks of the task where the error occurs. But I am facing the same error.

I am currently using the standard c library which incorporates the latest version Atollic True Studio 9.3.0. Can you suggest what I can do or what I can check to see where the error is coming from?

Thank you in advance

Best regards

10 REPLIES 10
TDJ
Lead

I occasionally experience the same HardFault problem using printf() from two or more ISRs of unequal priority.
In such case, one ISR may interrupt another one in the middle of strig rendering (and e.g. memcpy) or sending. There is no way to prevent it from happening other than temporarily disabling other IRQs or using a separate buffer for each ISR and spawning another low-priority process for grabbing and sending strings from each such buffer, but that is not a simple fix you are probably looking for.