Can XQueueSendFromISR interrupt Task implement XQueueReceive

Hello,

I am supposed to Receive can massages through interrupt and then send the msg to other task using queue :

xCanRxQueue = xQueueCreate(50, sizeof(can_frame_struct));

xQueueSendFromISR(xCanRxQueue, (void *)&can_rx_frame, (TickType_t)0);

But I do not want to trigger the task contains xQueueReceive () immediately(Event based task), but instead i want to make a periodic task that check the queue every specific period of time :

So for example if I made something like that:

task_10ms()
{
    TickType_t xLastWakeTime;
    const TickType_t xPeriod = pdMS_TO_TICKS(_10_MS_);
    xLastWakeTime = xTaskGetTickCount();

    for (;;)
    {
         while ( xQueueReceive(xCanRxQueue,  &can_frame, 0) != errQUEUE_EMPTY)
         {
                 // Read data that can_frame points to 
          }
        vTaskDelayUntil(&xLastWakeTime, xPeriod);
    }
}

My question is that CAN interrupt could come in very short time (ex: 1ms), So in that case does the queue will keeping updated while task10_ms executed ? OR Kernel suspend interrupts until task finished ?

And if queue could be updated while i am reading it, Do i need to set this task in critical section till i finish reading ?

The Queue logic will handle the needed Critical Section in the access of the data in the queue, so you don’t need to. As long as the task can process the messages fast enough to keep the queue from filling, you should be ok.

Thank you for your response.
From what you say, the queue will handle the critical section but then processing queue by the task (code inside the while loop) can be interrupted normally. So If I want to secure the task as much as possible , is it a good idea to create critical section while processing ? Or is there other better solutions ?

What do you mean or what do you want to achieve be secure the task ?
Note that critical sections are intended to protect very short pieces of (non-blocking) code because they’re implemented by disabling all FreeRTOS covered interrupts.

What is in the task that needs protecting? Presumably, the whole CAN message was sent so there isn’t anything that the ISR firing will hurt.

If you are just passing pointers to the messages, then the ISR needs to leave them alone until it has been told the task is done with them.

My point is that i want to execute while loop in specific time. So if for example when while loop started to serve queue, there were 10 messages in the queue. Then I want to insure that i will only serve these 10 messages only and not get interrupt in between that will increase the queue with new message. I am not sure if that scenario could happen or not, That is why I am asking about that.

Would the following work for you?

for (;;)
{
    UBaseType_t uxCount = uxQueueMessagesWaiting( xCanRxQueue );
    while ( ( uxCount > 0U ) &&
            ( xQueueReceive( xCanRxQueue, &can_frame, 0 ) != errQUEUE_EMPTY ) )
    {
        // Read data that can_frame points to 
        uxCount--;
    }
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
}

Stopping new interrupts from firing would be complicated: you would need a long critical section, and you might miss important other interrupts.

After I applied PR #545, the test with the reuseable socket went well.
PR #545 is still in revision :frowning:

Thank you for this feedback. That is actually what I was hoping to get from my question. I think this solution will work with me.