cancel
Showing results for 
Search instead for 
Did you mean: 

Hard fault (usage fault, invalid state), using X-CUBE-NFC03 and FreeRTOS, with STM32L4. Seems dependent on code/data size. Any idea where I should investigate ?

Slan
Associate II

Hello,

I am trying to develop a FreeRTOS application which need to detect/read/write an NFC tag.

I managed to make the NFC part work (based on ST's example code), but after changing my task stack size, a usage fault occurs (FORCED, INVSTATE).

After a few attempt to reproduce and solve this, I noticed the following :

  • Task size of 1024 words : work as expected
  • Task size of 768 : hard fault / INVSTATE in NFC library (see below)
  • Task size of 2048 : hard fault / INVSTATE with PC out of any source file (0x20001fe8)
ReturnCode ndefT4TPollerSelectFile(ndefContext *ctx, const uint8_t *fileId)
{
    ReturnCode               ret;
    rfalIsoDepApduTxRxParam  isoDepAPDU;
 
    if( (ctx == NULL) || !ndefT4TisT4TDevice(&ctx->device) ) // HARD FAULT on this line
    {
        return ERR_PARAM;
    }
 
    ndefT4TInitializeIsoDepTxRxParam(ctx, &isoDepAPDU);
 
    if (ctx->subCtx.t4t.mv1Flag)
    {
        (void)rfalT4TPollerComposeSelectFileV1Mapping(isoDepAPDU.txBuf, fileId, (uint8_t)sizeof(fileId), &isoDepAPDU.txBufLen);
    }
    else
    {
        (void)rfalT4TPollerComposeSelectFile(isoDepAPDU.txBuf, fileId, NDEF_T4T_FID_SIZE, &isoDepAPDU.txBufLen);
    }
       
    ret = ndefT4TTransceiveTxRx(ctx, &isoDepAPDU);
 
    return ret;
}

Might be worth to add a few days back, I had unexpected behaviour on some variable. In the code below, the address linked by usrRec_ptr was set to the right adress on definition, but changed after the call to ndefMessageDecode function.

I moved the declaration on the line before the while, then it worked as expected.

After modification on other part of the program, I tried to put it back at function start, now it works...

void nfc_parseMessage(uint8_t* rawMsgBuf, uint32_t rawMsgLen, nfc_text_records_t *usrRec, bool *tag_empty){
    ReturnCode       err;
    ndefConstBuffer  bufRawMessage;
    ndefMessage      message;
    ndefRecord*      record;
 
    char* usrRec_ptr[3] = {usrRec->app_id, usrRec->user_name, usrRec->remaining_coffee};
 
    bufRawMessage.buffer = rawMsgBuf;
    bufRawMessage.length = rawMsgLen;
 
    err = ndefMessageDecode(&bufRawMessage, &message);
    if (err != ERR_NONE)
    {
        return;
    }
 
    record = ndefMessageGetFirstRecord(&message);
    uint8_t i=0;
    ndefType         type;
 
    while (record != NULL)
    {
    	ndefRecordToType(record, &type);
    	if(type.id == NDEF_TYPE_RTD_TEXT){
    		memcpy(usrRec_ptr[i], type.data.text.bufSentence.buffer, type.data.text.bufSentence.length);
    		usrRec_ptr[i++][type.data.text.bufSentence.length] = '\0';
    	}
        nfc_parseRecord(record);
        record = ndefMessageGetNextRecord(record);
    }
    if(i==0 && type.id==NDEF_TYPE_EMPTY){
    	*tag_empty = true;
    }
    else{
    	*tag_empty = false;
    }
}

Not sure if this is an NFC related issue, linker/compiler config issue (didn't change anything there except increasing heap and stack minimal size, but the default values don't work either). RAM usage is 35% with the largest task stack size

I doubt this issue is related to FreeRTOS, the code was generated by CubeIDE 1.3 (which take care of the interrupt/task priority to avoid conflicts). I have configASSERT defined, and I enabled stack overflow hook (mode 2) to check this (also, just to be sure I have checked the task stack in RAM which still has 0xA5 values at the end). I have just 2 tasks running, one for NFC, the other one for LED blink.

I tried to lower the FreeRTOS heap for stack sizes of 1024 and 768 words, the behaviour is the same (work with 1024, INVSTATE with 768, PC on the same line of code).

Any idea where I should look next ?

1 ACCEPTED SOLUTION

Accepted Solutions
Brian TIDAL
ST Employee

Hi

issue found: huge buffer allocated in the stack.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

6 REPLIES 6
Brian TIDAL
ST Employee

Hi,

can you provide to me (in private) the raw message buffer so I check the decoding of this NDEF? how many records do you have in this NDEF message?

if the corrupted address is always the same, can you try to set a write access hardware breakpoint and see which part of code is corrupting the data?

Regarding the stack size for tasks, if the tasks have been created by STM32CubeMX, the sizes are currently in bytes and not in dwords (i.e. 4 times less than expected). The static stack analyzer in STM32CubeIDE should help you to find the appropriate stack size for the various tasks. For example, ndefMessageDecode and its callees costs only 96 bytes of stack. The overall rfalNfcWorker costs 668 bytes.

if you have an hardfault on if( (ctx == NULL) || !ndefT4TisT4TDevice(&ctx->device) ), this means ctx does not point to a valid location i.e the ctx pointer is corrupted.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Slan
Associate II

Thanks for your reply, I sent you the file in private.

There should be 3 text records in this NDEF (but this is a read attempt, I'm not sure the tag has been read yet when the fault occurs.

Good to know for the stack, I never used the static stack analyzer and will give it a try (but I know 768 is a bit more than what I need, and 512 is too small as vApplicationStackOverflowHook is called).

Each time I read ctx value with breackpoint in there, it seem to point to a valid location, but I noticed the hardfault occurs later in that case ( breakpoint near if( (ctx == NULL) || !ndefT4TisT4TDevice(&ctx->device) ) ). In such cases, the overflow occurs on isoDepDataExchangePCD function, on the line gIsoDep.hdrLen = RFAL_ISODEP_PCB_LEN;

What does confuse me is the difference between a task size of 768, 1024 and 2048, even if I don't have stack overflow on those 3 sizes.

Slan
Associate II

I also noticed platformProtectWorker and platformUnprotectWorker macros in plateform.h, provided to "Protect RFAL Worker/Task/Process from concurrent execution on multi thread platforms". Even if I'm using an RTOS I didn't set those macros, but as I have a single NFC task this should not be an issue ?

Brian TIDAL
ST Employee

Hi

issue found: huge buffer allocated in the stack.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Slan
Associate II

Thanks again for your help Brian.

Just wanted to add, if someone has a similar issue, the buffer was the one used by ndef functions, and was declared as a local variable inside a function.

The library add a reference to this buffer to ndefContext. In my case, the local buffer was probably overwritten before being used again, with wrong data.

Regards.

bnesp.1
Associate

this is really helpful informative post. i must share this on my website. thanks for sharing this.