Reception buffer corrupted in UART IO with STM32 + FreeRTOS

thyanger wrote on Wednesday, June 08, 2016:

Hi everybody.

In my application there is an STM32 micro communicating with a 3G module. Firstly I just want to send an AT command to check whether the module is on or not. So I do

HAL_UART_Transmit(&UART_MOBILE_Handle, (uint8_t *)&"AT\r", sizeof("AT\r"), TOUT);
HAL_UART_Receive(&UART_MOBILE_Handle, (uint8_t *)rxBuffer, SIZEOFRXBUFFER, TOUT);

Unfortunately, at the end of the process I only get corrupted data within rxBuffer. That is, there is a fragmented version of what it is supposed to be the standard module answer to AT: something like \r\n\nAT\r instead of \r\n\r\nAT\r\nOK\r\n. The same code works fine without FreeRTOS.

Any advice?

Thank you and regards.

rtel wrote on Wednesday, June 08, 2016:

Is this a FreeRTOS question? Does it work when you don’t use FreeRTOS?

The HAL_UART_Transmit()/Receive() functions are not functions we
provide, but I would suggest checking the prototype of the functions as
from what you have posted the usage looks suspicious - especially where
taking the address of a pointer when passing in the string.

thyanger wrote on Thursday, June 09, 2016:

Yes it does work fine without FreeRTOS. Sorry there was a typo in the code: I did not directly copied from the IDE, now it is the corrected version.

rtel wrote on Thursday, June 09, 2016:

Is the UART using interrupts or is it polling? If it is using
interrupts, does the interrupt service routine make use of the FreeRTOS API?

thyanger wrote on Thursday, June 09, 2016:

Polling! Could it be a task switch problem?

rtel wrote on Thursday, June 09, 2016:

I doubt it. If it is polling then I can’t see why it would make any
difference if you were using FreeRTOS or not - unless there was another
task attempting to access the port at the same time.

thyanger wrote on Thursday, June 09, 2016:

Any suggestion? Possible configuration issues?

thyanger wrote on Thursday, June 09, 2016:

Hmmm, no that task is the unique using that peripheral…

hs2sf wrote on Sunday, June 12, 2016:

Maybe just a simple stack overflow ? Stack incl. thread-safe memory management in general is one of the main differences running code w/ or w/o FreeRTOS runtime environment.

rtel wrote on Sunday, June 12, 2016:

Do you have stack overflow checking switched on, and configASSERT()
defined? Links to information on both on the following page:
http://www.freertos.org/FAQHelp.html

thyanger wrote on Monday, June 13, 2016:

Hmmm, ok thanks for the hint, I will check.

thyanger wrote on Monday, June 13, 2016:

No, I don’t. I will put them on and start debugging, thank you for pointing this out.

thyanger wrote on Tuesday, June 14, 2016:

Just a question, what would happen in case of stack overflow (I am not an expert so do not hesitate to tell me “obvious” things)? I have the checking switched on and I have defined the corresponding hook, but nothing happens, the program runs without ending in the hook and the reception is corrupted. I tried both with configCHECK_FOR_STACK_OVERFLOW = 1 and 2.

thyanger wrote on Thursday, June 16, 2016:

So far my solution is using interrupts and it is working. I hope this helps anybody else who is getting into the same issue.

hs2sf wrote on Saturday, June 18, 2016:

Everything weird can happen on stack overflow (also depending on processor architecture). Often local variables are corrupted (even worse corrupted local pointer variables might cause hard to debug data coruption somewhere else), return addresses might get wrong causing a function to return to somewhere else etc.
Stack overflow checks as thankfully provided by FreeRTOS are a big help but can’t cover/detect all overflows b/c a check-function needs to be called. Enabling stack checks activate some trigger points in the OS usually on context/task switch to check the stack of the current task before switching to the next ready task or similar.
Hence stack overflows occuring while executing a task (function) are not detected.
One might ‘manually’ add further stack-checks inside a task function or use a debugger watching the stack-pointer (processor register - refer to the actual ABI of your processor) while stepping through suspicous code.
Note that there are some C-lib functions known to use a lot of stack (e.g. printf-family).
Sometimes the fastest way to find out if the reason of a bug could be stack-overflow, is to drastically increase the stack of the task for testing purposes and check if it’s working then or still buggy/crashing.

Good luck !

thyanger wrote on Monday, June 20, 2016:

Thanks for the suggestion. What do you mean for “drastically increase”?. I increased the task stack by a factor of 8 the base dimension (#define configMINIMAL_STACK_SIZE ((uint16_t)128)) but nothing changed. However I will investigate in light of what you pointed out.

Regards!

hs2sf wrote on Tuesday, June 21, 2016:

A factor of 8 is usually more than enough. I’ve to admit that my wording wasn’t so good.
I tried to say do not add just 16 bytes but 50-100% :slight_smile:
In your case where the ported code didn’t work yet it’s hard to estimate the right starting value.
It clearly depends of your code. Just for example I’m using 512 - 1024 byte in my current application and the tasks do more than just LED blinking. On the other hand the default min. size of 128 byte was not sufficient pretty early.
Hope it helps !

thyanger wrote on Wednesday, June 22, 2016:

Ok, I will try (so far I got stuck with another stupid problem that made me going crazy). I just want to add some extra elements I have hidden before thinking they were not important: to be more precise there are two tasks, say task A and task B. Task A is the main task in charge to do some things at, let’s say, application level, while task B is in charge to bring the module to the ready state (insert pin, open network and so on). So, task A starts and before entering the infinite loop it hard reset the module and waits for the start message. At this stage the reception buffer is never corrupted (I mean since the time I am trying to use polling). Then, based on what happende after the hard reset and the corresponding start message reception, task A, in case of success, starts task B and goes in the idle state (task A implements a state machine) waiting for task B to do its job. Now, task B firstly try to insert the SIM pin. Here, the 3G module feedback consisting in an ack string, has to be received and in this case it is corrupted. When performing this actions with low level send receive interrupts HALS this works like a charm (and the story goes on because then I am able to make the module ready for connection and then I can connect to a server and perform some IO flawlessly…).

I will post news if any, thank you for the support!

thyanger wrote on Thursday, June 23, 2016:

No good news, I “dramatically” increased the minimum stack size by a factor of 16 and nothing happened. On PIN insertion with polling I get

AIN=5119\r\r\nO\r\n+CPIN: REUPDATING\r\n\r\nG\r\n\rNE\r\n\r\nCALL  DONE\r\n

while with interrupts I get

AT+CPIN=5119\r\r\nOK\r\n\r\n+CPIN: READY\r\n\r\nOPL UPDATING\r\n\r\nPNN UPDATING\r\n\r\nSMS DONE\r\n\r\nCALL READY\r\n\r\nPB DONE\r\n

which is what it is supposed to be received. :\