From dad901797cc311f74d8020d2eb41180ecf759f15 Mon Sep 17 00:00:00 2001 From: gralco Date: Mon, 15 Feb 2016 08:51:33 -0700 Subject: [PATCH] Ensure that the rx_buffer does not truncate G-Code and tell the host if it does (once) Conflicts: Marlin/MarlinSerial.cpp Report that the RX buffer was filled once Ring buffer overflow also checks for \r and : nonsense that will be squashed Conflicts: Marlin/Marlin.h Marlin/MarlinSerial.cpp Marlin/Marlin_main.cpp --- Marlin/Marlin.h | 2 ++ Marlin/MarlinSerial.cpp | 49 +++++++++++++++++++++++++++++------------ Marlin/Marlin_main.cpp | 12 ++++++++++ Marlin/language.h | 1 + 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 8819b3fb8fe9..64a96c4d88fc 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -268,6 +268,7 @@ inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); } #define CRITICAL_SECTION_END SREG = _sreg; #endif +extern boolean comment_mode; extern bool axis_relative_modes[]; extern int feedrate_multiplier; extern bool volumetric_enabled; @@ -276,6 +277,7 @@ extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in m extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner extern float current_position[NUM_AXIS]; extern float home_offset[3]; // axis[n].home_offset +extern bool rxbuf_filled; extern float min_pos[3]; // axis[n].min_pos extern float max_pos[3]; // axis[n].max_pos extern bool axis_known_position[3]; // axis[n].is_known diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp index e6362fc7c78c..61049ba86922 100644 --- a/Marlin/MarlinSerial.cpp +++ b/Marlin/MarlinSerial.cpp @@ -40,20 +40,41 @@ ring_buffer rx_buffer = { { 0 }, 0, 0 }; #endif -FORCE_INLINE void store_char(unsigned char c) { - CRITICAL_SECTION_START; - uint8_t h = rx_buffer.head; - uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1); - - // if we should be storing the received character into the location - // just before the tail (meaning that the head would advance to the - // current location of the tail), we're about to overflow the buffer - // and so we don't write the character or advance the head. - if (i != rx_buffer.tail) { - rx_buffer.buffer[h] = c; - rx_buffer.head = i; - } - CRITICAL_SECTION_END; +bool rxbuf_filled = false; + +FORCE_INLINE void store_char(unsigned char c) +{ + static bool overflow = false; + if(overflow && !(c == '\n' || c == '\r' || (c == ':' && comment_mode == false))) + return; + else if(overflow && (c == '\n' || c == '\r' || (c == ':' && comment_mode == false))) + { + overflow = false; + return; + } + + int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we need to move the head back to the end of the previous line. + if (i != rx_buffer.tail) { + rx_buffer.buffer[rx_buffer.head] = c; + rx_buffer.head = i; + } + else { + overflow = true; + i = (uint8_t)(rx_buffer.head - 1) % RX_BUFFER_SIZE; + for(; !(rx_buffer.buffer[i] == '\n' || + rx_buffer.buffer[i] == '\r' || + (rx_buffer.buffer[i] == ':' && comment_mode != true)) && + rx_buffer.head != rx_buffer.tail; rx_buffer.head = i) + i = (uint8_t)(rx_buffer.head - 1) % RX_BUFFER_SIZE; + rx_buffer.head = (uint8_t)(i + 1) % RX_BUFFER_SIZE;; + if(!rxbuf_filled) + rxbuf_filled = true; + } } diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index edc36914c3f5..ca27a6bbee4e 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -437,6 +437,7 @@ static bool send_ok[BUFSIZE]; #endif #if ENABLED(HOST_KEEPALIVE_FEATURE) +boolean comment_mode = false; // States for managing Marlin and host communication // Marlin sends messages if blocked or busy @@ -967,6 +968,7 @@ void get_command() { // Add the command to the queue _enqueuecommand(serial_line_buffer, true); + rxbuf_filled = false; } else if (serial_count >= MAX_CMD_SIZE - 1) { // Keep fetching, but ignore normal characters beyond the max length @@ -7165,6 +7167,16 @@ void plan_arc( */ } + static bool reportrx_once = true; + if(rxbuf_filled && reportrx_once) + { + SERIAL_ERROR_START; + SERIAL_ERRORPGM(MSG_ERR_RXBUF_FULL); + reportrx_once = false; + } + else if(!rxbuf_filled) + reportrx_once = true; + #endif // SCARA #if ENABLED(TEMP_STAT_LEDS) diff --git a/Marlin/language.h b/Marlin/language.h index 1b82ec314c83..ae4b5306f209 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -137,6 +137,7 @@ #define MSG_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: " #define MSG_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: " #define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No Line Number with checksum, Last Line: " +#define MSG_ERR_RXBUF_FULL "RXbuf full" #define MSG_FILE_PRINTED "Done printing file" #define MSG_BEGIN_FILE_LIST "Begin file list" #define MSG_END_FILE_LIST "End file list"