Browse Source

Optimize serial output code for size (#20911)

X-Ryl669 4 years ago
parent
commit
9e004a9496
No account linked to committer's email address
3 changed files with 28 additions and 23 deletions
  1. 1
    0
      Marlin/src/core/macros.h
  2. 13
    13
      Marlin/src/core/serial_base.h
  3. 14
    10
      Marlin/src/core/serial_hook.h

+ 1
- 0
Marlin/src/core/macros.h View File

@@ -53,6 +53,7 @@
53 53
 
54 54
 #define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
55 55
 #define  FORCE_INLINE  __attribute__((always_inline)) inline
56
+#define NO_INLINE      __attribute__((noinline))
56 57
 #define _UNUSED      __attribute__((unused))
57 58
 #define _O0          __attribute__((optimize("O0")))
58 59
 #define _Os          __attribute__((optimize("Os")))

+ 13
- 13
Marlin/src/core/serial_base.h View File

@@ -78,23 +78,23 @@ struct SerialBase {
78 78
   FORCE_INLINE void write(const char* str)                    { while (*str) write(*str++); }
79 79
   FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
80 80
   FORCE_INLINE void print(const char* str)                    { write(str); }
81
-  FORCE_INLINE void print(char c, int base = 0)               { print((long)c, base); }
82
-  FORCE_INLINE void print(unsigned char c, int base = 0)      { print((unsigned long)c, base); }
83
-  FORCE_INLINE void print(int c, int base = DEC)              { print((long)c, base); }
84
-  FORCE_INLINE void print(unsigned int c, int base = DEC)     { print((unsigned long)c, base); }
81
+  NO_INLINE void print(char c, int base = 0)               { print((long)c, base); }
82
+  NO_INLINE void print(unsigned char c, int base = 0)      { print((unsigned long)c, base); }
83
+  NO_INLINE void print(int c, int base = DEC)              { print((long)c, base); }
84
+  NO_INLINE void print(unsigned int c, int base = DEC)     { print((unsigned long)c, base); }
85 85
   void print(long c, int base = DEC)            { if (!base) write(c); write((const uint8_t*)"-", c < 0); printNumber(c < 0 ? -c : c, base); }
86 86
   void print(unsigned long c, int base = DEC)   { printNumber(c, base); }
87 87
   void print(double c, int digits = 2)          { printFloat(c, digits); }
88 88
 
89
-  FORCE_INLINE void println(const char s[])                  { print(s); println(); }
90
-  FORCE_INLINE void println(char c, int base = 0)            { print(c, base); println(); }
91
-  FORCE_INLINE void println(unsigned char c, int base = 0)   { print(c, base); println(); }
92
-  FORCE_INLINE void println(int c, int base = DEC)           { print(c, base); println(); }
93
-  FORCE_INLINE void println(unsigned int c, int base = DEC)  { print(c, base); println(); }
94
-  FORCE_INLINE void println(long c, int base = DEC)          { print(c, base); println(); }
95
-  FORCE_INLINE void println(unsigned long c, int base = DEC) { print(c, base); println(); }
96
-  FORCE_INLINE void println(double c, int digits = 2)        { print(c, digits); println(); }
97
-  void println()                                { write("\r\n"); }
89
+  NO_INLINE void println(const char s[])                  { print(s); println(); }
90
+  NO_INLINE void println(char c, int base = 0)            { print(c, base); println(); }
91
+  NO_INLINE void println(unsigned char c, int base = 0)   { print(c, base); println(); }
92
+  NO_INLINE void println(int c, int base = DEC)           { print(c, base); println(); }
93
+  NO_INLINE void println(unsigned int c, int base = DEC)  { print(c, base); println(); }
94
+  NO_INLINE void println(long c, int base = DEC)          { print(c, base); println(); }
95
+  NO_INLINE void println(unsigned long c, int base = DEC) { print(c, base); println(); }
96
+  NO_INLINE void println(double c, int digits = 2)        { print(c, digits); println(); }
97
+  NO_INLINE void println()                                { write('\r'); write('\n'); }
98 98
 
99 99
   // Print a number with the given base
100 100
   void printNumber(unsigned long n, const uint8_t base) {

+ 14
- 10
Marlin/src/core/serial_hook.h View File

@@ -61,7 +61,7 @@ struct ConditionalSerial : public SerialBase< ConditionalSerial<SerialT> > {
61 61
 
62 62
   bool    & condition;
63 63
   SerialT & out;
64
-  size_t write(uint8_t c) { if (condition) return out.write(c); return 0; }
64
+  NO_INLINE size_t write(uint8_t c) { if (condition) return out.write(c); return 0; }
65 65
   void flush()            { if (condition) out.flush();  }
66 66
   void begin(long br)     { out.begin(br); }
67 67
   void end()              { out.end(); }
@@ -83,7 +83,7 @@ struct ForwardSerial : public SerialBase< ForwardSerial<SerialT> > {
83 83
   typedef SerialBase< ForwardSerial<SerialT> > BaseClassT;
84 84
 
85 85
   SerialT & out;
86
-  size_t write(uint8_t c) { return out.write(c); }
86
+  NO_INLINE size_t write(uint8_t c) { return out.write(c); }
87 87
   void flush()            { out.flush();  }
88 88
   void begin(long br)     { out.begin(br); }
89 89
   void end()              { out.end(); }
@@ -111,12 +111,12 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial<SerialT> >, public Seria
111 111
   EndOfMessageHook eofHook;
112 112
   void *           userPointer;
113 113
 
114
-  size_t write(uint8_t c) {
114
+  NO_INLINE size_t write(uint8_t c) {
115 115
     if (writeHook) writeHook(userPointer, c);
116 116
     return SerialT::write(c);
117 117
   }
118 118
 
119
-  void msgDone() {
119
+  NO_INLINE void msgDone() {
120 120
     if (eofHook) eofHook(userPointer);
121 121
   }
122 122
 
@@ -130,7 +130,11 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial<SerialT> >, public Seria
130 130
 
131 131
   using BaseClassT::print;
132 132
   using BaseClassT::println;
133
-  
133
+
134
+  // Underlying implementation might use Arduino's bool operator
135
+  bool connected() { 
136
+    return Private::HasMember_connected<SerialT>::value ? CALL_IF_EXISTS(bool, static_cast<SerialT*>(this), connected) : static_cast<SerialT*>(this)->operator bool(); 
137
+  }  
134 138
 
135 139
   void setHook(WriteHook writeHook = 0, EndOfMessageHook eofHook = 0, void * userPointer = 0) {
136 140
     // Order is important here as serial code can be called inside interrupts
@@ -165,13 +169,13 @@ struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset>
165 169
     AllMask           = FirstOutputMask | SecondOutputMask,
166 170
   };
167 171
 
168
-  size_t write(uint8_t c) {
172
+  NO_INLINE size_t write(uint8_t c) {
169 173
     size_t ret = 0;
170 174
     if (portMask & FirstOutputMask)   ret = serial0.write(c);
171 175
     if (portMask & SecondOutputMask)  ret = serial1.write(c) | ret;
172 176
     return ret;
173 177
   }
174
-  void msgDone() {
178
+  NO_INLINE void msgDone() {
175 179
     if (portMask & FirstOutputMask)   serial0.msgDone();
176 180
     if (portMask & SecondOutputMask)  serial1.msgDone();
177 181
   }
@@ -182,7 +186,7 @@ struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset>
182 186
       default: return false;
183 187
     }
184 188
   }
185
-  int read(uint8_t index) {
189
+  NO_INLINE int read(uint8_t index) {
186 190
     switch(index) {
187 191
       case 0 + offset: return serial0.read();
188 192
       case 1 + offset: return serial1.read();
@@ -208,11 +212,11 @@ struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset>
208 212
   using BaseClassT::read;
209 213
 
210 214
   // Redirect flush
211
-  void flush()      {
215
+  NO_INLINE void flush()      {
212 216
     if (portMask & FirstOutputMask)   serial0.flush();
213 217
     if (portMask & SecondOutputMask)  serial1.flush();
214 218
   }
215
-  void flushTX()    {
219
+  NO_INLINE void flushTX()    {
216 220
     if (portMask & FirstOutputMask)   CALL_IF_EXISTS(void, &serial0, flushTX);
217 221
     if (portMask & SecondOutputMask)  CALL_IF_EXISTS(void, &serial1, flushTX);
218 222
   }

Loading…
Cancel
Save