ESP-IDF TWAI Queue implementation advice

wilsonng
Posts: 1
Joined: Thu Mar 30, 2023 4:14 pm

ESP-IDF TWAI Queue implementation advice

Postby wilsonng » Thu Mar 30, 2023 4:18 pm

Hello fellow programmers,

I'm wondering what would be the best approach in getting "CAN/TWAI" messages fast. This is buffer handling, overflow, receiving messages without any losses.

I was thinking of running a high priority RX TWAI (xTaskCreatePinnedToCore) that would be polling forever for messages to come in that calls "twai_receive(&rx_msg, 0)" which would then "xQueueSend" to another task that would be instructed to parse the message and do what ever means it needs.

Is this ideal? Is this a good way to handle high fast CAN messages? Or is there a better approach.

Any help or suggestions would be great!

For buffer management a ring buffer could also be added in the "Parser Queue" task.

Ravenholem
Posts: 20
Joined: Wed Nov 10, 2021 7:13 pm

Re: ESP-IDF TWAI Queue implementation advice

Postby Ravenholem » Wed Oct 11, 2023 2:02 pm

Hello,
Have you gotten any further with these questions or concepts?
I am also in your same shoes. I am trying to find the best way to implement TWAI for RX.

I'm pretty confident that the way I'm doing it isn't the cleanest way to handle twai RX but it was what I originally follow from a example.
When I hook onto a 500k bus that is about 85% to 90% saturated things start acting a little weird.
I think it's caused by my RX Task always being switched to when a new CAN message shows.

I am currently doing as follows
This Task is also set to the highest priority task and is free running no vtaskdelay. As it is held by twai_receive();

Code: Select all

void CAN_RX_Task(void *arg)
{
    // Forever LOOP
    while (1)
    {
        // Create Message Struct
        twai_message_t RX_message;

        if (twai_receive(&RX_message, portMAX_DELAY) == ESP_OK)
        {
 
            switch (RX_message.identifier)
            {
                case CAN_ID_0:
                case CAN_ID_1:
                case CAN_ID_2:
                case CAN_ID_3:
                    // Send to RX Que to be read by main task
                    if (xQueueSend(CAN_RX_task_queue, &RX_message, 0) == pdTRUE)
                    {
                        // Message went into que!        
                    }
                    else
                    {
                        // Queue was full!                        
                    }                
   
                break;

                default:
                break;
            }
            
        }
        else
        {
            // twai_receive did not return ESP_OK
        }

    } // End Forever Loop

    vTaskDelete(NULL);
}

DrMickeyLauer
Posts: 168
Joined: Sun May 22, 2022 2:42 pm

Re: ESP-IDF TWAI Queue implementation advice

Postby DrMickeyLauer » Mon Oct 16, 2023 2:10 pm

I'm also using TWAI on the ESP32 family. While I have a pretty solid receiving architecture (Hints: Put TWAI service routine in IRAM, launch a high priority receiving task that only calls twai_receive and puts it into a queue of your liking), I'm struggling with solid transmission timing. See https://github.com/espressif/esp-idf/issues/12316 – I'm afraid the CAN controller has a first-level buffer of a handful of bytes and whenever this runs empty, it takes a non-deterministic number of microseconds to fill it up again.

I'd love to hear any success stories with regards to reliable send timing.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 141 guests