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)
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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
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