uart streaming output without interruptions
Posted: Mon Feb 24, 2025 6:12 am
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
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