Closed
Description
Hardware:
Board: ESP32
Core Installation version: framework-arduinoespressif32 3.10006.210326 (1.0.6)
IDE name: Platform.io
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 115200
Computer OS: Windows 10
Description:
I have worker task, which should sleep while no incoming data on uart and wake on data and process it.
I found that HardwareSerial::available() and HardwareSerial::read()
are non-blocking. So i have busyloop in task which is not good for CPU resource optimization.
Sketch:
#include <Arduino.h>
#include <HardwareSerial.h>
void *uart_task(void *arg)
{
size_t read;
for (;;) {
wait_for_data(&Serial2); // <- How to do this????
if (!Serial2.available()) // This is non-blocking.
continue;
read = Serial2.read(buff, sizeof(buff)); // Also non-blocking.
process_data(buff, read);
}
}
Metadata
Metadata
Assignees
Labels
No labels
Activity
dibalavs commentedon Jul 28, 2021
Some additionals:
I mean sleep on some sync primitive like mutex or semaphore.
I know that Stream has timedRead() function:
But it is not I want.
bertmelis commentedon Jul 28, 2021
Why don't you do
delay()
usesvTaskDelay
under the hood so during the wait your task is using minimal resources. In the Arduino framework there is no other way besides polling.dibalavs commentedon Jul 29, 2021
@bertmelis , actually this is not solution. This is dirty hack.
If delay() will very short, It will just usual busy loop.
if delay() will long, it will have slow response to available data in uart buffer, so you can lost data on overflow while is sleeping on delay()
just curious, esp32-hal-uart.c which is used as back-end for HardwareSerial is using xQueueReceive() for reading from uart buffer, which CAN sleep while no data, but this queue is used in non-blocking mode.
I think it couldn't be a problem to do sleeping on no-data.
bertmelis commentedon Jul 29, 2021
Yes it will be a problem because it will be a MAJOR breaking change.
It might not be a problem for you but it will for numerous other users, including me.
If the suggested solution doesn't work for you, you might want to switch to ESP-IDF or a completely different platform.
Besides, what do you think the processor is doing when there is nothing specific to be done?
Do you actually have a problem with timing or are you chasing nonexisting problems?
SuGlider commentedon Aug 17, 2021
Would the Arduino serialEvent be a solution?
https://www.arduino.cc/reference/en/language/functions/communication/serial/serialevent/
It's not blocking, but it is called only when there is some data to be read on Serial Port. It could trigger some action or task.
It checks for data right after executing loop(). Thus if loop() takes too long, serialEvent won't be frequently verified.
serialEvent is implemented in the PR #5549
VojtechBartoska commentedon Nov 18, 2021
@dibalavs Any updates or can I consider this as solved?
SuGlider commentedon Jan 12, 2022
A potential solution is being implemented.
It's the
Serial.onReceive(function)
As soon as any data arrives UART RX,
function()
will called.3 remaining items