Browse Source

M100: LPC1768 and DUE compatibility (#13962)

Bob Kuhn 6 years ago
parent
commit
fa3739aa23
1 changed files with 97 additions and 55 deletions
  1. 97
    55
      Marlin/src/gcode/calibrate/M100.cpp

+ 97
- 55
Marlin/src/gcode/calibrate/M100.cpp View File

50
  *
50
  *
51
  * Also, there are two support functions that can be called from a developer's C code.
51
  * Also, there are two support functions that can be called from a developer's C code.
52
  *
52
  *
53
- *    uint16_t check_for_free_memory_corruption(PGM_P const ptr);
53
+ *    uint16_t check_for_free_memory_corruption(PGM_P const free_memory_start);
54
  *    void M100_dump_routine(PGM_P const title, const char *start, const char *end);
54
  *    void M100_dump_routine(PGM_P const title, const char *start, const char *end);
55
  *
55
  *
56
  * Initial version by Roxy-3D
56
  * Initial version by Roxy-3D
60
 
60
 
61
 #define TEST_BYTE ((char) 0xE5)
61
 #define TEST_BYTE ((char) 0xE5)
62
 
62
 
63
-extern char* __brkval;
64
-extern size_t  __heap_start, __heap_end, __flp;
65
-extern char __bss_end;
63
+#if defined(__AVR__) || IS_32BIT_TEENSY
64
+
65
+  extern char __bss_end;
66
+  char* end_bss =  &__bss_end;
67
+  char* free_memory_start = end_bss;
68
+
69
+
70
+  char* free_memory_end = 0;
71
+  char* stacklimit = 0;
72
+  char* heaplimit = 0;
73
+
74
+  #define MEMORY_END_CORRECTION 0
75
+
76
+#elif defined(TARGET_LPC1768)
77
+
78
+  extern char   __bss_end__;
79
+  extern char   __StackLimit;
80
+  extern char   __HeapLimit;
81
+
82
+  char* end_bss =  &__bss_end__;
83
+  char* stacklimit =  &__StackLimit;
84
+  char* heaplimit =  &__HeapLimit ;
85
+
86
+  #define MEMORY_END_CORRECTION 0x200
87
+
88
+  char* free_memory_start = heaplimit;
89
+  char* free_memory_end = stacklimit - MEMORY_END_CORRECTION;
90
+
91
+
92
+#elif defined(__SAM3X8E__)
93
+
94
+  extern char   _ebss;
95
+
96
+  char* end_bss = &_ebss;
97
+
98
+  char* free_memory_start = end_bss;
99
+
100
+  char* free_memory_end = 0;
101
+  char* stacklimit = 0;
102
+  char* heaplimit = 0;
103
+
104
+  #define MEMORY_END_CORRECTION 0x10000  // need to stay well below 0x20080000 or M100 F crashes
105
+
106
+#else
107
+  #error "M100 - unsupported CPU"
108
+#endif
66
 
109
 
67
 //
110
 //
68
 // Utility functions
111
 // Utility functions
69
 //
112
 //
70
 
113
 
71
-#define END_OF_HEAP() (__brkval ? __brkval : &__bss_end)
72
-
73
 // Location of a variable on its stack frame. Returns a value above
114
 // Location of a variable on its stack frame. Returns a value above
74
 // the stack (once the function returns to the caller).
115
 // the stack (once the function returns to the caller).
75
 char* top_of_stack() {
116
 char* top_of_stack() {
78
 }
119
 }
79
 
120
 
80
 // Count the number of test bytes at the specified location.
121
 // Count the number of test bytes at the specified location.
81
-inline int32_t count_test_bytes(const char * const ptr) {
122
+inline int32_t count_test_bytes(const char * const start_free_memory) {
82
   for (uint32_t i = 0; i < 32000; i++)
123
   for (uint32_t i = 0; i < 32000; i++)
83
-    if (char(ptr[i]) != TEST_BYTE)
124
+    if (char(start_free_memory[i]) != TEST_BYTE)
84
       return i - 1;
125
       return i - 1;
85
 
126
 
86
   return -1;
127
   return -1;
93
 #if ENABLED(M100_FREE_MEMORY_DUMPER)
134
 #if ENABLED(M100_FREE_MEMORY_DUMPER)
94
   /**
135
   /**
95
    * M100 D
136
    * M100 D
96
-   *  Dump the free memory block from __brkval to the stack pointer.
137
+   *  Dump the free memory block from brkval to the stack pointer.
97
    *  malloc() eats memory from the start of the block and the stack grows
138
    *  malloc() eats memory from the start of the block and the stack grows
98
    *  up from the bottom of the block. Solid test bytes indicate nothing has
139
    *  up from the bottom of the block. Solid test bytes indicate nothing has
99
    *  used that memory yet. There should not be anything but test bytes within
140
    *  used that memory yet. There should not be anything but test bytes within
100
    *  the block. If so, it may indicate memory corruption due to a bad pointer.
141
    *  the block. If so, it may indicate memory corruption due to a bad pointer.
101
    *  Unexpected bytes are flagged in the right column.
142
    *  Unexpected bytes are flagged in the right column.
102
    */
143
    */
103
-  inline void dump_free_memory(const char *ptr, const char *sp) {
144
+  inline void dump_free_memory(const char *start_free_memory, const char *end_free_memory) {
104
     //
145
     //
105
     // Start and end the dump on a nice 16 byte boundary
146
     // Start and end the dump on a nice 16 byte boundary
106
     // (even though the values are not 16-byte aligned).
147
     // (even though the values are not 16-byte aligned).
107
     //
148
     //
108
-    ptr = (char*)((ptr_int_t)((uint32_t)ptr & 0xFFFFFFF0)); // Align to 16-byte boundary
109
-    sp  = (char*)((ptr_int_t)((uint32_t)sp  | 0x0000000F)); // Align sp to the 15th byte (at or above sp)
149
+    start_free_memory = (char*)((ptr_int_t)((uint32_t)start_free_memory & 0xFFFFFFF0)); // Align to 16-byte boundary
150
+    end_free_memory  = (char*)((ptr_int_t)((uint32_t)end_free_memory  | 0x0000000F)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
110
 
151
 
111
     // Dump command main loop
152
     // Dump command main loop
112
-    while (ptr < sp) {
113
-      print_hex_address(ptr);             // Print the address
153
+    while (start_free_memory < end_free_memory) {
154
+      print_hex_address(start_free_memory);             // Print the address
114
       SERIAL_CHAR(':');
155
       SERIAL_CHAR(':');
115
       for (uint8_t i = 0; i < 16; i++) {  // and 16 data bytes
156
       for (uint8_t i = 0; i < 16; i++) {  // and 16 data bytes
116
         if (i == 8) SERIAL_CHAR('-');
157
         if (i == 8) SERIAL_CHAR('-');
117
-        print_hex_byte(ptr[i]);
158
+        print_hex_byte(start_free_memory[i]);
118
         SERIAL_CHAR(' ');
159
         SERIAL_CHAR(' ');
119
       }
160
       }
120
       serial_delay(25);
161
       serial_delay(25);
121
       SERIAL_CHAR('|');                   // Point out non test bytes
162
       SERIAL_CHAR('|');                   // Point out non test bytes
122
       for (uint8_t i = 0; i < 16; i++) {
163
       for (uint8_t i = 0; i < 16; i++) {
123
-        char ccc = (char)ptr[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
124
-        if (&ptr[i] >= (const char*)command_queue && &ptr[i] < (const char*)(command_queue + sizeof(command_queue))) { // Print out ASCII in the command buffer area
164
+        char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
165
+        if (&start_free_memory[i] >= (const char*)command_queue && &start_free_memory[i] < (const char*)(command_queue + sizeof(command_queue))) { // Print out ASCII in the command buffer area
125
           if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' ';
166
           if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' ';
126
         }
167
         }
127
         else { // If not in the command buffer area, flag bytes that don't match the test byte
168
         else { // If not in the command buffer area, flag bytes that don't match the test byte
130
         SERIAL_CHAR(ccc);
171
         SERIAL_CHAR(ccc);
131
       }
172
       }
132
       SERIAL_EOL();
173
       SERIAL_EOL();
133
-      ptr += 16;
174
+      start_free_memory += 16;
134
       serial_delay(25);
175
       serial_delay(25);
135
       idle();
176
       idle();
136
     }
177
     }
143
     // Round the start and end locations to produce full lines of output
184
     // Round the start and end locations to produce full lines of output
144
     //
185
     //
145
     start = (char*)((ptr_int_t)((uint32_t)start & 0xFFFFFFF0)); // Align to 16-byte boundary
186
     start = (char*)((ptr_int_t)((uint32_t)start & 0xFFFFFFF0)); // Align to 16-byte boundary
146
-    end   = (char*)((ptr_int_t)((uint32_t)end   | 0x0000000F)); // Align sp to the 15th byte (at or above sp)
187
+    end   = (char*)((ptr_int_t)((uint32_t)end   | 0x0000000F)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
147
     dump_free_memory(start, end);
188
     dump_free_memory(start, end);
148
   }
189
   }
149
 
190
 
152
 inline int check_for_free_memory_corruption(PGM_P const title) {
193
 inline int check_for_free_memory_corruption(PGM_P const title) {
153
   serialprintPGM(title);
194
   serialprintPGM(title);
154
 
195
 
155
-  char *ptr = END_OF_HEAP(), *sp = top_of_stack();
156
-  int n = sp - ptr;
196
+  char *start_free_memory = free_memory_start, *end_free_memory = free_memory_end;
197
+  int n = end_free_memory - start_free_memory;
157
 
198
 
158
   SERIAL_ECHOPAIR("\nfmc() n=", n);
199
   SERIAL_ECHOPAIR("\nfmc() n=", n);
159
-  SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval));
160
-  SERIAL_ECHOPAIR("=",             hex_address(__brkval));
161
-  SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end));
162
-  SERIAL_ECHOPAIR(" sp=",          hex_address(sp));
200
+  SERIAL_ECHOPAIR("\nfree_memory_start=", hex_address(free_memory_start));
201
+  SERIAL_ECHOLNPAIR("  end_free_memory=",          hex_address(end_free_memory));
163
 
202
 
164
-  if (sp < ptr)  {
165
-    SERIAL_ECHOPGM(" sp < Heap ");
203
+  if (end_free_memory < start_free_memory)  {
204
+    SERIAL_ECHOPGM(" end_free_memory < Heap ");
166
     // SET_INPUT_PULLUP(63);           // if the developer has a switch wired up to their controller board
205
     // SET_INPUT_PULLUP(63);           // if the developer has a switch wired up to their controller board
167
     // safe_delay(5);                  // this code can be enabled to pause the display as soon as the
206
     // safe_delay(5);                  // this code can be enabled to pause the display as soon as the
168
     // while ( READ(63))               // malfunction is detected.   It is currently defaulting to a switch
207
     // while ( READ(63))               // malfunction is detected.   It is currently defaulting to a switch
172
     //   idle();
211
     //   idle();
173
     serial_delay(20);
212
     serial_delay(20);
174
     #if ENABLED(M100_FREE_MEMORY_DUMPER)
213
     #if ENABLED(M100_FREE_MEMORY_DUMPER)
175
-      M100_dump_routine(PSTR("   Memory corruption detected with sp<Heap\n"), (char*)0x1B80, (char*)0x21FF);
214
+      M100_dump_routine(PSTR("   Memory corruption detected with end_free_memory<Heap\n"), (char*)0x1B80, (char*)0x21FF);
176
     #endif
215
     #endif
177
   }
216
   }
178
 
217
 
179
   // Scan through the range looking for the biggest block of 0xE5's we can find
218
   // Scan through the range looking for the biggest block of 0xE5's we can find
180
   int block_cnt = 0;
219
   int block_cnt = 0;
181
   for (int i = 0; i < n; i++) {
220
   for (int i = 0; i < n; i++) {
182
-    if (ptr[i] == TEST_BYTE) {
183
-      int32_t j = count_test_bytes(ptr + i);
221
+    if (start_free_memory[i] == TEST_BYTE) {
222
+      int32_t j = count_test_bytes(start_free_memory + i);
184
       if (j > 8) {
223
       if (j > 8) {
185
         // SERIAL_ECHOPAIR("Found ", j);
224
         // SERIAL_ECHOPAIR("Found ", j);
186
-        // SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(ptr + i));
225
+        // SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(start_free_memory + i));
187
         i += j;
226
         i += j;
188
         block_cnt++;
227
         block_cnt++;
189
         SERIAL_ECHOPAIR(" (", block_cnt);
228
         SERIAL_ECHOPAIR(" (", block_cnt);
190
         SERIAL_ECHOPAIR(") found=", j);
229
         SERIAL_ECHOPAIR(") found=", j);
191
-        SERIAL_ECHOPGM("   ");
230
+        SERIAL_ECHOLNPGM("   ");
192
       }
231
       }
193
     }
232
     }
194
   }
233
   }
195
   SERIAL_ECHOPAIR("  block_found=", block_cnt);
234
   SERIAL_ECHOPAIR("  block_found=", block_cnt);
196
 
235
 
197
-  if (block_cnt != 1 || __brkval != nullptr)
236
+  if (block_cnt != 1)
198
     SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
237
     SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
199
 
238
 
200
   if (block_cnt == 0)       // Make sure the special case of no free blocks shows up as an
239
   if (block_cnt == 0)       // Make sure the special case of no free blocks shows up as an
215
  *  Return the number of free bytes in the memory pool,
254
  *  Return the number of free bytes in the memory pool,
216
  *  with other vital statistics defining the pool.
255
  *  with other vital statistics defining the pool.
217
  */
256
  */
218
-inline void free_memory_pool_report(char * const ptr, const int32_t size) {
257
+inline void free_memory_pool_report(char * const start_free_memory, const int32_t size) {
219
   int32_t max_cnt = -1, block_cnt = 0;
258
   int32_t max_cnt = -1, block_cnt = 0;
220
   char *max_addr = nullptr;
259
   char *max_addr = nullptr;
221
   // Find the longest block of test bytes in the buffer
260
   // Find the longest block of test bytes in the buffer
222
   for (int32_t i = 0; i < size; i++) {
261
   for (int32_t i = 0; i < size; i++) {
223
-    char *addr = ptr + i;
262
+    char *addr = start_free_memory + i;
224
     if (*addr == TEST_BYTE) {
263
     if (*addr == TEST_BYTE) {
225
       const int32_t j = count_test_bytes(addr);
264
       const int32_t j = count_test_bytes(addr);
226
       if (j > 8) {
265
       if (j > 8) {
249
    *  Corrupt <num> locations in the free memory pool and report the corrupt addresses.
288
    *  Corrupt <num> locations in the free memory pool and report the corrupt addresses.
250
    *  This is useful to check the correctness of the M100 D and the M100 F commands.
289
    *  This is useful to check the correctness of the M100 D and the M100 F commands.
251
    */
290
    */
252
-  inline void corrupt_free_memory(char *ptr, const uint32_t size) {
253
-    ptr += 8;
254
-    const uint32_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack.
291
+  inline void corrupt_free_memory(char *start_free_memory, const uint32_t size) {
292
+    start_free_memory += 8;
293
+    const uint32_t near_top = top_of_stack() - start_free_memory - 250, // -250 to avoid interrupt activity that's altered the stack.
255
                    j = near_top / (size + 1);
294
                    j = near_top / (size + 1);
256
 
295
 
257
     SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
296
     SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
258
     for (uint32_t i = 1; i <= size; i++) {
297
     for (uint32_t i = 1; i <= size; i++) {
259
-      char * const addr = ptr + i * j;
298
+      char * const addr = start_free_memory + i * j;
260
       *addr = i;
299
       *addr = i;
261
       SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
300
       SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
262
     }
301
     }
268
  * M100 I
307
  * M100 I
269
  *  Init memory for the M100 tests. (Automatically applied on the first M100.)
308
  *  Init memory for the M100 tests. (Automatically applied on the first M100.)
270
  */
309
  */
271
-inline void init_free_memory(char *ptr, int32_t size) {
310
+inline void init_free_memory(char *start_free_memory, int32_t size) {
272
   SERIAL_ECHOLNPGM("Initializing free memory block.\n\n");
311
   SERIAL_ECHOLNPGM("Initializing free memory block.\n\n");
273
 
312
 
274
   size -= 250;    // -250 to avoid interrupt activity that's altered the stack.
313
   size -= 250;    // -250 to avoid interrupt activity that's altered the stack.
277
     return;
316
     return;
278
   }
317
   }
279
 
318
 
280
-  ptr += 8;       // move a few bytes away from the heap just because we don't want
319
+  start_free_memory += 8;       // move a few bytes away from the heap just because we don't want
281
                   // to be altering memory that close to it.
320
                   // to be altering memory that close to it.
282
-  memset(ptr, TEST_BYTE, size);
321
+  memset(start_free_memory, TEST_BYTE, size);
283
 
322
 
284
   SERIAL_ECHO(size);
323
   SERIAL_ECHO(size);
285
   SERIAL_ECHOLNPGM(" bytes of memory initialized.\n");
324
   SERIAL_ECHOLNPGM(" bytes of memory initialized.\n");
286
 
325
 
287
   for (int32_t i = 0; i < size; i++) {
326
   for (int32_t i = 0; i < size; i++) {
288
-    if (ptr[i] != TEST_BYTE) {
289
-      SERIAL_ECHOPAIR("? address : ", hex_address(ptr + i));
290
-      SERIAL_ECHOLNPAIR("=", hex_byte(ptr[i]));
327
+    if (start_free_memory[i] != TEST_BYTE) {
328
+      SERIAL_ECHOPAIR("? address : ", hex_address(start_free_memory + i));
329
+      SERIAL_ECHOLNPAIR("=", hex_byte(start_free_memory[i]));
291
       SERIAL_EOL();
330
       SERIAL_EOL();
292
     }
331
     }
293
   }
332
   }
297
  * M100: Free Memory Check
336
  * M100: Free Memory Check
298
  */
337
  */
299
 void GcodeSuite::M100() {
338
 void GcodeSuite::M100() {
300
-  SERIAL_ECHOPAIR("\n__brkval : ", hex_address(__brkval));
301
-  SERIAL_ECHOPAIR("\n__bss_end : ", hex_address(&__bss_end));
302
-
303
-  char *ptr = END_OF_HEAP(), *sp = top_of_stack();
304
 
339
 
305
-  SERIAL_ECHOPAIR("\nstart of free space : ", hex_address(ptr));
306
-  SERIAL_ECHOLNPAIR("\nStack Pointer : ", hex_address(sp));
340
+  char *sp = top_of_stack();
341
+  if (!free_memory_end) free_memory_end = sp - MEMORY_END_CORRECTION;
342
+  SERIAL_ECHOPAIR("\nbss_end               : ", hex_address(end_bss));
343
+  if (heaplimit) SERIAL_ECHOPAIR("\n__heaplimit           : ", hex_address(heaplimit ));
344
+  SERIAL_ECHOPAIR("\nfree_memory_start     : ", hex_address(free_memory_start));
345
+  if (stacklimit) SERIAL_ECHOPAIR("\n__stacklimit          : ", hex_address(stacklimit));
346
+  SERIAL_ECHOPAIR("\nfree_memory_end       : ", hex_address(free_memory_end  ));
347
+  if (MEMORY_END_CORRECTION)  SERIAL_ECHOPAIR("\nMEMORY_END_CORRECTION: ", MEMORY_END_CORRECTION );
348
+  SERIAL_ECHOLNPAIR("\nStack Pointer         : ", hex_address(sp));
307
 
349
 
308
   // Always init on the first invocation of M100
350
   // Always init on the first invocation of M100
309
   static bool m100_not_initialized = true;
351
   static bool m100_not_initialized = true;
310
   if (m100_not_initialized || parser.seen('I')) {
352
   if (m100_not_initialized || parser.seen('I')) {
311
     m100_not_initialized = false;
353
     m100_not_initialized = false;
312
-    init_free_memory(ptr, sp - ptr);
354
+    init_free_memory(free_memory_start, free_memory_end - free_memory_start);
313
   }
355
   }
314
 
356
 
315
   #if ENABLED(M100_FREE_MEMORY_DUMPER)
357
   #if ENABLED(M100_FREE_MEMORY_DUMPER)
316
     if (parser.seen('D'))
358
     if (parser.seen('D'))
317
-      return dump_free_memory(ptr, sp);
359
+      return dump_free_memory(free_memory_start, free_memory_end);
318
   #endif
360
   #endif
319
 
361
 
320
   if (parser.seen('F'))
362
   if (parser.seen('F'))
321
-    return free_memory_pool_report(ptr, sp - ptr);
363
+    return free_memory_pool_report(free_memory_start, free_memory_end - free_memory_start);
322
 
364
 
323
   #if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
365
   #if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
324
 
366
 
325
     if (parser.seen('C'))
367
     if (parser.seen('C'))
326
-      return corrupt_free_memory(ptr, parser.value_int());
368
+      return corrupt_free_memory(free_memory_start, parser.value_int());
327
 
369
 
328
   #endif
370
   #endif
329
 }
371
 }

Loading…
Cancel
Save