Quellcode durchsuchen

Fix M100 Free Memory Checker

M100 had numerious changes and quit working.   Part of the problem is
the overloading of the SERIAL_PROTOCOL functions.   Also, some of the
address arithmatic was changed to use char *ptr and passing ptr into the
SERIAL_PROTOCOL functions caused them to try to print a string instead
of a number.     M100 is working again.   Let's keep it that way!

M100 has been expanded to now have a function  int
free_memory_is_corrupted()  that can be called from other code to see if
the free space is still contiguous.  It may make sense to add a flag to
control its verbose nature but right now, the extra chit chat is very
helpful to know int free_memory_is_corrupted()  is doing the right thing
and what it found at various points when it was called.     A 'Show &
Tell' is coming up with int free_memory_is_corrupted().
Roxy-3D vor 8 Jahren
Ursprung
Commit
ba85faabc0
1 geänderte Dateien mit 68 neuen und 32 gelöschten Zeilen
  1. 68
    32
      Marlin/M100_Free_Mem_Chk.cpp

+ 68
- 32
Marlin/M100_Free_Mem_Chk.cpp Datei anzeigen

@@ -55,7 +55,8 @@ extern char __bss_end;
55 55
 
56 56
 char* top_of_stack();
57 57
 int how_many_E5s_are_here(char*);
58
-
58
+int free_memory_is_corrupted();         // int not bool!!!!  it will tell us how many blocks of
59
+                                        // free memory it found.
59 60
 void gcode_M100() {
60 61
   static bool m100_not_initialized = true;
61 62
   char* sp, *ptr;
@@ -69,18 +70,26 @@ void gcode_M100() {
69 70
   // probably caused by bad pointers.  Any unexpected values will be flagged in
70 71
   // the right hand column to help spotting them.
71 72
   //
73
+    SERIAL_ECHOPAIR("\n__brkval : 0x", hex_word((uint16_t)__brkval) );
74
+    SERIAL_ECHOPAIR("\n__bss_end : 0x", hex_word((uint16_t)&__bss_end));
75
+  //
76
+  // With out malloc() we need to be smart and use &__bss_end
77
+  //
78
+    ptr = __brkval ? __brkval : &__bss_end;    
79
+    SERIAL_ECHOPAIR("\nstart of free space : 0x", hex_word((uint16_t)ptr));
80
+
81
+    sp = top_of_stack();
82
+    SERIAL_ECHOLNPAIR("\nStack Pointer : 0x", hex_word((uint16_t)sp));
83
+
72 84
   #if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command
73 85
     if (code_seen('D')) {
74
-      ptr = __brkval ? __brkval : &__bss_end;
75 86
       //
76 87
       // We want to start and end the dump on a nice 16 byte boundry even though
77 88
       // the values we are using are not 16 byte aligned.
78 89
       //
79
-      SERIAL_ECHOPAIR("\nbss_end : 0x", hex_word((uint16_t)ptr));
80
-      ptr = (char*)((uint32_t)ptr & 0xfff0);
81
-      sp = top_of_stack();
82
-      SERIAL_ECHOLNPAIR("\nStack Pointer : 0x", hex_word((uint16_t)sp));
83
-      sp = (char*)((uint32_t)sp | 0x000f);
90
+      ptr = (char*) ((uint16_t) ptr & 0xfff0);
91
+      sp  = (char*) ((uint16_t) sp  | 0x000f);
92
+
84 93
       n = sp - ptr;
85 94
       //
86 95
       // This is the main loop of the Dump command.
@@ -89,6 +98,8 @@ void gcode_M100() {
89 98
         print_hex_word((uint16_t)ptr); // Print the address
90 99
         SERIAL_CHAR(':');
91 100
         for (i = 0; i < 16; i++) {      // and 16 data bytes
101
+          if (i==8)
102
+            SERIAL_CHAR('-');
92 103
           print_hex_byte(*(ptr + i));
93 104
           SERIAL_CHAR(' ');
94 105
         }
@@ -97,6 +108,7 @@ void gcode_M100() {
97 108
           SERIAL_CHAR((*(ptr + i) == (char)0xe5) ? ' ' : '?');
98 109
         SERIAL_EOL;
99 110
         ptr += 16;
111
+        idle();
100 112
       }
101 113
       return;
102 114
     }
@@ -106,11 +118,8 @@ void gcode_M100() {
106 118
   // other vital statistics that define the memory pool.
107 119
   //
108 120
   if (code_seen('F')) {
109
-    #if 0
110
-      int max_addr = (int)  __brkval ? __brkval : &__bss_end;
111
-      int max_cnt = 0;
112
-    #endif
113
-    int block_cnt = 0;
121
+    int max_cnt = -1, block_cnt = 0;
122
+    uint16_t max_addr=0;
114 123
     ptr =  __brkval ? __brkval : &__bss_end;
115 124
     sp = top_of_stack();
116 125
     n = sp - ptr;
@@ -121,19 +130,21 @@ void gcode_M100() {
121 130
         if (j > 8) {
122 131
           SERIAL_ECHOPAIR("Found ", j);
123 132
           SERIAL_ECHOLNPAIR(" bytes free at 0x", hex_word((uint16_t)(ptr + i)));
133
+          if (j > max_cnt) {  
134
+            max_cnt  = j;    
135
+            max_addr = (uint16_t) ptr + i;
136
+          }
124 137
           i += j;
125 138
           block_cnt++;
126 139
         }
127
-        #if 0
128
-          if (j > max_cnt) {      // We don't do anything with this information yet
129
-            max_cnt  = j;     // but we do know where the biggest free memory block is.
130
-            max_addr = (int) ptr + i;
131
-          }
132
-        #endif
133 140
       }
134 141
     }
135
-    if (block_cnt > 1)
142
+    if (block_cnt > 1) {
136 143
       SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
144
+      SERIAL_ECHOPAIR("\nLargest free block is ", max_cnt);
145
+      SERIAL_ECHOLNPAIR(" bytes big at 0x", hex_word(max_addr));
146
+    }
147
+    SERIAL_ECHOLNPAIR("free_memory_is_corrupted() = ", free_memory_is_corrupted()); 
137 148
     return;
138 149
   }
139 150
   //
@@ -144,14 +155,10 @@ void gcode_M100() {
144 155
     if (code_seen('C')) {
145 156
       int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool
146 157
       SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
147
-      ptr = __brkval ? __brkval : &__bss_end;
148
-      SERIAL_ECHOPAIR("\nbss_end : ", ptr);
149 158
       ptr += 8;
150 159
       sp = top_of_stack();
151
-      SERIAL_ECHOPAIR("\nStack Pointer : ", sp);
152
-      SERIAL_ECHOLNPGM("\n");
153
-      n = sp - ptr - 64;    // -64 just to keep us from finding interrupt activity that
154
-      // has altered the stack.
160
+      n = sp - ptr - 250;    // -250 just to keep us from finding interrupt activity that
161
+                            // has altered the stack.
155 162
       j = n / (x + 1);
156 163
       for (i = 1; i <= x; i++) {
157 164
         *(ptr + (i * j)) = i;
@@ -167,13 +174,11 @@ void gcode_M100() {
167 174
   //
168 175
   if (m100_not_initialized || code_seen('I')) {            // If no sub-command is specified, the first time
169 176
     SERIAL_ECHOLNPGM("Initializing free memory block.\n"); // this happens, it will Initialize.
170
-    ptr = __brkval ? __brkval : &__bss_end;                // Repeated M100 with no sub-command will not destroy the
171
-    SERIAL_ECHOPAIR("\nbss_end : ", ptr);                  // state of the initialized free memory pool.
177
+                                                           // Repeated M100 with no sub-command will not destroy the
178
+                                                           // state of the initialized free memory pool.
172 179
     ptr += 8;
173
-    sp = top_of_stack();
174
-    SERIAL_ECHOPAIR("\nStack Pointer : ", sp);
175 180
     SERIAL_ECHOLNPGM("\n");
176
-    n = sp - ptr - 64;    // -64 just to keep us from finding interrupt activity that
181
+    n = sp - ptr - 250;    // -250 just to keep us from finding interrupt activity that
177 182
     // has altered the stack.
178 183
     SERIAL_ECHO(n);
179 184
     SERIAL_ECHOLNPGM(" bytes of memory initialized.\n");
@@ -181,8 +186,8 @@ void gcode_M100() {
181 186
       *(ptr + i) = (char)0xe5;
182 187
     for (i = 0; i < n; i++) {
183 188
       if (*(ptr + i) != (char)0xe5) {
184
-        SERIAL_ECHOPAIR("? address : ", ptr + i);
185
-        SERIAL_ECHOPAIR("=", *(ptr + i));
189
+        SERIAL_ECHOPAIR("? address : ", hex_word(ptr+i) );
190
+        SERIAL_ECHOPAIR("=", hex_byte(*(ptr + i)) );
186 191
         SERIAL_ECHOLNPGM("\n");
187 192
       }
188 193
     }
@@ -212,5 +217,36 @@ int how_many_E5s_are_here(char* p) {
212 217
   return -1;
213 218
 }
214 219
 
220
+
221
+int free_memory_is_corrupted() {
222
+  char *sp, *ptr;
223
+  int block_cnt = 0, i, j, n;
224
+
225
+    ptr = __brkval ? __brkval : &__bss_end;    
226
+    sp = top_of_stack();
227
+
228
+    n = sp - ptr;
229
+
230
+    // Scan through the range looking for the biggest block of 0xE5's we can find
231
+    for (i = 0; i < n; i++) {
232
+      if (*(ptr + i) == (char)0xe5) {
233
+        j = how_many_E5s_are_here(ptr + i);
234
+        if (j > 8) {
235
+//        SERIAL_ECHOPAIR("Found ", j);
236
+//        SERIAL_ECHOLNPAIR(" bytes free at 0x", hex_word((uint16_t)(ptr + i)));
237
+
238
+          i += j;
239
+          block_cnt++;
240
+        }
241
+      }
242
+    }
243
+
244
+//  if (block_cnt > 1) {
245
+//    SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
246
+//   SERIAL_ECHOLNPAIR("\nLargest free block is ", max_cnt);
247
+//  }
248
+    return block_cnt;
249
+  }
250
+
215 251
 #endif
216 252
 

Laden…
Abbrechen
Speichern