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
o239955_st
Associate II
Posted on October 16, 2014 at 11:37

Another strange think today.

SP seems to be mismanaged:

here the function:

uint8_t rdr_getRawPage(uint8_t *data,uint16_t index,uint32_t timeOut){

 

 

    uint8_t request[]={REQ_SOF,0x04,GET_RAWP_CMD,0x00,0x00};

 

    uint16_t count=3;

 

    uint8_t ans[6];

 

    uint16_t i;

 

    uint32_t waitTime;

 

 

    flushBuffer(&rxRdrBufferStruct);

 

 

    request[3] = (uint8_t)(index>>8);

 

    request[4] = (uint8_t)(index & 0x00FF);

 

    rdr_sendPacket((uint8_t*)request,sizeof(request));

.....

Data address is 0x2001FD70. Juste before calling the function SP is 0x2001FD90 !!!

After entering the function the poinet passed by data is always 0x2001FD70 OK, SP is 0x2001FD60 and local variable ans is at 0x2001FD70 !!!! 

Is it really normal???

stm322399
Senior
Posted on October 16, 2014 at 11:53

Beside data that looks to wrongly seat on the stack, others addresses looks correct. Focus on data. Show us any line dealing with this variable in its context.

o239955_st
Associate II
Posted on October 16, 2014 at 14:43

First of all, thanks Mr Laurent for your help.

Here after you could find pieces of code ''playing'' with pointer. I must notify you that popData function are working for months only get_rawData is new.

Another thing is everytime i start this code, without modify the code, the address of buffer is changing, sometime lower than SP address sometime higher. It is not normal if the code doesn't change. (No compilation between) Mayby Attolic work wrong

PS my debug prob is a SEGGER J-Link ultra+ and the core clock is at 100MHz 

Thanks in advance

main(){

    uint32_t waitComTime = 0;

    char rdrSNB[8];

    uint8_t buffer[600];

/*    static RTC_TimeTypeDef RTCTime;

    static RTC_DateTypeDef RTCDate;

    comRadarMode = COM_GPRS_MODE;*/

    initBoard();

    setPwrLed(ENABLE);

    setComLed(DISABLE);

    setStatusLed(DISABLE);

    initParam();

    initUsrDriver();

    

    ......

    rdr_getRawPage(buffer,0,1000);  // generally crash here

    

    ......

   }

uint8_t rdr_getRawPage(uint8_t *data,uint16_t index,uint32_t timeOut){

    uint8_t request[]={REQ_SOF,0x04,GET_RAWP_CMD,0x00,0x00};

    uint16_t count=3;

    uint8_t ans[6];

    uint16_t i;

    uint32_t waitTime;

    

    .... some stuffs....

    

    waitTime = sysTickMs;

    while(rdr_getRxBufferSize()<(PAGE_SIZE_16MB+6))

        if((sysTickMs-waitTime)>timeOut) {

            lastRdrError=RDR_PGTO_ERROR;

            return 0;

        }

    for(i=0;i<PAGE_SIZE_16MB;i++){

        popData(&rxRdrBufferStruct,data);    //generally crash here

        data++;

    }

    if(!rdr_getPacket(ans,&count,1000)) {

        return 0;

    }

return 1;

uint16_t popData(ringBuffer* buffer, uint8_t *data){

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

    buffer->tail++;

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

        buffer->tail = buffer->start;

    }

    buffer->count = getCount(buffer);

    return buffer->count;

}

Initialisation of  rxRdRBufferStruct:

rxRdrBufferStruct.bufferHandle = rxRdrBuffer;

    rxRdrBufferStruct.start = rxRdrBuffer;

    rxRdrBufferStruct.end = rxRdrBuffer + RX_RDR_BUFFER_SIZE;

    rxRdrBufferStruct.heap = rxRdrBufferStruct.start;

    rxRdrBufferStruct.tail = rxRdrBufferStruct.start;

Declaration of ringBuffer (type of rxRDRBufferStruct)

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;

stm322399
Senior
Posted on October 16, 2014 at 15:01

Can't tell what's wrong with observed value of data until I know how you observe the value.

On the other side, the following is very interesting:

for(i=0;i<PAGE_SIZE_16MB;i++){
popData(&rxRdrBufferStruct,data); //generally crash here
data++;
}

I hope

PAGE_SIZE_16MB

is not 0x01000000 ! Like we says in french ''j'en tombe le c.. par terre''.
o239955_st
Associate II
Posted on October 16, 2014 at 15:56

eh No this define has probably a bad name, It for different king of SPI memory used on a board. This defined is equal to 528.

Last time I check the value of data during the for loop, data was increasing by one (ok it point to a byte) and crash arrive when it ''hint'' the SP bouh.

Everytime i made a step debug, and the crash appear, it was due to a SP address upper than the last variable create onto the stack.

I'm checking this function at an other place in my code (in a function called by a function called.....) up to now, it is ok. Strange

Are you a french native person?

stm322399
Senior
Posted on October 16, 2014 at 16:21

ouf !

It time to enter dirty debug:

* place *(volatile unsigned char*)=0; very early in main, and put a breakpoint with the debugger on it.

* When it breaks, observe SP and buffer

* place *(volatile unsigned char*)=0; before the call to rdr_getRawPage, put a breakpoint.

* When it breaks, observe SP and buffer

I'am French. You outed me !

o239955_st
Associate II
Posted on October 20, 2014 at 09:51

Hello,

I tried this but *(volatile unsigned char*)=0; make compil error (''expected expressions before '=' token'')

Thanks

Olivier

stm322399
Senior
Posted on October 20, 2014 at 09:59

Of course, it is wrong !! I missed the name of the variable !

The idea is to know buffer address, so: *(volatile unsigned char*)buffer=0; this instruction make sure that the debugger will have a visibility to buffer address.

o239955_st
Associate II
Posted on October 22, 2014 at 09:04

Hello,

Sorry I'm working on other project for a few days. I will test it on Monday 27 and give you the result.

Thanks