1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

(re)introduce timeout in HardwareSerial::readBytes(buffer, size) (#5558)

(re)introduce timeout in HardwareSerial::readBytes(buffer, size), add HardwareSerial::read(buffer, size) + visual test
This commit is contained in:
david gauchard 2019-01-08 04:01:21 +01:00 committed by GitHub
parent 8f8628c681
commit dc03293d82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 7 deletions

View File

@ -27,6 +27,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <PolledTimeout.h>
#include "Arduino.h" #include "Arduino.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "Esp.h" #include "Esp.h"
@ -132,6 +133,22 @@ unsigned long HardwareSerial::detectBaudrate(time_t timeoutMillis)
return detectedBaudrate; return detectedBaudrate;
} }
size_t HardwareSerial::readBytes(char* buffer, size_t size)
{
size_t got = 0;
while (got < size)
{
esp8266::polledTimeout::oneShot timeOut(_timeout);
size_t avail;
while ((avail = available()) == 0 && !timeOut);
if (avail == 0)
break;
got += read(buffer + got, std::min(size - got, avail));
}
return got;
}
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
HardwareSerial Serial(UART0); HardwareSerial Serial(UART0);
#endif #endif

View File

@ -132,13 +132,15 @@ public:
// return -1 when data is unvailable (arduino api) // return -1 when data is unvailable (arduino api)
return uart_read_char(_uart); return uart_read_char(_uart);
} }
size_t readBytes(char* buffer, size_t size) override // ::read(buffer, size): same as readBytes without timeout
size_t read(char* buffer, size_t size)
{ {
return uart_read(_uart, buffer, size); return uart_read(_uart, buffer, size);
} }
size_t readBytes(char* buffer, size_t size) override;
size_t readBytes(uint8_t* buffer, size_t size) override size_t readBytes(uint8_t* buffer, size_t size) override
{ {
return uart_read(_uart, (char*)buffer, size); return readBytes((char*)buffer, size);
} }
int availableForWrite(void) int availableForWrite(void)
{ {

View File

@ -16,12 +16,15 @@
#define BUFFER_SIZE 4096 // may be useless to use more than 2*SERIAL_SIZE_RX #define BUFFER_SIZE 4096 // may be useless to use more than 2*SERIAL_SIZE_RX
#define SERIAL_SIZE_RX 1024 // Serial.setRxBufferSize() #define SERIAL_SIZE_RX 1024 // Serial.setRxBufferSize()
#define FAKE_INCREASED_AVAILABLE 100 // test readBytes's timeout
#define TIMEOUT 5000 #define TIMEOUT 5000
#define DEBUG(x...) //x #define DEBUG(x...) //x
uint8_t buf [BUFFER_SIZE]; uint8_t buf [BUFFER_SIZE];
uint8_t temp [BUFFER_SIZE]; uint8_t temp [BUFFER_SIZE];
bool reading = true; bool reading = true;
size_t testReadBytesTimeout = 0;
static size_t out_idx = 0, in_idx = 0; static size_t out_idx = 0, in_idx = 0;
static size_t local_receive_size = 0; static size_t local_receive_size = 0;
@ -83,6 +86,7 @@ void setup() {
size_for_1sec = baud / 10; // 8n1=10baudFor8bits size_for_1sec = baud / 10; // 8n1=10baudFor8bits
logger->printf("led changes state every %zd bytes (= 1 second)\n", size_for_1sec); logger->printf("led changes state every %zd bytes (= 1 second)\n", size_for_1sec);
logger->printf("press 's' to stop reading, not writing (induces overrun)\n"); logger->printf("press 's' to stop reading, not writing (induces overrun)\n");
logger->printf("press 't' to toggle timeout testing on readBytes\n");
// prepare send/compare buffer // prepare send/compare buffer
for (size_t i = 0; i < sizeof buf; i++) { for (size_t i = 0; i < sizeof buf; i++) {
@ -136,7 +140,7 @@ void loop() {
if (reading) { if (reading) {
// receive data // receive data
maxlen = Serial.available(); maxlen = Serial.available() + testReadBytesTimeout;
if (maxlen > maxavail) { if (maxlen > maxavail) {
maxavail = maxlen; maxavail = maxlen;
} }
@ -180,8 +184,16 @@ void loop() {
timeout = (last_ms = now_ms) + TIMEOUT; timeout = (last_ms = now_ms) + TIMEOUT;
} }
if (logger->read() == 's') { if (logger->available())
switch (logger->read()) {
case 's':
logger->println("now stopping reading, keeping writing"); logger->println("now stopping reading, keeping writing");
reading = false; reading = false;
break;
case 't':
testReadBytesTimeout ^= FAKE_INCREASED_AVAILABLE;
logger->printf("testing readBytes timeout: %d\n", !!testReadBytesTimeout);
break;
default:;
} }
} }

View File

@ -30,6 +30,7 @@
*/ */
#include <Arduino.h> #include <Arduino.h>
#include <PolledTimeout.h>
#include <unistd.h> // write #include <unistd.h> // write
@ -64,6 +65,22 @@ void HardwareSerial::flush ()
fflush(stdout); fflush(stdout);
} }
size_t HardwareSerial::readBytes(char* buffer, size_t size)
{
size_t got = 0;
while (got < size)
{
esp8266::polledTimeout::oneShot timeOut(_timeout);
size_t avail;
while ((avail = available()) == 0 && !timeOut);
if (avail == 0)
break;
got += read(buffer + got, std::min(size - got, avail));
}
return got;
}
// uart.c // uart.c
extern "C" extern "C"