Unverified Commit 7cbd0371 authored by Rodrigo Garcia's avatar Rodrigo Garcia Committed by GitHub

Improves UART reading performance (#7525)

* Improves UART reading performance

* overrides Stream::readBytes()

* fixes override signature

* adds some IDF error return  conditions
parent 744cbc2c
...@@ -450,10 +450,12 @@ int HardwareSerial::peek(void) ...@@ -450,10 +450,12 @@ int HardwareSerial::peek(void)
int HardwareSerial::read(void) int HardwareSerial::read(void)
{ {
if(available()) { uint8_t c = 0;
return uartRead(_uart); if (uartReadBytes(_uart, &c, 1, 0) == 1) {
} return c;
} else {
return -1; return -1;
}
} }
// read characters into buffer // read characters into buffer
...@@ -462,16 +464,13 @@ int HardwareSerial::read(void) ...@@ -462,16 +464,13 @@ int HardwareSerial::read(void)
// the buffer is NOT null terminated. // the buffer is NOT null terminated.
size_t HardwareSerial::read(uint8_t *buffer, size_t size) size_t HardwareSerial::read(uint8_t *buffer, size_t size)
{ {
size_t avail = available(); return uartReadBytes(_uart, buffer, size, 0);
if (size < avail) { }
avail = size;
} // Overrides Stream::readBytes() to be faster using IDF
size_t count = 0; size_t HardwareSerial::readBytes(uint8_t *buffer, size_t length)
while(count < avail) { {
*buffer++ = uartRead(_uart); return uartReadBytes(_uart, buffer, length, (uint32_t)getTimeout());
count++;
}
return count;
} }
void HardwareSerial::flush(void) void HardwareSerial::flush(void)
......
...@@ -118,6 +118,12 @@ public: ...@@ -118,6 +118,12 @@ public:
{ {
return read((uint8_t*) buffer, size); 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(void);
void flush( bool txOnly); void flush( bool txOnly);
size_t write(uint8_t); size_t write(uint8_t);
......
...@@ -331,7 +331,36 @@ uint32_t uartAvailableForWrite(uart_t* uart) ...@@ -331,7 +331,36 @@ uint32_t uartAvailableForWrite(uart_t* uart)
return available; 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) uint8_t uartRead(uart_t* uart)
{ {
if(uart == NULL) { if(uart == NULL) {
...@@ -347,7 +376,7 @@ uint8_t uartRead(uart_t* uart) ...@@ -347,7 +376,7 @@ uint8_t uartRead(uart_t* uart)
} else { } else {
int len = uart_read_bytes(uart->num, &c, 1, 20 / portTICK_RATE_MS); 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; c = 0;
} }
} }
...@@ -355,6 +384,7 @@ uint8_t uartRead(uart_t* uart) ...@@ -355,6 +384,7 @@ uint8_t uartRead(uart_t* uart)
return c; return c;
} }
uint8_t uartPeek(uart_t* uart) uint8_t uartPeek(uart_t* uart)
{ {
if(uart == NULL) { if(uart == NULL) {
...@@ -368,7 +398,7 @@ uint8_t uartPeek(uart_t* uart) ...@@ -368,7 +398,7 @@ uint8_t uartPeek(uart_t* uart)
c = uart->peek_byte; c = uart->peek_byte;
} else { } else {
int len = uart_read_bytes(uart->num, &c, 1, 20 / portTICK_RATE_MS); 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; c = 0;
} else { } else {
uart->has_peek = true; uart->has_peek = true;
......
...@@ -69,6 +69,7 @@ void uartGetEventQueue(uart_t* uart, QueueHandle_t *q); ...@@ -69,6 +69,7 @@ void uartGetEventQueue(uart_t* uart, QueueHandle_t *q);
uint32_t uartAvailable(uart_t* uart); uint32_t uartAvailable(uart_t* uart);
uint32_t uartAvailableForWrite(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 uartRead(uart_t* uart);
uint8_t uartPeek(uart_t* uart); uint8_t uartPeek(uart_t* uart);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment