From 9e004a94963771167bb3f5d6fa51ccd671a27a19 Mon Sep 17 00:00:00 2001 From: X-Ryl669 Date: Fri, 29 Jan 2021 02:59:16 +0100 Subject: [PATCH] Optimize serial output code for size (#20911) --- Marlin/src/core/macros.h | 1 + Marlin/src/core/serial_base.h | 26 +++++++++++++------------- Marlin/src/core/serial_hook.h | 24 ++++++++++++++---------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index a0ccebc078..dcc688ae29 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -53,6 +53,7 @@ #define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__ #define FORCE_INLINE __attribute__((always_inline)) inline +#define NO_INLINE __attribute__((noinline)) #define _UNUSED __attribute__((unused)) #define _O0 __attribute__((optimize("O0"))) #define _Os __attribute__((optimize("Os"))) diff --git a/Marlin/src/core/serial_base.h b/Marlin/src/core/serial_base.h index b60e3b5788..220ccae831 100644 --- a/Marlin/src/core/serial_base.h +++ b/Marlin/src/core/serial_base.h @@ -78,23 +78,23 @@ struct SerialBase { FORCE_INLINE void write(const char* str) { while (*str) write(*str++); } FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); } FORCE_INLINE void print(const char* str) { write(str); } - FORCE_INLINE void print(char c, int base = 0) { print((long)c, base); } - FORCE_INLINE void print(unsigned char c, int base = 0) { print((unsigned long)c, base); } - FORCE_INLINE void print(int c, int base = DEC) { print((long)c, base); } - FORCE_INLINE void print(unsigned int c, int base = DEC) { print((unsigned long)c, base); } + NO_INLINE void print(char c, int base = 0) { print((long)c, base); } + NO_INLINE void print(unsigned char c, int base = 0) { print((unsigned long)c, base); } + NO_INLINE void print(int c, int base = DEC) { print((long)c, base); } + NO_INLINE void print(unsigned int c, int base = DEC) { print((unsigned long)c, base); } void print(long c, int base = DEC) { if (!base) write(c); write((const uint8_t*)"-", c < 0); printNumber(c < 0 ? -c : c, base); } void print(unsigned long c, int base = DEC) { printNumber(c, base); } void print(double c, int digits = 2) { printFloat(c, digits); } - FORCE_INLINE void println(const char s[]) { print(s); println(); } - FORCE_INLINE void println(char c, int base = 0) { print(c, base); println(); } - FORCE_INLINE void println(unsigned char c, int base = 0) { print(c, base); println(); } - FORCE_INLINE void println(int c, int base = DEC) { print(c, base); println(); } - FORCE_INLINE void println(unsigned int c, int base = DEC) { print(c, base); println(); } - FORCE_INLINE void println(long c, int base = DEC) { print(c, base); println(); } - FORCE_INLINE void println(unsigned long c, int base = DEC) { print(c, base); println(); } - FORCE_INLINE void println(double c, int digits = 2) { print(c, digits); println(); } - void println() { write("\r\n"); } + NO_INLINE void println(const char s[]) { print(s); println(); } + NO_INLINE void println(char c, int base = 0) { print(c, base); println(); } + NO_INLINE void println(unsigned char c, int base = 0) { print(c, base); println(); } + NO_INLINE void println(int c, int base = DEC) { print(c, base); println(); } + NO_INLINE void println(unsigned int c, int base = DEC) { print(c, base); println(); } + NO_INLINE void println(long c, int base = DEC) { print(c, base); println(); } + NO_INLINE void println(unsigned long c, int base = DEC) { print(c, base); println(); } + NO_INLINE void println(double c, int digits = 2) { print(c, digits); println(); } + NO_INLINE void println() { write('\r'); write('\n'); } // Print a number with the given base void printNumber(unsigned long n, const uint8_t base) { diff --git a/Marlin/src/core/serial_hook.h b/Marlin/src/core/serial_hook.h index 17cf8bdd7d..e14b821a9c 100644 --- a/Marlin/src/core/serial_hook.h +++ b/Marlin/src/core/serial_hook.h @@ -61,7 +61,7 @@ struct ConditionalSerial : public SerialBase< ConditionalSerial > { bool & condition; SerialT & out; - size_t write(uint8_t c) { if (condition) return out.write(c); return 0; } + NO_INLINE size_t write(uint8_t c) { if (condition) return out.write(c); return 0; } void flush() { if (condition) out.flush(); } void begin(long br) { out.begin(br); } void end() { out.end(); } @@ -83,7 +83,7 @@ struct ForwardSerial : public SerialBase< ForwardSerial > { typedef SerialBase< ForwardSerial > BaseClassT; SerialT & out; - size_t write(uint8_t c) { return out.write(c); } + NO_INLINE size_t write(uint8_t c) { return out.write(c); } void flush() { out.flush(); } void begin(long br) { out.begin(br); } void end() { out.end(); } @@ -111,12 +111,12 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial >, public Seria EndOfMessageHook eofHook; void * userPointer; - size_t write(uint8_t c) { + NO_INLINE size_t write(uint8_t c) { if (writeHook) writeHook(userPointer, c); return SerialT::write(c); } - void msgDone() { + NO_INLINE void msgDone() { if (eofHook) eofHook(userPointer); } @@ -130,7 +130,11 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial >, public Seria using BaseClassT::print; using BaseClassT::println; - + + // Underlying implementation might use Arduino's bool operator + bool connected() { + return Private::HasMember_connected::value ? CALL_IF_EXISTS(bool, static_cast(this), connected) : static_cast(this)->operator bool(); + } void setHook(WriteHook writeHook = 0, EndOfMessageHook eofHook = 0, void * userPointer = 0) { // Order is important here as serial code can be called inside interrupts @@ -165,13 +169,13 @@ struct MultiSerial : public SerialBase< MultiSerial AllMask = FirstOutputMask | SecondOutputMask, }; - size_t write(uint8_t c) { + NO_INLINE size_t write(uint8_t c) { size_t ret = 0; if (portMask & FirstOutputMask) ret = serial0.write(c); if (portMask & SecondOutputMask) ret = serial1.write(c) | ret; return ret; } - void msgDone() { + NO_INLINE void msgDone() { if (portMask & FirstOutputMask) serial0.msgDone(); if (portMask & SecondOutputMask) serial1.msgDone(); } @@ -182,7 +186,7 @@ struct MultiSerial : public SerialBase< MultiSerial default: return false; } } - int read(uint8_t index) { + NO_INLINE int read(uint8_t index) { switch(index) { case 0 + offset: return serial0.read(); case 1 + offset: return serial1.read(); @@ -208,11 +212,11 @@ struct MultiSerial : public SerialBase< MultiSerial using BaseClassT::read; // Redirect flush - void flush() { + NO_INLINE void flush() { if (portMask & FirstOutputMask) serial0.flush(); if (portMask & SecondOutputMask) serial1.flush(); } - void flushTX() { + NO_INLINE void flushTX() { if (portMask & FirstOutputMask) CALL_IF_EXISTS(void, &serial0, flushTX); if (portMask & SecondOutputMask) CALL_IF_EXISTS(void, &serial1, flushTX); }