09212024

Last update2016/05/28 14:38

Back 現在地: Home パートナー SCIOPTA パートナー Atollic 5.浮動小数をsprintfでフォーマットしようとしたときにHardFault_Handler() がコールされる

5.浮動小数をsprintfでフォーマットしようとしたときにHardFault_Handler() がコールされる

 

5.浮動小数をsprintfでフォーマットしようとしたときにHardFault_Handler() がコールされる

HardFault_Handler() は以下のように浮動少数をフォーマットしようとすると起こります

 

sprintf(my_string,"%2.2f",(float)12.33);

sprintf と %f の実行はヒープの使用が必要です。

hard faultする理由はそのヒープ領域にあり、ヒープ領域がIDファイルを書くときに割り当てられないことが原因です。 

 

>> 

The most likely cause of the error handler-call if due to lack of memory when using floats. Try reducing the page-size.

The page-size-setting can be found if you right-click on your project, then select 'Properties'.
Expand the 'C/C++ Build' - entry in the left column and select 'Settings'. 
Select the 'Tool Setting'-tab and then look under 'C Linker' for 'Optimization'. 
If you select that, you will see a drop down list for different page-sizes.

Select 'Small' and then Apply.

 

The other solutions are related to where how heap and stack are located in the memories.

In your linker script, 'end' gets set to _ebss which is located in the external ram.

Now, the problem comes down to the logic that implements the _sbrk() which is the memory pool allocator. It follows the very simple logic of:

Is the new heap pointer located below the stack pointer ? Then return memory : otherwise return out of memory.

Since the stack in your script is in the internal ram and the heap wants to be located in the external ram on a higher address, the _sbrk won't ever give out memory.

So you have at least three choices here,

1. Make sure the heap is located in the internal ram below the stack

2. Place the stack in the external ram as well

3. Re-implement the _sbrk() memory allocation logic. (you can look at the current _sbrk() implementation by right-clicking on your project, select new -> Other, then expand "System Calls" and generate the Minimal system calls file somewhere into your project)

 

The simplest way is to go for number 1.

Remove the PROVIDE(end = _ebss) from your linker scripts bss section.

And then you can place a new statement directly after the _estack = 0x2001000;, specifying for example:

end = 0x20000000; /* Place the heap at start of internal RAM */

 

Since the heap grows upwards, you don't want to place valuable data directly after the 'end' symbol as it might get overwritten.