From e5c2fea7318ac35360ebaf69662338718682211f Mon Sep 17 00:00:00 2001 From: david gauchard <gauchard@laas.fr> Date: Thu, 5 Apr 2018 01:55:33 +0200 Subject: [PATCH 01/21] uart fixes and BW improvements --- cores/esp8266/HardwareSerial.h | 12 +++++ cores/esp8266/uart.c | 97 ++++++++++++++++++++++++---------- cores/esp8266/uart.h | 2 + 3 files changed, 84 insertions(+), 27 deletions(-) diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index 0333d4ca87..532ed64241 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -88,6 +88,10 @@ class HardwareSerial: public Stream void end(); size_t setRxBufferSize(size_t size); + size_t getRxBufferSize() + { + return uart_get_rx_buffer_size(_uart); + } void swap() { @@ -128,6 +132,14 @@ class HardwareSerial: public Stream // this may return -1, but that's okay return uart_read_char(_uart); } + size_t readBytes (char* buffer, size_t size) override + { + return uart_read(_uart, buffer, size); + } + size_t readBytes (uint8_t* buffer, size_t size) override + { + return uart_read(_uart, (char*)buffer, size); + } int availableForWrite(void) { return static_cast<int>(uart_tx_free(_uart)); diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 47814f7a9d..9ac932e8ed 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -108,46 +108,26 @@ uart_rx_available_unsafe(uart_t* uart) return uart_rx_buffer_available_unsafe(uart->rx_buffer) + uart_rx_fifo_available(uart->uart_nr); } - //#define UART_DISCARD_NEWEST // Copy all the rx fifo bytes that fit into the rx buffer inline void +ICACHE_RAM_ATTR uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) { struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer; - while(uart_rx_fifo_available(uart->uart_nr)) { size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size; if(nextPos == rx_buffer->rpos) - { - - if (!uart->overrun) - { - uart->overrun = true; - os_printf_plus(overrun_str); - } - - // a choice has to be made here, - // do we discard newest or oldest data? -#ifdef UART_DISCARD_NEWEST - // discard newest data - // Stop copying if rx buffer is full - USF(uart->uart_nr); break; -#else - // discard oldest data - if (++rx_buffer->rpos == rx_buffer->size) - rx_buffer->rpos = 0; -#endif - } uint8_t data = USF(uart->uart_nr); rx_buffer->buffer[rx_buffer->wpos] = data; rx_buffer->wpos = nextPos; } } + inline int uart_peek_char_unsafe(uart_t* uart) { @@ -212,6 +192,50 @@ uart_read_char(uart_t* uart) return data; } +extern void iprint (int x); +extern void sprint (const char* s); + +size_t +uart_read(uart_t* uart, char* userbuffer, size_t usersize) +{ + if(uart == NULL || !uart->rx_enabled) + return -1; + + size_t ret = 0; + + ETS_UART_INTR_DISABLE(); + +sprint("a");iprint(usersize);iprint(uart->rx_buffer->rpos); + while (ret < usersize && uart_rx_available_unsafe(uart)) + { +#if 1 + if (!uart_rx_buffer_available_unsafe(uart->rx_buffer)) + { + // no more data in sw buffer, take them from hw fifo + while (ret < usersize && uart_rx_fifo_available(uart->uart_nr)) + userbuffer[ret++] = USF(uart->uart_nr); + + // no more sw/hw data available + break; + } +#endif + // pour sw buffer to user's buffer + // get largest linear length from sw buffer + size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos? + uart->rx_buffer->wpos - uart->rx_buffer->rpos: + uart->rx_buffer->size - uart->rx_buffer->rpos; + if (ret + chunk > usersize) + chunk = usersize - ret; + memcpy(userbuffer + ret, uart->rx_buffer->buffer + uart->rx_buffer->rpos, chunk); + uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size; + ret += chunk; + } +iprint(ret);iprint(uart->rx_buffer->rpos); + + ETS_UART_INTR_ENABLE(); + return ret; +} + size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size) { @@ -240,22 +264,36 @@ uart_resize_rx_buffer(uart_t* uart, size_t new_size) return uart->rx_buffer->size; } +size_t +uart_get_rx_buffer_size(uart_t* uart) +{ + return uart && uart->rx_enabled? uart->rx_buffer->size: 0; +} void ICACHE_RAM_ATTR uart_isr(void * arg) { uart_t* uart = (uart_t*)arg; + uint32_t usis = USIS(uart->uart_nr); + if(uart == NULL || !uart->rx_enabled) { - USIC(uart->uart_nr) = USIS(uart->uart_nr); + USIC(uart->uart_nr) = usis; ETS_UART_INTR_DISABLE(); return; } - if(USIS(uart->uart_nr) & ((1 << UIFF) | (1 << UITO))) + + if(usis & (1 << UIFF)) uart_rx_copy_fifo_to_buffer_unsafe(uart); + + if((usis & (1 << UIOF)) && !uart->overrun) + { + uart->overrun = true; +// os_printf_plus(overrun_str); + } - USIC(uart->uart_nr) = USIS(uart->uart_nr); + USIC(uart->uart_nr) = usis; } static void @@ -268,9 +306,12 @@ uart_start_isr(uart_t* uart) // triggers the IRS very often. A value of 127 would not leave much time // for ISR to clear fifo before the next byte is dropped. So pick a value // in the middle. - USC1(uart->uart_nr) = (100 << UCFFT) | (0x02 << UCTOT) | (1 <<UCTOE ); + #define INTRIGG 100 // was:100 + //was:USC1(uart->uart_nr) = (INTRIGG << UCFFT) | (0x02 << UCTOT) | (1 <<UCTOE); + USC1(uart->uart_nr) = (INTRIGG << UCFFT); USIC(uart->uart_nr) = 0xffff; - USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIFR) | (1 << UITO); + //was: USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIFR) | (1 << UITO); + USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIOF); ETS_UART_INTR_ATTACH(uart_isr, (void *)uart); ETS_UART_INTR_ENABLE(); } @@ -312,9 +353,11 @@ uart_tx_fifo_full(const int uart_nr) static void uart_do_write_char(const int uart_nr, char c) { + ETS_UART_INTR_DISABLE(); while(uart_tx_fifo_full(uart_nr)); USF(uart_nr) = c; + ETS_UART_INTR_ENABLE(); } size_t diff --git a/cores/esp8266/uart.h b/cores/esp8266/uart.h index 127c5d0ebb..73c4449274 100644 --- a/cores/esp8266/uart.h +++ b/cores/esp8266/uart.h @@ -126,11 +126,13 @@ void uart_set_baudrate(uart_t* uart, int baud_rate); int uart_get_baudrate(uart_t* uart); size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size); +size_t uart_get_rx_buffer_size(uart_t* uart); size_t uart_write_char(uart_t* uart, char c); size_t uart_write(uart_t* uart, const char* buf, size_t size); int uart_read_char(uart_t* uart); int uart_peek_char(uart_t* uart); +size_t uart_read(uart_t* uart, char* buffer, size_t size); size_t uart_rx_available(uart_t* uart); size_t uart_tx_free(uart_t* uart); void uart_wait_tx_empty(uart_t* uart); From f79bc9090ddb2b0d97deb6e6fe62c81524d43637 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 5 Apr 2018 15:10:05 +0200 Subject: [PATCH 02/21] uart: read_char straightly use hw buffer --- cores/esp8266/HardwareSerial.h | 4 +-- cores/esp8266/uart.c | 55 ++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index 532ed64241..26b190bcf9 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -132,11 +132,11 @@ class HardwareSerial: public Stream // this may return -1, but that's okay return uart_read_char(_uart); } - size_t readBytes (char* buffer, size_t size) override + size_t readBytes(char* buffer, size_t size) override { return uart_read(_uart, buffer, size); } - 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); } diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 9ac932e8ed..4b3b4021a0 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -108,14 +108,12 @@ uart_rx_available_unsafe(uart_t* uart) return uart_rx_buffer_available_unsafe(uart->rx_buffer) + uart_rx_fifo_available(uart->uart_nr); } -//#define UART_DISCARD_NEWEST - // Copy all the rx fifo bytes that fit into the rx buffer inline void -ICACHE_RAM_ATTR uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) { struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer; + while(uart_rx_fifo_available(uart->uart_nr)) { size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size; @@ -136,11 +134,14 @@ uart_peek_char_unsafe(uart_t* uart) //without the following if statement and body, there is a good chance of a fifo overrun if (uart_rx_buffer_available_unsafe(uart->rx_buffer) == 0) + // hw fifo can't be peeked, data need to be copied to sw uart_rx_copy_fifo_to_buffer_unsafe(uart); return uart->rx_buffer->buffer[uart->rx_buffer->rpos]; } +#if 0 + inline int uart_read_char_unsafe(uart_t* uart) { @@ -150,7 +151,31 @@ uart_read_char_unsafe(uart_t* uart) return data; } +#else +// taking data straight from hw fifo: loopback-test BW jumps by 19% +inline int +uart_read_char_unsafe(uart_t* uart) +{ + if (uart_rx_buffer_available_unsafe(uart->rx_buffer)) + { + // take oldest sw data + int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos]; + uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size; + return ret; + } + + if (uart_rx_fifo_available(uart->uart_nr)) + { + // no sw data, take from hw fifo + return USF(uart->uart_nr); + } + + // unavailable + return -1; +} + +#endif /**********************************************************/ @@ -195,6 +220,7 @@ uart_read_char(uart_t* uart) extern void iprint (int x); extern void sprint (const char* s); +// loopback-test BW jumps by 190% size_t uart_read(uart_t* uart, char* userbuffer, size_t usersize) { @@ -202,23 +228,20 @@ uart_read(uart_t* uart, char* userbuffer, size_t usersize) return -1; size_t ret = 0; - ETS_UART_INTR_DISABLE(); -sprint("a");iprint(usersize);iprint(uart->rx_buffer->rpos); while (ret < usersize && uart_rx_available_unsafe(uart)) { -#if 1 if (!uart_rx_buffer_available_unsafe(uart->rx_buffer)) { // no more data in sw buffer, take them from hw fifo while (ret < usersize && uart_rx_fifo_available(uart->uart_nr)) - userbuffer[ret++] = USF(uart->uart_nr); - + userbuffer[ret++] = USF(uart->uart_nr); + // no more sw/hw data available - break; + break; } -#endif + // pour sw buffer to user's buffer // get largest linear length from sw buffer size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos? @@ -230,8 +253,7 @@ sprint("a");iprint(usersize);iprint(uart->rx_buffer->rpos); uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size; ret += chunk; } -iprint(ret);iprint(uart->rx_buffer->rpos); - + ETS_UART_INTR_ENABLE(); return ret; } @@ -306,7 +328,12 @@ uart_start_isr(uart_t* uart) // triggers the IRS very often. A value of 127 would not leave much time // for ISR to clear fifo before the next byte is dropped. So pick a value // in the middle. - #define INTRIGG 100 // was:100 + // update: loopback test @ 3Mbauds/8n1 (=2343Kibits/s): + // - 4..120 give 2300Kibits/s + // - 1, 2, 3 are below + // was 100, use 8 to stay away from overrun + #define INTRIGG 8 + //was:USC1(uart->uart_nr) = (INTRIGG << UCFFT) | (0x02 << UCTOT) | (1 <<UCTOE); USC1(uart->uart_nr) = (INTRIGG << UCFFT); USIC(uart->uart_nr) = 0xffff; @@ -353,11 +380,9 @@ uart_tx_fifo_full(const int uart_nr) static void uart_do_write_char(const int uart_nr, char c) { - ETS_UART_INTR_DISABLE(); while(uart_tx_fifo_full(uart_nr)); USF(uart_nr) = c; - ETS_UART_INTR_ENABLE(); } size_t From 45e2bd5fdcb5b5241f428472ef777b48d2cc3351 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 5 Apr 2018 15:21:17 +0200 Subject: [PATCH 03/21] +attributes for functions called by ISR --- cores/esp8266/uart.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 4b3b4021a0..e0f597435d 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -83,7 +83,8 @@ struct uart_ -inline size_t +// called by ISR +inline size_t ICACHE_RAM_ATTR uart_rx_fifo_available(const int uart_nr) { return (USS(uart_nr) >> USRXC) & 0xFF; @@ -109,7 +110,8 @@ uart_rx_available_unsafe(uart_t* uart) } // Copy all the rx fifo bytes that fit into the rx buffer -inline void +// called by ISR +inline void ICACHE_RAM_ATTR uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) { struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer; From 974b758412171daf2b9e4f773608618677932a30 Mon Sep 17 00:00:00 2001 From: david gauchard <gauchard@laas.fr> Date: Thu, 5 Apr 2018 01:55:33 +0200 Subject: [PATCH 04/21] uart: BW improvements read_char straightly use hw buffer (+ ~10%bw) read by block (+ ~190%bw) (instead of generic Stream::readBytes) attributes for functions called by ISR remove overrun message remove some ISR flags which were not honoured --- cores/esp8266/HardwareSerial.h | 8 +++ cores/esp8266/uart.c | 89 +++++++++++++++++++++++++++------- cores/esp8266/uart.h | 1 + 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index 0333d4ca87..a8ab643049 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -128,6 +128,14 @@ class HardwareSerial: public Stream // this may return -1, but that's okay return uart_read_char(_uart); } + size_t readBytes(char* buffer, size_t size) override + { + return uart_read(_uart, buffer, size); + } + size_t readBytes(uint8_t* buffer, size_t size) override + { + return uart_read(_uart, (char*)buffer, size); + } int availableForWrite(void) { return static_cast<int>(uart_tx_free(_uart)); diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 47814f7a9d..b033dc65ec 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -45,7 +45,6 @@ #include "esp8266_peri.h" #include "user_interface.h" -const char overrun_str [] ICACHE_RODATA_ATTR STORE_ATTR = "uart input full!\r\n"; static int s_uart_debug_nr = UART0; @@ -83,7 +82,8 @@ struct uart_ -inline size_t +// called by ISR +inline size_t ICACHE_RAM_ATTR uart_rx_fifo_available(const int uart_nr) { return (USS(uart_nr) >> USRXC) & 0xFF; @@ -108,11 +108,11 @@ uart_rx_available_unsafe(uart_t* uart) return uart_rx_buffer_available_unsafe(uart->rx_buffer) + uart_rx_fifo_available(uart->uart_nr); } - //#define UART_DISCARD_NEWEST // Copy all the rx fifo bytes that fit into the rx buffer -inline void +// called by ISR +inline void ICACHE_RAM_ATTR uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) { struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer; @@ -122,12 +122,7 @@ uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size; if(nextPos == rx_buffer->rpos) { - - if (!uart->overrun) - { - uart->overrun = true; - os_printf_plus(overrun_str); - } + uart->overrun = true; // a choice has to be made here, // do we discard newest or oldest data? @@ -156,20 +151,33 @@ uart_peek_char_unsafe(uart_t* uart) //without the following if statement and body, there is a good chance of a fifo overrun if (uart_rx_buffer_available_unsafe(uart->rx_buffer) == 0) + // hw fifo can't be peeked, data need to be copied to sw uart_rx_copy_fifo_to_buffer_unsafe(uart); return uart->rx_buffer->buffer[uart->rx_buffer->rpos]; } -inline int +// taking data straight from hw fifo: loopback-test BW jumps by 19% +inline int uart_read_char_unsafe(uart_t* uart) { - int data = uart_peek_char_unsafe(uart); - if(data != -1) + if (uart_rx_buffer_available_unsafe(uart->rx_buffer)) + { + // take oldest sw data + int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos]; uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size; - return data; -} + return ret; + } + + if (uart_rx_fifo_available(uart->uart_nr)) + { + // no sw data, take from hw fifo + return USF(uart->uart_nr); + } + // unavailable + return -1; +} /**********************************************************/ @@ -212,6 +220,44 @@ uart_read_char(uart_t* uart) return data; } +// loopback-test BW jumps by 190% +size_t +uart_read(uart_t* uart, char* userbuffer, size_t usersize) +{ + if(uart == NULL || !uart->rx_enabled) + return -1; + + size_t ret = 0; + ETS_UART_INTR_DISABLE(); + + while (ret < usersize && uart_rx_available_unsafe(uart)) + { + if (!uart_rx_buffer_available_unsafe(uart->rx_buffer)) + { + // no more data in sw buffer, take them from hw fifo + while (ret < usersize && uart_rx_fifo_available(uart->uart_nr)) + userbuffer[ret++] = USF(uart->uart_nr); + + // no more sw/hw data available + break; + } + + // pour sw buffer to user's buffer + // get largest linear length from sw buffer + size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos? + uart->rx_buffer->wpos - uart->rx_buffer->rpos: + uart->rx_buffer->size - uart->rx_buffer->rpos; + if (ret + chunk > usersize) + chunk = usersize - ret; + memcpy(userbuffer + ret, uart->rx_buffer->buffer + uart->rx_buffer->rpos, chunk); + uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size; + ret += chunk; + } + + ETS_UART_INTR_ENABLE(); + return ret; +} + size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size) { @@ -252,7 +298,7 @@ uart_isr(void * arg) ETS_UART_INTR_DISABLE(); return; } - if(USIS(uart->uart_nr) & ((1 << UIFF) | (1 << UITO))) + if(USIS(uart->uart_nr) & (1 << UIFF)) uart_rx_copy_fifo_to_buffer_unsafe(uart); USIC(uart->uart_nr) = USIS(uart->uart_nr); @@ -268,9 +314,16 @@ uart_start_isr(uart_t* uart) // triggers the IRS very often. A value of 127 would not leave much time // for ISR to clear fifo before the next byte is dropped. So pick a value // in the middle. - USC1(uart->uart_nr) = (100 << UCFFT) | (0x02 << UCTOT) | (1 <<UCTOE ); + // update: with direct peeking and loopback test @ 3Mbauds/8n1 (=2343Kibits/s): + // when high, allows to directly peek into hw buffer, avoiding two copies + // - 4..120 give 2300Kibits/s + // - 1, 2, 3 are below + // - far below 2000 without direct peeking + #define INTRIGGER 100 + + USC1(uart->uart_nr) = (INTRIGGER << UCFFT); USIC(uart->uart_nr) = 0xffff; - USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIFR) | (1 << UITO); + USIE(uart->uart_nr) = (1 << UIFF); ETS_UART_INTR_ATTACH(uart_isr, (void *)uart); ETS_UART_INTR_ENABLE(); } diff --git a/cores/esp8266/uart.h b/cores/esp8266/uart.h index 127c5d0ebb..e0a36eb5d2 100644 --- a/cores/esp8266/uart.h +++ b/cores/esp8266/uart.h @@ -131,6 +131,7 @@ size_t uart_write_char(uart_t* uart, char c); size_t uart_write(uart_t* uart, const char* buf, size_t size); int uart_read_char(uart_t* uart); int uart_peek_char(uart_t* uart); +size_t uart_read(uart_t* uart, char* buffer, size_t size); size_t uart_rx_available(uart_t* uart); size_t uart_tx_free(uart_t* uart); void uart_wait_tx_empty(uart_t* uart); From 6560ab87f509fbeb6e1827aaed90f866ccde37d3 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Fri, 30 Nov 2018 15:19:17 +0100 Subject: [PATCH 05/21] fix merge --- cores/esp8266/HardwareSerial.h | 4 +- cores/esp8266/uart.c | 89 +++++----------------------------- 2 files changed, 15 insertions(+), 78 deletions(-) diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index cddd4fe311..54d600ccca 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -124,12 +124,12 @@ class HardwareSerial: public Stream int peek(void) override { - // this may return -1, but that's okay + // return -1 when data is unvailable (arduino api) return uart_peek_char(_uart); } int read(void) override { - // this may return -1, but that's okay + // return -1 when data is unvailable (arduino api) return uart_read_char(_uart); } size_t readBytes(char* buffer, size_t size) override diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 69ab124a7a..f78b78cfef 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -47,7 +47,7 @@ #include "user_interface.h" #include "uart_register.h" -//const char overrun_str [] PROGMEM STORE_ATTR = "uart input full!\r\n"; +const char overrun_str [] PROGMEM STORE_ATTR = "uart input full!\r\n"; static int s_uart_debug_nr = UART0; @@ -111,11 +111,8 @@ uart_rx_available_unsafe(uart_t* uart) return uart_rx_buffer_available_unsafe(uart->rx_buffer) + uart_rx_fifo_available(uart->uart_nr); } -<<<<<<< HEAD -======= //#define UART_DISCARD_NEWEST ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 // Copy all the rx fifo bytes that fit into the rx buffer // called by ISR inline void ICACHE_RAM_ATTR @@ -127,10 +124,12 @@ uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) { size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size; if(nextPos == rx_buffer->rpos) -<<<<<<< HEAD -======= { - uart->overrun = true; + if (!uart->overrun) + { + uart->overrun = true; + os_printf_plus(overrun_str); + } // a choice has to be made here, // do we discard newest or oldest data? @@ -138,15 +137,19 @@ uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) // discard newest data // Stop copying if rx buffer is full USF(uart->uart_nr); ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 break; +#else + // discard oldest data + if (++rx_buffer->rpos == rx_buffer->size) + rx_buffer->rpos = 0; +#endif + } uint8_t data = USF(uart->uart_nr); rx_buffer->buffer[rx_buffer->wpos] = data; rx_buffer->wpos = nextPos; } } - inline int uart_peek_char_unsafe(uart_t* uart) { @@ -161,27 +164,6 @@ uart_peek_char_unsafe(uart_t* uart) return uart->rx_buffer->buffer[uart->rx_buffer->rpos]; } -<<<<<<< HEAD -#if 0 - -inline int -======= -// taking data straight from hw fifo: loopback-test BW jumps by 19% -inline int ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 -uart_read_char_unsafe(uart_t* uart) -{ - if (uart_rx_buffer_available_unsafe(uart->rx_buffer)) - { - // take oldest sw data - int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos]; - uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size; - return ret; - } - -<<<<<<< HEAD -#else - // taking data straight from hw fifo: loopback-test BW jumps by 19% inline int uart_read_char_unsafe(uart_t* uart) @@ -193,33 +175,11 @@ uart_read_char_unsafe(uart_t* uart) uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size; return ret; } -======= - if (uart_rx_fifo_available(uart->uart_nr)) - { - // no sw data, take from hw fifo - return USF(uart->uart_nr); - } - - // unavailable - return -1; -} ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 - - if (uart_rx_fifo_available(uart->uart_nr)) - { - // no sw data, take from hw fifo - return USF(uart->uart_nr); - } // unavailable - return -1; + return -3; } -#endif -/**********************************************************/ - - - size_t uart_rx_available(uart_t* uart) { @@ -257,12 +217,6 @@ uart_read_char(uart_t* uart) return data; } -<<<<<<< HEAD -extern void iprint (int x); -extern void sprint (const char* s); - -======= ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 // loopback-test BW jumps by 190% size_t uart_read(uart_t* uart, char* userbuffer, size_t usersize) @@ -281,11 +235,7 @@ uart_read(uart_t* uart, char* userbuffer, size_t usersize) while (ret < usersize && uart_rx_fifo_available(uart->uart_nr)) userbuffer[ret++] = USF(uart->uart_nr); -<<<<<<< HEAD // no more sw/hw data available -======= - // no more sw/hw data available ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 break; } @@ -375,7 +325,6 @@ uart_start_isr(uart_t* uart) // triggers the IRS very often. A value of 127 would not leave much time // for ISR to clear fifo before the next byte is dropped. So pick a value // in the middle. -<<<<<<< HEAD // update: loopback test @ 3Mbauds/8n1 (=2343Kibits/s): // - 4..120 give 2300Kibits/s // - 1, 2, 3 are below @@ -387,18 +336,6 @@ uart_start_isr(uart_t* uart) USIC(uart->uart_nr) = 0xffff; //was: USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIFR) | (1 << UITO); USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIOF); -======= - // update: with direct peeking and loopback test @ 3Mbauds/8n1 (=2343Kibits/s): - // when high, allows to directly peek into hw buffer, avoiding two copies - // - 4..120 give 2300Kibits/s - // - 1, 2, 3 are below - // - far below 2000 without direct peeking - #define INTRIGGER 100 - - USC1(uart->uart_nr) = (INTRIGGER << UCFFT); - USIC(uart->uart_nr) = 0xffff; - USIE(uart->uart_nr) = (1 << UIFF); ->>>>>>> 3c1e312faff1669b62cfd47bee6edaea49785aa5 ETS_UART_INTR_ATTACH(uart_isr, (void *)uart); ETS_UART_INTR_ENABLE(); } From c68d474c4151f5b9a5964dbf96f3d9b092d9d71e Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Wed, 5 Dec 2018 13:02:47 +0100 Subject: [PATCH 06/21] fix buffer overflow --- cores/esp8266/uart.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index f78b78cfef..d4545ca2b8 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -175,9 +175,8 @@ uart_read_char_unsafe(uart_t* uart) uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size; return ret; } - // unavailable - return -3; + return -1; } size_t @@ -208,13 +207,8 @@ uart_peek_char(uart_t* uart) int uart_read_char(uart_t* uart) { - if(uart == NULL || !uart->rx_enabled) - return -1; - - ETS_UART_INTR_DISABLE(); - int data = uart_read_char_unsafe(uart); - ETS_UART_INTR_ENABLE(); - return data; + uint8_t ret; + return uart_read(uart, (char*)&ret, 1)? ret: -1; } // loopback-test BW jumps by 190% @@ -222,7 +216,7 @@ size_t uart_read(uart_t* uart, char* userbuffer, size_t usersize) { if(uart == NULL || !uart->rx_enabled) - return -1; + return 0; size_t ret = 0; ETS_UART_INTR_DISABLE(); @@ -272,6 +266,8 @@ uart_resize_rx_buffer(uart_t* uart, size_t new_size) ETS_UART_INTR_DISABLE(); while(uart_rx_available_unsafe(uart) && new_wpos < new_size) new_buf[new_wpos++] = uart_read_char_unsafe(uart); //if uart_rx_available_unsafe() returns non-0, uart_read_char_unsafe() can't return -1 + if (new_wpos == new_size) + new_wpos = 0; uint8_t * old_buf = uart->rx_buffer->buffer; uart->rx_buffer->rpos = 0; From ff63718320cd3b539e4f6011ad9c5388f6966e07 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Wed, 5 Dec 2018 13:18:58 +0100 Subject: [PATCH 07/21] serial stress test sketch --- cores/esp8266/uart.c | 6 +- .../examples/serialStress/serialStress.ino | 164 ++++++++++++++++++ 2 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 libraries/esp8266/examples/serialStress/serialStress.ino diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index d4545ca2b8..d47bc77840 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -322,10 +322,10 @@ uart_start_isr(uart_t* uart) // for ISR to clear fifo before the next byte is dropped. So pick a value // in the middle. // update: loopback test @ 3Mbauds/8n1 (=2343Kibits/s): - // - 4..120 give 2300Kibits/s + // - 4..120 give > 2300Kibits/s // - 1, 2, 3 are below - // was 100, use 8 to stay away from overrun - #define INTRIGG 8 + // was 100, use 16 to stay away from overrun + #define INTRIGG 16 //was:USC1(uart->uart_nr) = (INTRIGG << UCFFT) | (0x02 << UCTOT) | (1 <<UCTOE); USC1(uart->uart_nr) = (INTRIGG << UCFFT); diff --git a/libraries/esp8266/examples/serialStress/serialStress.ino b/libraries/esp8266/examples/serialStress/serialStress.ino new file mode 100644 index 0000000000..b2c7df1bc6 --- /dev/null +++ b/libraries/esp8266/examples/serialStress/serialStress.ino @@ -0,0 +1,164 @@ + +/* + Serial read/write/verify/benchmark + Using internal loopback + Using SoftwareSerial library for logging + + Sketch meant for debugging only + Released to public domain +*/ + +#include <ESP8266WiFi.h> +#include <SoftwareSerial.h> + +#define SSBAUD 115200 // logger on console for humans +#define BAUD 3000000 // hardware serial stress test +#define BUFFER_SIZE 4096 // may be useless to use more than 2*SERIAL_SIZE_RX +#define SERIAL_SIZE_RX 1024 // Serial.setRxBufferSize() + +#define TIMEOUT 5000 +#define DEBUG(x...) //x + +uint8_t buf [BUFFER_SIZE]; +uint8_t temp [BUFFER_SIZE]; + +static size_t out_idx = 0, in_idx = 0; +static size_t local_receive_size = 0; +static size_t size_for_1sec, size_for_led = 0; +static size_t maxavail = 0; +static uint64_t in_total = 0, in_prev = 0; +static uint64_t start_ms, last_ms; +static uint64_t timeout; + +Stream* logger; + +void error (const char* what) +{ + logger->printf("\r\nerror: %s after %ld minutes\r\nread idx: %d\r\nwrite idx: %d\r\ntotal: %ld\r\nlast read: %d\r\nmaxavail: %d\r\n", + what, (long)((millis() - start_ms) / 60000), in_idx, out_idx, (long)in_total, (int)local_receive_size, maxavail); + if (Serial.hasOverrun()) + logger->printf("overrun!\r\n"); + logger->printf("should be (size=%d idx=%d..%d):\r\n ", BUFFER_SIZE, in_idx, in_idx + local_receive_size - 1); + for (size_t i = in_idx; i < in_idx + local_receive_size; i++) + logger->printf("%02x(%c) ", buf[i], (unsigned char)((buf[i] > 31 && buf[i] < 128) ? buf[i] : '.')); + logger->print("\r\n\r\nis: "); + for (size_t i = 0; i < local_receive_size; i++) + logger->printf("%02x(%c) ", temp[i], (unsigned char)((temp[i] > 31 && temp[i] < 128) ? temp[i] : '.')); + logger->println("\r\n\r\n"); + + while (true) + delay(1000); +} + +void preinit() +{ + // (no C++ in function) + // disable wifi + ESP8266WiFiClass::preinitWiFiOff(); +} + +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + + Serial.begin(BAUD); + Serial.swap(); // RX=GPIO13 TX=GPIO15 + Serial.setRxBufferSize(SERIAL_SIZE_RX); + + // using HardwareSerial0 pins, + // so we can still log to the regular usbserial chips + SoftwareSerial* ss = new SoftwareSerial(3, 1); + ss->begin(SSBAUD); + logger = ss; + logger->println(); + logger->printf("\r\n\r\nOn Software Serial for logging\r\n"); + + int baud = Serial.baudRate(); + logger->printf(ESP.getFullVersion().c_str()); + logger->printf("\r\n\r\nBAUD: %d - CoreRxBuffer: %d bytes - TestBuffer: %d bytes\r\n", + baud, SERIAL_SIZE_RX, BUFFER_SIZE); + + size_for_1sec = baud / 10; // 8n1=10baudFor8bits + logger->printf("led changes state every %zd bytes (= 1 second)\r\n", size_for_1sec); + + // prepare send/compare buffer + for (size_t i = 0; i < sizeof buf; i++) + buf[i] = (uint8_t)i; + + // bind RX and TX + USC0(0) |= (1 << UCLBE); + + while (Serial.read() == -1); + if (Serial.hasOverrun()) + logger->print("overrun?\r\n"); + + timeout = (start_ms = last_ms = millis()) + TIMEOUT; + logger->println("setup done"); +} + +void loop() +{ + size_t maxlen = Serial.availableForWrite(); + // check remaining space in buffer + if (maxlen > BUFFER_SIZE - out_idx) + maxlen = BUFFER_SIZE - out_idx; + // check if not cycling more than buffer size relatively to input + size_t in_out = out_idx == in_idx ? + BUFFER_SIZE : + (in_idx + BUFFER_SIZE - out_idx - 1) % BUFFER_SIZE; + if (maxlen > in_out) + maxlen = in_out; + DEBUG(logger->printf("(aw%i/w%i", Serial.availableForWrite(), maxlen)); + size_t local_written_size = Serial.write(buf + out_idx, maxlen); + DEBUG(logger->printf(":w%i/aw%i/ar%i)\r\n", local_written_size, Serial.availableForWrite(), Serial.available())); + if (local_written_size > maxlen) + error("bad write"); + if ((out_idx += local_written_size) == BUFFER_SIZE) + out_idx = 0; + delay(0); + + DEBUG(logger->printf("----------\r\n")); + + if (Serial.hasOverrun()) + logger->printf("overrun!\r\n"); + + // receive data + maxlen = Serial.available(); + if (maxlen > maxavail) + maxavail = maxlen; + // check space in temp receive buffer + if (maxlen > BUFFER_SIZE - in_idx) + maxlen = BUFFER_SIZE - in_idx; + DEBUG(logger->printf("(ar%i/r%i", Serial.available(), maxlen)); + local_receive_size = Serial.readBytes(temp, maxlen); + DEBUG(logger->printf(":r%i/ar%i)\r\n", local_receive_size, Serial.available())); + if (local_receive_size > maxlen) + error("bad read"); + if (local_receive_size) + { + if (memcmp(buf + in_idx, temp, local_receive_size) != 0) + error("fail"); + if ((in_idx += local_receive_size) == BUFFER_SIZE) + in_idx = 0; + in_total += local_receive_size; + } + DEBUG(logger->printf("r(%d) ok\r\n", local_receive_size)); + + // say something on data every second + if ((size_for_led += local_written_size) >= size_for_1sec || millis() > timeout) + { + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + size_for_led = 0; + + if (in_prev == in_total) + error("receiving nothing?\r\n"); + + unsigned long now_ms = millis(); + int bwkbps_avg = ((((uint64_t)in_total) * 8000) / (now_ms - start_ms)) >> 10; + int bwkbps_now = (((in_total - in_prev) * 8000) / (now_ms - last_ms)) >> 10 ; + logger->printf("bwavg=%d bwnow=%d kbps maxavail=%i\r\n", bwkbps_avg, bwkbps_now, maxavail); + + in_prev = in_total; + timeout = (last_ms = now_ms) + TIMEOUT; + } +} From 40f237f10fc52ae6837446197ff88ee7d0fc62f3 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Wed, 5 Dec 2018 13:19:49 +0100 Subject: [PATCH 08/21] astyle --- .../examples/serialStress/serialStress.ino | 71 +++++++++++-------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/libraries/esp8266/examples/serialStress/serialStress.ino b/libraries/esp8266/examples/serialStress/serialStress.ino index b2c7df1bc6..53d4ce034b 100644 --- a/libraries/esp8266/examples/serialStress/serialStress.ino +++ b/libraries/esp8266/examples/serialStress/serialStress.ino @@ -3,7 +3,7 @@ Serial read/write/verify/benchmark Using internal loopback Using SoftwareSerial library for logging - + Sketch meant for debugging only Released to public domain */ @@ -32,33 +32,34 @@ static uint64_t timeout; Stream* logger; -void error (const char* what) -{ +void error(const char* what) { logger->printf("\r\nerror: %s after %ld minutes\r\nread idx: %d\r\nwrite idx: %d\r\ntotal: %ld\r\nlast read: %d\r\nmaxavail: %d\r\n", what, (long)((millis() - start_ms) / 60000), in_idx, out_idx, (long)in_total, (int)local_receive_size, maxavail); - if (Serial.hasOverrun()) + if (Serial.hasOverrun()) { logger->printf("overrun!\r\n"); + } logger->printf("should be (size=%d idx=%d..%d):\r\n ", BUFFER_SIZE, in_idx, in_idx + local_receive_size - 1); - for (size_t i = in_idx; i < in_idx + local_receive_size; i++) + for (size_t i = in_idx; i < in_idx + local_receive_size; i++) { logger->printf("%02x(%c) ", buf[i], (unsigned char)((buf[i] > 31 && buf[i] < 128) ? buf[i] : '.')); + } logger->print("\r\n\r\nis: "); - for (size_t i = 0; i < local_receive_size; i++) + for (size_t i = 0; i < local_receive_size; i++) { logger->printf("%02x(%c) ", temp[i], (unsigned char)((temp[i] > 31 && temp[i] < 128) ? temp[i] : '.')); + } logger->println("\r\n\r\n"); - while (true) + while (true) { delay(1000); + } } -void preinit() -{ +void preinit() { // (no C++ in function) // disable wifi ESP8266WiFiClass::preinitWiFiOff(); } -void setup() -{ +void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(BAUD); @@ -82,76 +83,86 @@ void setup() logger->printf("led changes state every %zd bytes (= 1 second)\r\n", size_for_1sec); // prepare send/compare buffer - for (size_t i = 0; i < sizeof buf; i++) + for (size_t i = 0; i < sizeof buf; i++) { buf[i] = (uint8_t)i; + } // bind RX and TX USC0(0) |= (1 << UCLBE); while (Serial.read() == -1); - if (Serial.hasOverrun()) + if (Serial.hasOverrun()) { logger->print("overrun?\r\n"); + } timeout = (start_ms = last_ms = millis()) + TIMEOUT; logger->println("setup done"); } -void loop() -{ +void loop() { size_t maxlen = Serial.availableForWrite(); // check remaining space in buffer - if (maxlen > BUFFER_SIZE - out_idx) + if (maxlen > BUFFER_SIZE - out_idx) { maxlen = BUFFER_SIZE - out_idx; + } // check if not cycling more than buffer size relatively to input size_t in_out = out_idx == in_idx ? BUFFER_SIZE : (in_idx + BUFFER_SIZE - out_idx - 1) % BUFFER_SIZE; - if (maxlen > in_out) + if (maxlen > in_out) { maxlen = in_out; + } DEBUG(logger->printf("(aw%i/w%i", Serial.availableForWrite(), maxlen)); size_t local_written_size = Serial.write(buf + out_idx, maxlen); DEBUG(logger->printf(":w%i/aw%i/ar%i)\r\n", local_written_size, Serial.availableForWrite(), Serial.available())); - if (local_written_size > maxlen) + if (local_written_size > maxlen) { error("bad write"); - if ((out_idx += local_written_size) == BUFFER_SIZE) + } + if ((out_idx += local_written_size) == BUFFER_SIZE) { out_idx = 0; + } delay(0); DEBUG(logger->printf("----------\r\n")); - if (Serial.hasOverrun()) + if (Serial.hasOverrun()) { logger->printf("overrun!\r\n"); + } // receive data maxlen = Serial.available(); - if (maxlen > maxavail) + if (maxlen > maxavail) { maxavail = maxlen; + } // check space in temp receive buffer - if (maxlen > BUFFER_SIZE - in_idx) + if (maxlen > BUFFER_SIZE - in_idx) { maxlen = BUFFER_SIZE - in_idx; + } DEBUG(logger->printf("(ar%i/r%i", Serial.available(), maxlen)); local_receive_size = Serial.readBytes(temp, maxlen); DEBUG(logger->printf(":r%i/ar%i)\r\n", local_receive_size, Serial.available())); - if (local_receive_size > maxlen) + if (local_receive_size > maxlen) { error("bad read"); - if (local_receive_size) - { - if (memcmp(buf + in_idx, temp, local_receive_size) != 0) + } + if (local_receive_size) { + if (memcmp(buf + in_idx, temp, local_receive_size) != 0) { error("fail"); - if ((in_idx += local_receive_size) == BUFFER_SIZE) + } + if ((in_idx += local_receive_size) == BUFFER_SIZE) { in_idx = 0; + } in_total += local_receive_size; } DEBUG(logger->printf("r(%d) ok\r\n", local_receive_size)); // say something on data every second - if ((size_for_led += local_written_size) >= size_for_1sec || millis() > timeout) - { + if ((size_for_led += local_written_size) >= size_for_1sec || millis() > timeout) { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); size_for_led = 0; - if (in_prev == in_total) + if (in_prev == in_total) { error("receiving nothing?\r\n"); + } unsigned long now_ms = millis(); int bwkbps_avg = ((((uint64_t)in_total) * 8000) / (now_ms - start_ms)) >> 10; From 3428144634a0d797709c8fa9c25db049b880a2c7 Mon Sep 17 00:00:00 2001 From: david gauchard <gauchard@laas.fr> Date: Wed, 5 Dec 2018 23:07:05 +0100 Subject: [PATCH 09/21] serial stress example: interactive keyboard, stop reading, overrun --- .../examples/serialStress/serialStress.ino | 82 +++++++++++-------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/libraries/esp8266/examples/serialStress/serialStress.ino b/libraries/esp8266/examples/serialStress/serialStress.ino index 53d4ce034b..7b25ff9f2f 100644 --- a/libraries/esp8266/examples/serialStress/serialStress.ino +++ b/libraries/esp8266/examples/serialStress/serialStress.ino @@ -21,6 +21,7 @@ uint8_t buf [BUFFER_SIZE]; uint8_t temp [BUFFER_SIZE]; +bool reading = true; static size_t out_idx = 0, in_idx = 0; static size_t local_receive_size = 0; @@ -33,20 +34,20 @@ static uint64_t timeout; Stream* logger; void error(const char* what) { - logger->printf("\r\nerror: %s after %ld minutes\r\nread idx: %d\r\nwrite idx: %d\r\ntotal: %ld\r\nlast read: %d\r\nmaxavail: %d\r\n", + logger->printf("\nerror: %s after %ld minutes\nread idx: %d\nwrite idx: %d\ntotal: %ld\nlast read: %d\nmaxavail: %d\n", what, (long)((millis() - start_ms) / 60000), in_idx, out_idx, (long)in_total, (int)local_receive_size, maxavail); if (Serial.hasOverrun()) { - logger->printf("overrun!\r\n"); + logger->printf("overrun!\n"); } - logger->printf("should be (size=%d idx=%d..%d):\r\n ", BUFFER_SIZE, in_idx, in_idx + local_receive_size - 1); + logger->printf("should be (size=%d idx=%d..%d):\n ", BUFFER_SIZE, in_idx, in_idx + local_receive_size - 1); for (size_t i = in_idx; i < in_idx + local_receive_size; i++) { logger->printf("%02x(%c) ", buf[i], (unsigned char)((buf[i] > 31 && buf[i] < 128) ? buf[i] : '.')); } - logger->print("\r\n\r\nis: "); + logger->print("\n\nis: "); for (size_t i = 0; i < local_receive_size; i++) { logger->printf("%02x(%c) ", temp[i], (unsigned char)((temp[i] > 31 && temp[i] < 128) ? temp[i] : '.')); } - logger->println("\r\n\r\n"); + logger->println("\n\n"); while (true) { delay(1000); @@ -72,15 +73,15 @@ void setup() { ss->begin(SSBAUD); logger = ss; logger->println(); - logger->printf("\r\n\r\nOn Software Serial for logging\r\n"); + logger->printf("\n\nOn Software Serial for logging\n"); int baud = Serial.baudRate(); logger->printf(ESP.getFullVersion().c_str()); - logger->printf("\r\n\r\nBAUD: %d - CoreRxBuffer: %d bytes - TestBuffer: %d bytes\r\n", + logger->printf("\n\nBAUD: %d - CoreRxBuffer: %d bytes - TestBuffer: %d bytes\n", baud, SERIAL_SIZE_RX, BUFFER_SIZE); size_for_1sec = baud / 10; // 8n1=10baudFor8bits - logger->printf("led changes state every %zd bytes (= 1 second)\r\n", size_for_1sec); + logger->printf("led changes state every %zd bytes (= 1 second)\n", size_for_1sec); // prepare send/compare buffer for (size_t i = 0; i < sizeof buf; i++) { @@ -92,7 +93,7 @@ void setup() { while (Serial.read() == -1); if (Serial.hasOverrun()) { - logger->print("overrun?\r\n"); + logger->print("overrun?\n"); } timeout = (start_ms = last_ms = millis()) + TIMEOUT; @@ -114,7 +115,7 @@ void loop() { } DEBUG(logger->printf("(aw%i/w%i", Serial.availableForWrite(), maxlen)); size_t local_written_size = Serial.write(buf + out_idx, maxlen); - DEBUG(logger->printf(":w%i/aw%i/ar%i)\r\n", local_written_size, Serial.availableForWrite(), Serial.available())); + DEBUG(logger->printf(":w%i/aw%i/ar%i)\n", local_written_size, Serial.availableForWrite(), Serial.available())); if (local_written_size > maxlen) { error("bad write"); } @@ -123,37 +124,40 @@ void loop() { } delay(0); - DEBUG(logger->printf("----------\r\n")); + DEBUG(logger->printf("----------\n")); if (Serial.hasOverrun()) { - logger->printf("overrun!\r\n"); + logger->printf("overrun!\n"); } - // receive data - maxlen = Serial.available(); - if (maxlen > maxavail) { - maxavail = maxlen; - } - // check space in temp receive buffer - if (maxlen > BUFFER_SIZE - in_idx) { - maxlen = BUFFER_SIZE - in_idx; - } - DEBUG(logger->printf("(ar%i/r%i", Serial.available(), maxlen)); - local_receive_size = Serial.readBytes(temp, maxlen); - DEBUG(logger->printf(":r%i/ar%i)\r\n", local_receive_size, Serial.available())); - if (local_receive_size > maxlen) { - error("bad read"); - } - if (local_receive_size) { - if (memcmp(buf + in_idx, temp, local_receive_size) != 0) { - error("fail"); + if (reading) + { + // receive data + maxlen = Serial.available(); + if (maxlen > maxavail) { + maxavail = maxlen; + } + // check space in temp receive buffer + if (maxlen > BUFFER_SIZE - in_idx) { + maxlen = BUFFER_SIZE - in_idx; } - if ((in_idx += local_receive_size) == BUFFER_SIZE) { - in_idx = 0; + DEBUG(logger->printf("(ar%i/r%i", Serial.available(), maxlen)); + local_receive_size = Serial.readBytes(temp, maxlen); + DEBUG(logger->printf(":r%i/ar%i)\n", local_receive_size, Serial.available())); + if (local_receive_size > maxlen) { + error("bad read"); } - in_total += local_receive_size; + if (local_receive_size) { + if (memcmp(buf + in_idx, temp, local_receive_size) != 0) { + error("fail"); + } + if ((in_idx += local_receive_size) == BUFFER_SIZE) { + in_idx = 0; + } + in_total += local_receive_size; + } + DEBUG(logger->printf("r(%d) ok\n", local_receive_size)); } - DEBUG(logger->printf("r(%d) ok\r\n", local_receive_size)); // say something on data every second if ((size_for_led += local_written_size) >= size_for_1sec || millis() > timeout) { @@ -161,15 +165,21 @@ void loop() { size_for_led = 0; if (in_prev == in_total) { - error("receiving nothing?\r\n"); + error("receiving nothing?\n"); } unsigned long now_ms = millis(); int bwkbps_avg = ((((uint64_t)in_total) * 8000) / (now_ms - start_ms)) >> 10; int bwkbps_now = (((in_total - in_prev) * 8000) / (now_ms - last_ms)) >> 10 ; - logger->printf("bwavg=%d bwnow=%d kbps maxavail=%i\r\n", bwkbps_avg, bwkbps_now, maxavail); + logger->printf("bwavg=%d bwnow=%d kbps maxavail=%i\n", bwkbps_avg, bwkbps_now, maxavail); in_prev = in_total; timeout = (last_ms = now_ms) + TIMEOUT; } + + if (logger->read() == 's') + { + logger->println("now stopping reading, keeping writing"); + reading = false; + } } From 882989ec2e36613be300980bfc9f1d8e47b56aeb Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 6 Dec 2018 16:06:27 +0100 Subject: [PATCH 10/21] serial device test: bandwidth & overrun --- tests/device/test_serial/test_serial.ino | 191 +++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 tests/device/test_serial/test_serial.ino diff --git a/tests/device/test_serial/test_serial.ino b/tests/device/test_serial/test_serial.ino new file mode 100644 index 0000000000..19481f91ff --- /dev/null +++ b/tests/device/test_serial/test_serial.ino @@ -0,0 +1,191 @@ +#include <BSTest.h> +BS_ENV_DECLARE(); + +// this is the serialStress.ino example, stripped down + +/* + Serial read/write/verify/benchmark + Using internal loopback + + Released to public domain +*/ + +#include <ESP8266WiFi.h> + +#define SSBAUD 115200 // console for humans +#define BAUD 3000000 // hardware serial stress test +#define BUFFER_SIZE 4096 // may be useless to use more than 2*SERIAL_SIZE_RX +#define SERIAL_SIZE_RX 1024 // Serial.setRxBufferSize() + +#define TIMEOUT 5000 +#define DEBUG(x...) //x + +uint8_t buf [BUFFER_SIZE]; +uint8_t temp [BUFFER_SIZE]; +bool reading = true; +bool overrun = false; + +static size_t out_idx = 0, in_idx = 0; +static size_t local_receive_size = 0; +static size_t size_for_1sec, size_for_led = 0; +static size_t maxavail = 0; +static uint64_t in_total = 0, in_prev = 0; +static uint64_t start_ms, last_ms; +static uint64_t timeout; + +void preinit() { + // (no C++ in function) + // disable wifi + ESP8266WiFiClass::preinitWiFiOff(); +} + +void setup() +{ + Serial.begin(SSBAUD); + + int baud = BAUD; + size_for_1sec = baud / 10; // 8n1=10baudFor8bits + //Serial.printf(ESP.getFullVersion().c_str()); + //Serial.printf("\n\nBAUD: %d - CoreRxBuffer: %d bytes - TestBuffer: %d bytes\n", + // baud, SERIAL_SIZE_RX, BUFFER_SIZE); + + //Serial.printf("led changes state every %zd bytes (= 1 second)\n", size_for_1sec); + //Serial.printf("press 's' to stop reading, not writing (induces overrun)\n"); + + BS_RUN(Serial); +} + +void test_setup() +{ + Serial.begin(BAUD); + + // bind RX and TX + USC0(0) |= (1 << UCLBE); + + Serial.flush(); + while (Serial.read() != -1); + timeout = (start_ms = last_ms = millis()) + TIMEOUT; +} + +void test_setdown () +{ + // unbind RX and TX + Serial.flush(); + USC0(0) &= ~(1 << UCLBE); + while (Serial.read() != -1); + Serial.begin(SSBAUD); +} + +int bwkbps_avg = 0; + +bool test_loop () +{ + size_t maxlen = Serial.availableForWrite(); + // check remaining space in buffer + if (maxlen > BUFFER_SIZE - out_idx) { + maxlen = BUFFER_SIZE - out_idx; + } + // check if not cycling more than buffer size relatively to input + size_t in_out = out_idx == in_idx ? + BUFFER_SIZE : + (in_idx + BUFFER_SIZE - out_idx - 1) % BUFFER_SIZE; + if (maxlen > in_out) { + maxlen = in_out; + } + size_t local_written_size = Serial.write(buf + out_idx, maxlen); + if (local_written_size > maxlen) { + return false; + } + if ((out_idx += local_written_size) == BUFFER_SIZE) { + out_idx = 0; + } + delay(0); + + if (Serial.hasOverrun()) { + overrun = true; + } + if (Serial.hasRxError()) { + } + + if (reading) + { + // receive data + maxlen = Serial.available(); + if (maxlen > maxavail) { + maxavail = maxlen; + } + // check space in temp receive buffer + if (maxlen > BUFFER_SIZE - in_idx) { + maxlen = BUFFER_SIZE - in_idx; + } + local_receive_size = Serial.readBytes(temp, maxlen); + if (local_receive_size > maxlen) { + return false; + } + if (local_receive_size) { + if (memcmp(buf + in_idx, temp, local_receive_size) != 0) { + return false; + } + if ((in_idx += local_receive_size) == BUFFER_SIZE) { + in_idx = 0; + } + in_total += local_receive_size; + } + } + + // say something on data every second + if ((size_for_led += local_written_size) >= size_for_1sec || millis() > timeout) { + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + size_for_led = 0; + + if (in_prev == in_total) { + return false; + } + + unsigned long now_ms = millis(); + bwkbps_avg = ((((uint64_t)in_total) * 8000) / (now_ms - start_ms)) >> 10; + //bwkbps_now = (((in_total - in_prev) * 8000) / (now_ms - last_ms)) >> 10 ; + + in_prev = in_total; + timeout = (last_ms = now_ms) + TIMEOUT; + } + + if (millis() > 5000) + { + reading = false; + } + if (millis() > 6000) + { + return false; + } + + return true; +} + +TEST_CASE("bandwidth and overrun", "[serial]") +{ + overrun = false; + bwkbps_avg = 0; + CHECK(overrun == false); + CHECK(bwkbps_avg == 0); + + // let serial flush its BS output before flushing and switching to 3MBPS + delay(100); + + test_setup(); + while (test_loop()); + test_setdown(); + + Serial.printf("bandwidth = %d kbps - overrun=%d\n", bwkbps_avg, overrun); + + // BAUD*10/8/1000 =>kbps *9/10 => 90% at least + CHECK(bwkbps_avg > ((((BAUD*8/10)/1000)*9)/10)); + CHECK(overrun == true); + + while (Serial.read() != -1); + Serial.flush(); +} + +void loop () +{ +} From 3ec2a6057037112d68424962cb985295541c0aef Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 6 Dec 2018 16:07:08 +0100 Subject: [PATCH 11/21] update + HardwareSerial::hasError() --- cores/esp8266/HardwareSerial.h | 5 +++ cores/esp8266/uart.c | 45 ++++++++++++++----- cores/esp8266/uart.h | 1 + .../examples/serialStress/serialStress.ino | 5 ++- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index 54d600ccca..f76e804319 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -196,6 +196,11 @@ class HardwareSerial: public Stream return uart_has_overrun(_uart); } + bool hasRxError(void) + { + return uart_has_rx_error(_uart); + } + void startDetectBaudrate(); unsigned long testBaudrate(); diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index d47bc77840..9e640a3dfd 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -47,7 +47,7 @@ #include "user_interface.h" #include "uart_register.h" -const char overrun_str [] PROGMEM STORE_ATTR = "uart input full!\r\n"; +//const char overrun_str [] PROGMEM STORE_ATTR = "uart input full!\r\n"; static int s_uart_debug_nr = UART0; @@ -65,7 +65,8 @@ struct uart_ int baud_rate; bool rx_enabled; bool tx_enabled; - bool overrun; + bool rx_overrun; + bool rx_error; uint8_t rx_pin; uint8_t tx_pin; struct uart_rx_buffer_ * rx_buffer; @@ -125,10 +126,10 @@ uart_rx_copy_fifo_to_buffer_unsafe(uart_t* uart) size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size; if(nextPos == rx_buffer->rpos) { - if (!uart->overrun) + if (!uart->rx_overrun) { - uart->overrun = true; - os_printf_plus(overrun_str); + uart->rx_overrun = true; + //os_printf_plus(overrun_str); } // a choice has to be made here, @@ -302,12 +303,15 @@ uart_isr(void * arg) if(usis & (1 << UIFF)) uart_rx_copy_fifo_to_buffer_unsafe(uart); - if((usis & (1 << UIOF)) && !uart->overrun) + if((usis & (1 << UIOF)) && !uart->rx_overrun) { - uart->overrun = true; -// os_printf_plus(overrun_str); + uart->rx_overrun = true; + //os_printf_plus(overrun_str); } + if (usis & ((1 << UIFR) | (1 << UIPE) | (1 << UITO))) + uart->rx_error = true; + USIC(uart->uart_nr) = usis; } @@ -331,7 +335,12 @@ uart_start_isr(uart_t* uart) USC1(uart->uart_nr) = (INTRIGG << UCFFT); USIC(uart->uart_nr) = 0xffff; //was: USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIFR) | (1 << UITO); - USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIOF); + // UIFF: rx fifo full + // UIOF: rx fifo overflow (=overrun) + // UIFR: frame error + // UIPE: parity error + // UITO: rx fifo timeout + USIE(uart->uart_nr) = (1 << UIFF) | (1 << UIOF) | (1 << UIFR) | (1 << UIPE) | (1 << UITO); ETS_UART_INTR_ATTACH(uart_isr, (void *)uart); ETS_UART_INTR_ENABLE(); } @@ -474,7 +483,8 @@ uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx return NULL; uart->uart_nr = uart_nr; - uart->overrun = false; + uart->rx_overrun = false; + uart->rx_error = false; switch(uart->uart_nr) { @@ -737,11 +747,22 @@ uart_rx_enabled(uart_t* uart) bool uart_has_overrun (uart_t* uart) { - if (uart == NULL || !uart->overrun) + if (uart == NULL || !uart->rx_overrun) + return false; + + // clear flag + uart->rx_overrun = false; + return true; +} + +bool +uart_has_rx_error (uart_t* uart) +{ + if (uart == NULL || !uart->rx_error) return false; // clear flag - uart->overrun = false; + uart->rx_error = false; return true; } diff --git a/cores/esp8266/uart.h b/cores/esp8266/uart.h index 8e9e35b71f..7f9dce0f0a 100644 --- a/cores/esp8266/uart.h +++ b/cores/esp8266/uart.h @@ -139,6 +139,7 @@ void uart_wait_tx_empty(uart_t* uart); void uart_flush(uart_t* uart); bool uart_has_overrun (uart_t* uart); // returns then clear overrun flag +bool uart_has_rx_error (uart_t* uart); // returns then clear rxerror flag void uart_set_debug(int uart_nr); int uart_get_debug(); diff --git a/libraries/esp8266/examples/serialStress/serialStress.ino b/libraries/esp8266/examples/serialStress/serialStress.ino index 7b25ff9f2f..6d1bcbdc65 100644 --- a/libraries/esp8266/examples/serialStress/serialStress.ino +++ b/libraries/esp8266/examples/serialStress/serialStress.ino @@ -127,7 +127,10 @@ void loop() { DEBUG(logger->printf("----------\n")); if (Serial.hasOverrun()) { - logger->printf("overrun!\n"); + logger->printf("rx overrun!\n"); + } + if (Serial.hasRxError()) { + logger->printf("rx error!\n"); } if (reading) From a38f9d86693d79e676ffe79a3afb91657d243e9b Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 6 Dec 2018 16:11:50 +0100 Subject: [PATCH 12/21] interactive overrun in example --- .../serialStress.ino => SerialStress/SerialStress.ino} | 1 + 1 file changed, 1 insertion(+) rename libraries/esp8266/examples/{serialStress/serialStress.ino => SerialStress/SerialStress.ino} (98%) diff --git a/libraries/esp8266/examples/serialStress/serialStress.ino b/libraries/esp8266/examples/SerialStress/SerialStress.ino similarity index 98% rename from libraries/esp8266/examples/serialStress/serialStress.ino rename to libraries/esp8266/examples/SerialStress/SerialStress.ino index 6d1bcbdc65..eafa425876 100644 --- a/libraries/esp8266/examples/serialStress/serialStress.ino +++ b/libraries/esp8266/examples/SerialStress/SerialStress.ino @@ -82,6 +82,7 @@ void setup() { size_for_1sec = baud / 10; // 8n1=10baudFor8bits 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"); // prepare send/compare buffer for (size_t i = 0; i < sizeof buf; i++) { From 6b7771548584890349b1de9970a866c970329527 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 6 Dec 2018 16:12:35 +0100 Subject: [PATCH 13/21] astyle --- libraries/esp8266/examples/SerialStress/SerialStress.ino | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/esp8266/examples/SerialStress/SerialStress.ino b/libraries/esp8266/examples/SerialStress/SerialStress.ino index eafa425876..7b13d6eb74 100644 --- a/libraries/esp8266/examples/SerialStress/SerialStress.ino +++ b/libraries/esp8266/examples/SerialStress/SerialStress.ino @@ -134,8 +134,7 @@ void loop() { logger->printf("rx error!\n"); } - if (reading) - { + if (reading) { // receive data maxlen = Serial.available(); if (maxlen > maxavail) { @@ -181,8 +180,7 @@ void loop() { timeout = (last_ms = now_ms) + TIMEOUT; } - if (logger->read() == 's') - { + if (logger->read() == 's') { logger->println("now stopping reading, keeping writing"); reading = false; } From b63926142f074a21f0ebc761117a08f353e6da0e Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 6 Dec 2018 17:06:12 +0100 Subject: [PATCH 14/21] Test using @plerup's SoftwareSerial as submodule (tag 3.4.1) --- .gitmodules | 3 +++ libraries/SoftwareSerial | 1 + 2 files changed, 4 insertions(+) create mode 160000 libraries/SoftwareSerial diff --git a/.gitmodules b/.gitmodules index 2703cecb68..6ccf7f096b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "tools/sdk/ssl/bearssl"] path = tools/sdk/ssl/bearssl url = https://github.com/earlephilhower/bearssl-esp8266 +[submodule "libraries/SoftwareSerial"] + path = libraries/SoftwareSerial + url = https://github.com/plerup/espsoftwareserial.git diff --git a/libraries/SoftwareSerial b/libraries/SoftwareSerial new file mode 160000 index 0000000000..5378868de7 --- /dev/null +++ b/libraries/SoftwareSerial @@ -0,0 +1 @@ +Subproject commit 5378868de76e1a38d34e0fc888d26e3612a5497d From 40d123714afa57fb6eb8821e270a298f0a744b52 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Thu, 6 Dec 2018 23:37:50 +0100 Subject: [PATCH 15/21] update upstream ref (fix warning) --- libraries/SoftwareSerial | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/SoftwareSerial b/libraries/SoftwareSerial index 5378868de7..23ae000cb2 160000 --- a/libraries/SoftwareSerial +++ b/libraries/SoftwareSerial @@ -1 +1 @@ -Subproject commit 5378868de76e1a38d34e0fc888d26e3612a5497d +Subproject commit 23ae000cb2cf4d5823a2744f6b8ae831575ff135 From c48b54f0b7bbe77b323c18a39715b28bece76a81 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Fri, 7 Dec 2018 00:53:58 +0100 Subject: [PATCH 16/21] host mock uart/read(buf,size) --- tests/host/common/MockSerial.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/host/common/MockSerial.cpp b/tests/host/common/MockSerial.cpp index 4aa097a0cd..8c2798dba0 100644 --- a/tests/host/common/MockSerial.cpp +++ b/tests/host/common/MockSerial.cpp @@ -109,4 +109,11 @@ size_t uart_write (uart_t* uart, const char* buf, size_t size) return write(1, buf, size); } +size_t uart_read(uart_t* uart, char* userbuffer, size_t usersize) +{ + ///XXXTODO + (void)uart; + return read(0, userbuffer, usersize); +} + } // extern "C" From 18a189f6708c6fb87f17ae2277e32a006035351d Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Fri, 7 Dec 2018 01:05:39 +0100 Subject: [PATCH 17/21] reset style changes in submodules before style diff --- tests/common.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/common.sh b/tests/common.sh index 5fbe245060..e9fa151458 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -248,6 +248,9 @@ function check_examples_style() --suffix=none \ --options=$TRAVIS_BUILD_DIR/tests/examples_style.conf {} \; + # we have no control over submodules + git submodule foreach --recursive git reset --hard + git diff --exit-code -- $TRAVIS_BUILD_DIR/libraries echo -e "travis_fold:end:check_examples_style" From fb25c8d7c9f3cecc6510e2c7fdd73c90cfb453a6 Mon Sep 17 00:00:00 2001 From: david gauchard <gauchard@laas.fr> Date: Sat, 8 Dec 2018 22:52:51 +0100 Subject: [PATCH 18/21] update build_boards_manager_package.sh for submodules --- package/build_boards_manager_package.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/package/build_boards_manager_package.sh b/package/build_boards_manager_package.sh index 3da5ef8ffe..42c088e8fa 100755 --- a/package/build_boards_manager_package.sh +++ b/package/build_boards_manager_package.sh @@ -16,6 +16,8 @@ else plain_ver=$ver fi +set -e + package_name=esp8266-$ver echo "Version: $ver" echo "Package name: $package_name" @@ -44,10 +46,20 @@ srcdir=$PWD rm -rf package/versions/$ver mkdir -p $outdir +# Get submodules +modules=libraries/SoftwareSerial +for mod in $modules; do + echo "refreshing submodule: $mod" + git submodule update --init -- $mod + (cd $mod && git reset --hard) +done +echo "done with submodules" + # Some files should be excluded from the package cat << EOF > exclude.txt .git .gitignore +.gitmodules .travis.yml package doc @@ -58,15 +70,6 @@ git ls-files --other --directory >> exclude.txt rsync -a --exclude-from 'exclude.txt' $srcdir/ $outdir/ rm exclude.txt -# Get additional libraries (TODO: add them as git submodule or subtree?) - -# SoftwareSerial library -curl -L -o SoftwareSerial.zip https://github.com/plerup/espsoftwareserial/archive/3.4.1.zip -unzip -q SoftwareSerial.zip -rm -rf SoftwareSerial.zip -mv espsoftwareserial-* SoftwareSerial -mv SoftwareSerial $outdir/libraries - # For compatibility, on OS X we need GNU sed which is usually called 'gsed' if [ "$(uname)" == "Darwin" ]; then SED=gsed @@ -154,3 +157,5 @@ python ../../merge_packages.py $new_json $old_json >tmp && mv tmp $new_json && r popd popd + +echo "All done" From cbd8b449ee261fec11f765a79bd826fb9a8e851b Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Mon, 10 Dec 2018 10:15:01 +0100 Subject: [PATCH 19/21] trigger CI (removing space) --- cores/esp8266/uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp8266/uart.c b/cores/esp8266/uart.c index 9e640a3dfd..e16b309df0 100644 --- a/cores/esp8266/uart.c +++ b/cores/esp8266/uart.c @@ -51,7 +51,7 @@ static int s_uart_debug_nr = UART0; -struct uart_rx_buffer_ +struct uart_rx_buffer_ { size_t size; size_t rpos; From 99fcfdacea379c52106fb8b78356c68924d931a6 Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Mon, 10 Dec 2018 11:46:13 +0100 Subject: [PATCH 20/21] cannot reproduce locally the CI issue, setting bash -x option to get live trace --- package/build_boards_manager_package.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package/build_boards_manager_package.sh b/package/build_boards_manager_package.sh index 42c088e8fa..b1fe72357e 100755 --- a/package/build_boards_manager_package.sh +++ b/package/build_boards_manager_package.sh @@ -1,6 +1,8 @@ #!/bin/bash # +set -x + # Extract next version from platform.txt next=`sed -n -E 's/version=([0-9.]+)/\1/p' ../platform.txt` From 6234fe02dccf5adcedf693fc677ac4d68904bb0c Mon Sep 17 00:00:00 2001 From: David Gauchard <gauchard@laas.fr> Date: Mon, 10 Dec 2018 12:28:38 +0100 Subject: [PATCH 21/21] remove previously added (in this PR) 'set -e' in package builder (passes local tests, not real CI) script-comment new recipe.hooks.core.prebuild.3 (along with already commented .1 and .2) moved CI package test to be first on the test list remove 'set -x', wish me luck --- .travis.yml | 4 ++-- package/build_boards_manager_package.sh | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a992a5094e..732b21b126 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,8 @@ cache: matrix: include: + - env: + - BUILD_TYPE=package - env: - BUILD_TYPE=build_even - env: @@ -22,8 +24,6 @@ matrix: - BUILD_TYPE=platformio_odd - env: - BUILD_TYPE=docs - - env: - - BUILD_TYPE=package - env: - BUILD_TYPE=host_tests - env: diff --git a/package/build_boards_manager_package.sh b/package/build_boards_manager_package.sh index b1fe72357e..9e4468c58b 100755 --- a/package/build_boards_manager_package.sh +++ b/package/build_boards_manager_package.sh @@ -1,7 +1,7 @@ #!/bin/bash # -set -x +#set -x # Extract next version from platform.txt next=`sed -n -E 's/version=([0-9.]+)/\1/p' ../platform.txt` @@ -18,7 +18,8 @@ else plain_ver=$ver fi -set -e +# 'set -e' breaks CI but not local tests +#set -e package_name=esp8266-$ver echo "Version: $ver" @@ -88,6 +89,7 @@ $SED 's/tools.esptool.path={runtime.platform.path}\/tools\/esptool/tools.esptool $SED 's/tools.mkspiffs.path={runtime.platform.path}\/tools\/mkspiffs/tools.mkspiffs.path=\{runtime.tools.mkspiffs.path\}/g' |\ $SED 's/recipe.hooks.core.prebuild.1.pattern.*//g' |\ $SED 's/recipe.hooks.core.prebuild.2.pattern.*//g' |\ +$SED 's/recipe.hooks.core.prebuild.3.pattern.*//g' |\ $SED "s/version=.*/version=$ver/g" |\ $SED -E "s/name=([a-zA-Z0-9\ -]+).*/name=\1($ver)/g"\ > $outdir/platform.txt