I programmed a CAN Bus logger for the ESP32 with ESP-IDF.

Currently this is just one main program with one loop. In that loop data is read from the CAN-Bus receiver and written to one log file on a SD-Card.

Now I also want to receive data from the UART serial port. And that data should also be written to the same log file on the same SD-Card.

My question is: Should I just add a few lines in the existing loop to read the data from the UART and write it to the log file on the SD-Card? Or would it be better to separate the code in two or more tasks for reading the data from the CAN-Bus, reading the data from the UART, and writing it to the log file on the SD-Card?

I am not sure about the baud rate until now. But the data from the UART will be a lot less than from the CAN-Bus. So there will be maybe 10 or 100 log file lines from the CAN-Bus and then 1 line from the UART.

This question is about the principle if I should use FreeRTOS with multiple task to implement this or just one loop. Until now I think one loop is easier and better because then I control exactly what is happening in which order. And this is not complex, only a few lines. But obviously I ask here to get expert advice if my thinking about this makes sense.


You can do the logging all from a single main-loop, but adding in the logging of the UART will definitely be more than a few simple lines. When everything is in a single main-loop, you have to manually take care that

  • No messages from the high-speed protocol get lost (for example, due to a blocking read on the low-speed protocol)
  • The partial messages returned from the non-blocking reads are properly reassembled
  • Message boundaries (e.g. newlines in the stream from the UART) are correctly detected and handled

None of this is impossible, but it is more than "a few lines in the existing loop".

On the other hand, if you use a multi-threaded OS, like FreeRTOS, you can create a separate task for each protocol and for the writing to the SD card. If you make the communication to the writing task atomic (all information for a log line is delivered all at once), then the other tasks can focus exclusively on the trickeries of logging that particular protocol. And although it is now a bit more work, adding a third protocol would again be "just a few lines".

  • Thanks for your fast and detailed answer. I am not sure but in this case I think it is really only two lines of code to read the UART because the code reads the buffer. From the API reference: "Incoming serial stream is processed by FSM and moved to the Rx FIFO buffer. Therefore the task of API’s communication functions is limited to writing and reading the data to / from the respective buffer." (docs.espressif.com/projects/esp-idf/en/latest/api-reference/…) And I understand that your answer is more general and not specific for this processor and framework.
    – Edgar
    Dec 9 '19 at 12:21
  • @Edgar, can you guarantee that every time you check the Rx buffer, there is a full UART message in there and not a partial one or more than one? If that is the case, then the UART API already effectively implements the task I described. Dec 9 '19 at 12:27
  • Thanks, I will test it and find out. And then I can report it here - in a few days.
    – Edgar
    Dec 9 '19 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.