diff --git a/Marlin/M100_Free_Mem_Chk.cpp b/Marlin/M100_Free_Mem_Chk.cpp index 0851ff69d..ccbc1c8b0 100644 --- a/Marlin/M100_Free_Mem_Chk.cpp +++ b/Marlin/M100_Free_Mem_Chk.cpp @@ -40,8 +40,8 @@ * * Also, there are two support functions that can be called from a developer's C code. * - * uint16_t check_for_free_memory_corruption(char * const ptr); - * void M100_dump_routine( char *title, char *start, char *end); + * uint16_t check_for_free_memory_corruption(const char * const ptr); + * void M100_dump_routine(const char * const title, const char *start, const char *end); * * Initial version by Roxy-3D */ @@ -68,7 +68,7 @@ extern char __bss_end; // #define END_OF_HEAP() (__brkval ? __brkval : &__bss_end) -int check_for_free_memory_corruption(char *title); +int check_for_free_memory_corruption(const char * const title); // Location of a variable on its stack frame. Returns a value above // the stack (once the function returns to the caller). @@ -100,7 +100,7 @@ int16_t count_test_bytes(const uint8_t * const ptr) { * the block. If so, it may indicate memory corruption due to a bad pointer. * Unexpected bytes are flagged in the right column. */ - void dump_free_memory(uint8_t *ptr, uint8_t *sp) { + void dump_free_memory(const uint8_t *ptr, const uint8_t *sp) { // // Start and end the dump on a nice 16 byte boundary // (even though the values are not 16-byte aligned). @@ -120,17 +120,13 @@ int16_t count_test_bytes(const uint8_t * const ptr) { safe_delay(25); SERIAL_CHAR('|'); // Point out non test bytes for (uint8_t i = 0; i < 16; i++) { - char ccc; - ccc = (char) ptr[i]; - if ( &ptr[i]>=&command_queue[0][0] && &ptr[i]<&command_queue[BUFSIZE][MAX_CMD_SIZE]) { // Print out ASCII in the command - if ( ccc<' ' || ccc>0x7e) // buffer area - ccc = ' '; - } - else - if (ccc != TEST_BYTE) // If not display data in the command buffer - ccc = '?'; // area, we flag bytes that don't match the test byte - else - ccc = ' '; + char ccc = (char)ptr[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken + if (&ptr[i] >= command_queue && &ptr[i] < &command_queue[BUFSIZE][MAX_CMD_SIZE]) { // Print out ASCII in the command buffer area + if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' '; + } + else { // If not in the command buffer area, flag bytes that don't match the test byte + ccc = (ccc == TEST_BYTE) ? ' ' : '?'; + } SERIAL_CHAR(ccc); } SERIAL_EOL; @@ -140,19 +136,16 @@ int16_t count_test_bytes(const uint8_t * const ptr) { } } -void M100_dump_routine( char *title, char *start, char *end) { -unsigned char c; -int i; - -// -// Round the start and end locations to produce full lines of output -// - start = (char*) ((uint16_t) start & 0xfff0); - end = (char*) ((uint16_t) end | 0x000f); - - SERIAL_ECHOLN(title); - dump_free_memory( start, end ); +void M100_dump_routine(const char * const title, const char *start, const char *end) { + SERIAL_ECHOLN(title); + // + // Round the start and end locations to produce full lines of output + // + start = (char*)((uint16_t) start & 0xfff0); + end = (char*)((uint16_t) end | 0x000f); + dump_free_memory(start, end); } + #endif // M100_FREE_MEMORY_DUMPER /** @@ -233,10 +226,10 @@ void init_free_memory(uint8_t *ptr, int16_t size) { SERIAL_ECHOLNPGM(" bytes of memory initialized.\n"); for (uint16_t i = 0; i < size; i++) { - if (((char) ptr[i]) != TEST_BYTE) { + if ((char)ptr[i] != TEST_BYTE) { SERIAL_ECHOPAIR("? address : ", hex_address(ptr + i)); - SERIAL_ECHOPAIR("=", hex_byte(ptr[i])); - SERIAL_EOL; SERIAL_EOL; + SERIAL_ECHOLNPAIR("=", hex_byte(ptr[i])); + SERIAL_EOL; } } } @@ -276,68 +269,66 @@ void gcode_M100() { #endif } -int check_for_free_memory_corruption(char *title) { - char *sp, *ptr; - int block_cnt = 0, i, j, n; +int check_for_free_memory_corruption(const char * const title) { + SERIAL_ECHO(title); - SERIAL_ECHO(title); + char *ptr = END_OF_HEAP(), *sp = top_of_stack(); + int n = sp - ptr; - ptr = __brkval ? __brkval : &__bss_end; - sp = top_of_stack(); + SERIAL_ECHOPAIR("\nfmc() n=", n); + SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval)); + SERIAL_ECHOPAIR("=", hex_address(__brkval)); + SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end)); + SERIAL_ECHOPAIR(" sp=", hex_address(sp)); - n = sp - ptr; - SERIAL_ECHOPAIR("\nfmc() n=", n); - SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval)); - SERIAL_ECHOPAIR("=", hex_address(__brkval)); - SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end)); - SERIAL_ECHOPAIR(" sp=", hex_word(sp)); + if (sp < ptr) { + SERIAL_ECHOPGM(" sp < Heap "); + // SET_INPUT_PULLUP(63); // if the developer has a switch wired up to their controller board + // safe_delay(5); // this code can be enabled to pause the display as soon as the + // while ( READ(63)) // malfunction is detected. It is currently defaulting to a switch + // idle(); // being on pin-63 which is unassigend and available on most controller + // safe_delay(20); // boards. + // while ( !READ(63)) + // idle(); + safe_delay(20); + #ifdef M100_FREE_MEMORY_DUMPER + M100_dump_routine(" Memory corruption detected with sp 8) { -// SERIAL_ECHOPAIR("Found ", j); -// SERIAL_ECHOLNPAIR(" bytes free at 0x", hex_word((uint16_t)(ptr + i))); - - i += j; - block_cnt++; - SERIAL_ECHOPAIR(" (", block_cnt); - SERIAL_ECHOPAIR(") found=", j); - SERIAL_ECHOPGM(" "); - } + // Scan through the range looking for the biggest block of 0xE5's we can find + int block_cnt = 0; + for (int i = 0; i < n; i++) { + if (ptr[i] == TEST_BYTE) { + int16_t j = count_test_bytes(ptr + i); + if (j > 8) { + // SERIAL_ECHOPAIR("Found ", j); + // SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(ptr + i)); + i += j; + block_cnt++; + SERIAL_ECHOPAIR(" (", block_cnt); + SERIAL_ECHOPAIR(") found=", j); + SERIAL_ECHOPGM(" "); } } - SERIAL_ECHOPAIR(" block_found=", block_cnt); - - if ((block_cnt!=1) || (__brkval != 0x0000)) - SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area."); - - if ((block_cnt==0)) // Make sure the special case of no free blocks shows up as an - block_cnt = -1; // error to the calling code! - - if (block_cnt==1) { - SERIAL_ECHOPGM(" return=0\n"); // if the block_cnt is 1, nothing has broken up the free memory - return 0; // area and it is appropriate to say 'no corruption'. - } - SERIAL_ECHOPGM(" return=true\n"); - return block_cnt; } + SERIAL_ECHOPAIR(" block_found=", block_cnt); + + if (block_cnt != 1 || __brkval != 0x0000) + SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area."); + + if (block_cnt == 0) // Make sure the special case of no free blocks shows up as an + block_cnt = -1; // error to the calling code! + + SERIAL_ECHOPGM(" return="); + if (block_cnt == 1) { + SERIAL_CHAR('0'); // if the block_cnt is 1, nothing has broken up the free memory + SERIAL_EOL; // area and it is appropriate to say 'no corruption'. + return 0; + } + SERIAL_ECHOLNPGM("true"); + return block_cnt; +} #endif // M100_FREE_MEMORY_WATCHER diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index a1b030219..137d29ee1 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -284,7 +284,7 @@ #if ENABLED(M100_FREE_MEMORY_WATCHER) void gcode_M100(); - void M100_dump_routine( char *title, char *start, char *end); + void M100_dump_routine(const char * const title, const char *start, const char *end); #endif #if ENABLED(SDSUPPORT) @@ -9571,8 +9571,8 @@ void process_next_command() { SERIAL_ECHO_START; SERIAL_ECHOLN(current_command); #if ENABLED(M100_FREE_MEMORY_WATCHER) - SERIAL_ECHOPAIR("slot:", cmd_queue_index_r); - M100_dump_routine( " Command Queue:", &command_queue[0][0], &command_queue[BUFSIZE][MAX_CMD_SIZE] ); + SERIAL_ECHOPAIR("slot:", cmd_queue_index_r); + M100_dump_routine(" Command Queue:", &command_queue[0][0], &command_queue[BUFSIZE][MAX_CMD_SIZE]); #endif } diff --git a/Marlin/pinsDebug.h b/Marlin/pinsDebug.h index a60b7449c..f347097c0 100644 --- a/Marlin/pinsDebug.h +++ b/Marlin/pinsDebug.h @@ -524,7 +524,7 @@ inline void report_pin_state_extended(int8_t pin, bool ignore, bool extended = t SERIAL_PROTOCOLPAIR(" Input = ", digitalRead_mod(pin)); } - //if (!pwm_status(pin)) SERIAL_ECHOCHAR(' '); // add padding if it's not a PWM pin + //if (!pwm_status(pin)) SERIAL_CHAR(' '); // add padding if it's not a PWM pin if (extended) pwm_details(pin); // report PWM capabilities only if doing an extended report SERIAL_EOL; } diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index 222215c77..6c4fcd23a 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -35,7 +35,6 @@ #include - void lcd_babystep_z(); void lcd_return_to_status(); bool lcd_clicked(); void lcd_implementation_clear(); @@ -305,7 +304,7 @@ // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine. static int g29_verbose_level, phase_value = -1, repetition_cnt, - storage_slot=0, map_type, grid_size; + storage_slot = 0, map_type, grid_size; static bool repeat_flag, c_flag, x_flag, y_flag; static float x_pos, y_pos, measured_z, card_thickness = 0.0, ubl_constant = 0.0; @@ -330,13 +329,10 @@ // Invalidate Mesh Points. This command is a little bit asymetrical because // it directly specifies the repetition count and does not use the 'R' parameter. if (code_seen('I')) { - int cnt = 0; + uint8_t cnt = 0; repetition_cnt = code_has_value() ? code_value_int() : 1; while (repetition_cnt--) { - if (cnt>20) { - cnt = 0; - idle(); - } + if (cnt > 20) { cnt = 0; idle(); } const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, x_pos, y_pos, 0, NULL, false); // The '0' says we want to use the nozzle's position if (location.x_index < 0) { SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n"); @@ -381,7 +377,7 @@ } if (code_seen('J')) { - if (grid_size<2 || grid_size>5) { + if (!WITHIN(grid_size, 2, 5)) { SERIAL_PROTOCOLLNPGM("ERROR - grid size must be between 2 and 5"); return; } @@ -996,7 +992,7 @@ repetition_cnt = 0; repeat_flag = code_seen('R'); if (repeat_flag) { - repetition_cnt = code_has_value() ? code_value_int() : GRID_MAX_POINTS_X*GRID_MAX_POINTS_Y; + repetition_cnt = code_has_value() ? code_value_int() : (GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y); if (repetition_cnt < 1) { SERIAL_PROTOCOLLNPGM("Invalid Repetition count.\n"); return UBL_ERR;