Improves UART reading performance (#7525)

* Improves UART reading performance

* overrides Stream::readBytes()

* fixes override signature

* adds some IDF error return  conditions
This commit is contained in:
Rodrigo Garcia 2022-12-13 06:54:07 -03:00 committed by GitHub
parent 744cbc2c01
commit 7cbd0371e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 15 deletions

View file

@ -450,10 +450,12 @@ int HardwareSerial::peek(void)
int HardwareSerial::read(void)
{
if(available()) {
return uartRead(_uart);
uint8_t c = 0;
if (uartReadBytes(_uart, &c, 1, 0) == 1) {
return c;
} else {
return -1;
}
return -1;
}
// read characters into buffer
@ -462,16 +464,13 @@ int HardwareSerial::read(void)
// the buffer is NOT null terminated.
size_t HardwareSerial::read(uint8_t *buffer, size_t size)
{
size_t avail = available();
if (size < avail) {
avail = size;
}
size_t count = 0;
while(count < avail) {
*buffer++ = uartRead(_uart);
count++;
}
return count;
return uartReadBytes(_uart, buffer, size, 0);
}
// Overrides Stream::readBytes() to be faster using IDF
size_t HardwareSerial::readBytes(uint8_t *buffer, size_t length)
{
return uartReadBytes(_uart, buffer, length, (uint32_t)getTimeout());
}
void HardwareSerial::flush(void)

View file

@ -118,6 +118,12 @@ public:
{
return read((uint8_t*) buffer, size);
}
// Overrides Stream::readBytes() to be faster using IDF
size_t readBytes(uint8_t *buffer, size_t length);
size_t readBytes(char *buffer, size_t length)
{
return readBytes((uint8_t *) buffer, length);
}
void flush(void);
void flush( bool txOnly);
size_t write(uint8_t);

View file

@ -331,7 +331,36 @@ uint32_t uartAvailableForWrite(uart_t* uart)
return available;
}
size_t uartReadBytes(uart_t* uart, uint8_t *buffer, size_t size, uint32_t timeout_ms)
{
if(uart == NULL || size == 0 || buffer == NULL) {
return 0;
}
size_t bytes_read = 0;
UART_MUTEX_LOCK();
if (uart->has_peek) {
uart->has_peek = false;
*buffer++ = uart->peek_byte;
size--;
bytes_read = 1;
}
if (size > 0) {
int len = uart_read_bytes(uart->num, buffer, size, pdMS_TO_TICKS(timeout_ms));
if (len < 0) len = 0; // error reading UART
bytes_read += len;
}
UART_MUTEX_UNLOCK();
return bytes_read;
}
// DEPRICATED but the original code will be kepts here as future reference when a final solution
// to the UART driver is defined in the use case of reading byte by byte from UART.
uint8_t uartRead(uart_t* uart)
{
if(uart == NULL) {
@ -347,7 +376,7 @@ uint8_t uartRead(uart_t* uart)
} else {
int len = uart_read_bytes(uart->num, &c, 1, 20 / portTICK_RATE_MS);
if (len == 0) {
if (len <= 0) { // includes negative return from IDF in case of error
c = 0;
}
}
@ -355,6 +384,7 @@ uint8_t uartRead(uart_t* uart)
return c;
}
uint8_t uartPeek(uart_t* uart)
{
if(uart == NULL) {
@ -368,7 +398,7 @@ uint8_t uartPeek(uart_t* uart)
c = uart->peek_byte;
} else {
int len = uart_read_bytes(uart->num, &c, 1, 20 / portTICK_RATE_MS);
if (len == 0) {
if (len <= 0) { // includes negative return from IDF in case of error
c = 0;
} else {
uart->has_peek = true;

View file

@ -69,6 +69,7 @@ void uartGetEventQueue(uart_t* uart, QueueHandle_t *q);
uint32_t uartAvailable(uart_t* uart);
uint32_t uartAvailableForWrite(uart_t* uart);
size_t uartReadBytes(uart_t* uart, uint8_t *buffer, size_t size, uint32_t timeout_ms);
uint8_t uartRead(uart_t* uart);
uint8_t uartPeek(uart_t* uart);