Hi, new here. I am using esp-idf v5.3.1 for an S3 device.
My current problem is how to get an esp uart to stream bursts of data with a defined cadence. I need to send 59 bytes at 230400-baud every 4 ms -- the data packet lasts about 2.6ms, with about a 1.4ms inter-packet gap. This device connects to a legacy system and this uart timing is important -- the packet must be sent with no interruptions or delays.
On core 0, I have an lvgl/gui task running at a low priority. Also on core 0 is a medium-priority sd-card task that, when enabled, reads several-thousand-byte chunks from a file into ping-pong buffers (this happens every 600ms or so and is throttled by the buffers being emptied). These ping-pong buffers are read by a 4ms timer to grab the next 24-bytes of data to send to a queue for the uart task (which formats it into a 59-byte output packet and sends it to the uart).
My current plan is to put the uart task on core 1 (which has just one other lower-priority task). I also used a boot-time init task to ensure the uart isr is on core 1. The uart task will read the queue and dump the data to the uart.
I have various related questions:
- does the uart_write_bytes(...) need a critical-section wrap to keep the packet intact?
- does the uart isr get interrupted by freertos at all (putting a gap in the packet)?
- does the uart isr need to be in iram?
- does the 4ms timer callback need to be in iram, and should it be on core 1 as well?
And then I started wondering about the queue memory -- I am unclear where that resides and whether writes or reads of the queue can be paused by freertos activity. I have data being pulled off an sd-card file in large-ish chunks and saved to a buffer
in memory. When my 4ms timer fires it grabs 24 bytes from that buffer and stuffs it into a queue.
- can the 4ms timer have priority higher than freertos so it does not get interrupted?
- can the queue being read by the uart task on core 1 be interrupted by system activity?
- is there a dma option to consider?
Pardon the barrage of questions, but freertos and ESP two-core systems are still pretty new to me
(though have been coding C for many decades). Much of this code is running, but I am unsure the
best approach for this timing-sensitive uart streaming output. Thx
uart streaming output without interruptions
-
- Posts: 10
- Joined: Sat Feb 22, 2025 7:21 pm
-
- Posts: 9985
- Joined: Thu Nov 26, 2015 4:08 am
Re: uart streaming output without interruptions
It should be mostly fine. The UART has a hardware FIFO of (iirc by default) 128 bytes, so if you call uart_write_bytes() for your 59 bytes, it'll dump the data immediately into the FIFO and the UART itself will handle sending them without interruption. In theory, you could have an issue if an interrupt occurs after the 1st byte and lasts long enough for the UART to send it all, but you could work around that by having interrupt-intensive stuff (WiFi, BT, LCD, ...) running on one core and the UART thing on the 2nd core.
-
- Posts: 10
- Joined: Sat Feb 22, 2025 7:21 pm
Re: uart streaming output without interruptions
Thanks for the suggestions. I had also asked this on the freertos forum:
https://forums.freertos.org/t/how-to-st ... data/22620
The summary: having the timer feed a queue and a task reading the queue, only got one out of three posts to the queue and did not work. Perhaps things could have been tuned to make it work, but I ended up just removing the task and queue and doing it all in the timer -- works great!
https://forums.freertos.org/t/how-to-st ... data/22620
The summary: having the timer feed a queue and a task reading the queue, only got one out of three posts to the queue and did not work. Perhaps things could have been tuned to make it work, but I ended up just removing the task and queue and doing it all in the timer -- works great!
Who is online
Users browsing this forum: No registered users and 123 guests