Hello all,
I am new at FreeRTOS
Want to ask some advice about this situation:
I am building a small application to scan QR codes. This consist of 4 simple tasks, each of which blink a LED at a different frequency, and actually are accessory tasks to test the scheduling is being done right.
The main function is waiting to receive data coming from the scanner to save it before sending it to the terminal using a custom echo function.
This receiving function is not actually running in a freeRTOS task, because it runs in the background based on DMA to send and receive the data. When data arrives, it is received and sent by DMA, no CPU resources are used here. No FreeRTOS scheduling either for this activity.
Sending data is direct, for receiving I use a callback function.
Now, the custom echo function, uses a function that sends data to terminal, which is as mentioned based on DMA. Below is the function I use to send the data:
static void dataSend(char* msg){
uint8_t newSize = strlen(msg);
memset(txDma, 0, BUFFERSIZE);
memcpy(txDma, msg, newSize);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_4, newSize);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_4);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);
LL_mDelay(10);
}
The ISR for transmission is here:
void DMA1_Channel4_5_6_7_IRQHandler(void)
{
if(LL_DMA_IsActiveFlag_TC4(DMA1))
{
LL_DMA_ClearFlag_TC4(DMA1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_4);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_4);
}
}
Here is the echo function using dataSend:
void echo(char* fmt, ...){
static char echoString[BUFFERSIZE];
static SemaphoreHandle_t echoMutex = NULL;
va_list a;
if(NULL == echoMutex)
echoMutex = xSemaphoreCreateMutex();
if(NULL == echoMutex)
return;
xSemaphoreTake( echoMutex, portMAX_DELAY );
va_start(a, fmt);
vsnprintf(echoString, BUFFERSIZE, fmt, a);
va_end(a);
dataSend((char *)echoString);
xSemaphoreGive( echoMutex );
}
Here is the ISR for reception:
if(LL_USART_IsEnabledIT_RTO(USART2) && LL_USART_IsActiveFlag_RTO(USART2)){
LL_USART_ClearFlag_RTO(USART2);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_5);
rxCount = rxSize - LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_5);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_5, rxSize);
USART2_RTOCallback();
}
and here the callback function USART2_RTOCallback():
void USART2_RTOCallback(void){
memset(rxData, 0, BUFFERSIZE);
memcpy(rxData, rxDma, rxCount);
rxData[rxCount] = '\0';
echo("%s\r\n", rxData);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_5);
}
I have tested this echo function either without using a mutex and without using FreeRTOS at all and it works fine. However, when include all FreeRTOS mutex related lines of code, it prints only the first time and the next echo calls does not print anything. I cannot figure out where the problems might be. Should I create the mutex as a global or inside the echo function is Ok ?
Another question is, considering it works apparently normal without a mutex. Is it right to use it in that way or it might cause problems when scaling the code to more functionality or adding more tasks ?
Another problem is: I use LL_mDelay() inside the dataSend function because when I use vtaskDelay(…) function it also stops receiving data
Please give me some advices about how to go with this
Thank you in advance