cancel
Showing results for 
Search instead for 
Did you mean: 

Hard fault error and static variable

o239955_st
Associate II
Posted on October 15, 2014 at 10:14

Hello all,

Following some hardfault error with my code running into a STM32F415, I found a solution that leave me puzzled.

In my main, I declare a array of 600 uint8_t called data;

uint8_t data[600];

I call a function that need a pointer to an uint8_t, this function will fill the array with some datas. So I call this function like this:

foo(data,...);

As the name of an array is a pointer to that array, OK;

The function is filling the array pointed by data, and sometime a hardfault is rise with IMPRECISERR from CSR register set to 1.

I read some information on the web about this error could be solved by declaring each array with STATIC. Why ?

Normally, the cover of a variable is the all function, so when a function call another function, my data variable should be accessible to the called function (in this case a pointer). If I declare it STATIC, this variable will stay on the stack for live not only for the running function scope, so I will use more RAM than needed.

Thanks for you help.

Oli

18 REPLIES 18
Posted on October 15, 2014 at 10:26

> In my main, I declare a array of 600 uint8_t called data;

> uint8_t data[600];

As a local variable? Where is your stack located? Don't you use some RTOS?

> The function is filling the array pointed by data,

How?

> I read some information on the web about this error could be solved by declaring each array with STATIC.

Where?

JW

stm322399
Senior
Posted on October 15, 2014 at 10:34

Static variables are not allocated on the stack, but in the data segment. On most project, code run in flash, data is at the bottom of the SRAM and stack at the top of the SRAM.

In the case the foo function does something bad with the buffer (like overrrun), when the variable is on the stack you will crash very important data like function return address and saved value of registers (that should be preserved across function call). When the variable is static, an overrun will erase other variables, or nothing (depends on the data segment allocation).

As soon as a pointer is corrupted, there are chance that a memory access with a forbidden address occurs very soon, hence the imprecise abort.

It is likely that data buffer is badly used. Note that the scope of a variable allocated inside a function (stack variable) covers the whole function including subfunctions calls, but make sure that the pointer is not saved somewhere to be used later outside of the scope of its definition.

o239955_st
Associate II
Posted on October 15, 2014 at 13:02

Thanks for your help,

I don't use RTOS and the Stack begin at the end of the RAM (0x20020000), The data segment begin at the bottom of the RAM and DATA SEGMENT fill 7ko.

where the code:

Into main.c

uint8_t data[600];

getPage(data,0,1000);

Into page.c:

getPage(uint8_t *data,uint16_t index,uint32_t TimeOut){

uint16_t i=534;

....

....

while(i){     // extract data from buffer and place it to (*data)

   popData(BufferIn,data);

   data++;

   i--;

}

...

...

Into Buffer.c

popData(ringBuffer *buffer,uint8_t *data){

   (*data) = *(buffer->tail);

   buffer->tail++;

   if(buffer->tail == buffer->End) {

     buffer->tail = buffer->start;

}

...

Here the buffer struct:

typedef struct {

    volatile uint32_t  count;

    volatile uint8_t *start;

    volatile uint8_t *end;

    volatile uint8_t *heap;

    volatile uint8_t *tail;

    uint8_t *bufferHandle;

} ringBuffer;

All buffer are uint8_t[1024] .

Thanks for your answers.

Oli

stm322399
Senior
Posted on October 15, 2014 at 14:05

what if i changes its value between initialization and use ?

Replace while(i) { ... i--;} with for(i=534;i;i--)

o239955_st
Associate II
Posted on October 15, 2014 at 14:27

I will try,

But this hardfault error doesn't appear every time, may be 1 time per 10 run.

Sometimes this error happen in other function following the one I mentioned in post.

Now I've an Hardfault error when calling another function (just when executing first asm instruction ''push {r7, lr}''.Very strange.

stm322399
Senior
Posted on October 15, 2014 at 14:37

When the push instruction hard faults, check MSP/PSP values.

o239955_st
Associate II
Posted on October 15, 2014 at 15:17

I've tried fro loop instead of while but nothing change.

I've did some other test and I've got some strange thinks.

First test:

Just before call the getPage function the buffer adress in 0x2001FD28 and the SP is at 0x2001FD70 so in the buffer aera ???

Second test:

Second run: buffer array is placed at 0x2001FDD7 so with the top SRAM at 0x20020000, buffer cannot have 600 byte.

For each run, SP get same adresses but not buffer (base address change).

My tool is the last Attolic TrueStudio pro version

Like we says in french ''j'en perds mon latin''.

Thanks for your help

stm322399
Senior
Posted on October 15, 2014 at 15:50

The good news is that we get closer to the problem.

Try to reduce your code to the minimum (still being able to look at SP and address of data), and eventually show us the code.

o239955_st
Associate II
Posted on October 15, 2014 at 17:24

Last try for today. I placed a little piece of code to catch and other info into the HadrFault handler (describe in this site: http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/).

And here result.

[Hard fault handler - all numbers in hex]

R0 = 0

R1 = 20AC

R2 = 0

R3 = 412

R12 = 0

LR [R14] = 800E3E5  subroutine call return address

PC [R15] = 8011A64  program counter

PSR = 41000000

BFAR = E000ED38

CFSR = 20400

HFSR = 40000000

DFSR = 1

AFSR = 0

SCB_SHCSR = 0

Too much headache for today :-), Good evening

Thanks

Olivier