2014-10-15 01:14 AM
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. Oli2014-10-16 02:37 AM
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???
2014-10-16 02:53 AM
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.
2014-10-16 05:43 AM
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;2014-10-16 06:01 AM
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''.
2014-10-16 06:56 AM
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?2014-10-16 07:21 AM
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 !2014-10-20 12:51 AM
Hello,
I tried this but *(volatile unsigned char*)=0; make compil error (''expected expressions before '=' token'') Thanks Olivier2014-10-20 12:59 AM
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.2014-10-22 12:04 AM
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