Debugging tool for mbed enabled microcontrollers, especially for NUCLEO-F303RE and STM32F042F6P6.
debug_register.cpp@25:cda8a4f9874a, 2021-03-21 (annotated)
- Committer:
- bieleluk
- Date:
- Sun Mar 21 20:43:16 2021 +0000
- Revision:
- 25:cda8a4f9874a
- Parent:
- 15:83d4dced2a28
;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bieleluk | 0:e36b454cc2e6 | 1 | #include "Debug.h" |
bieleluk | 0:e36b454cc2e6 | 2 | |
bieleluk | 0:e36b454cc2e6 | 3 | // create object of class Debug_register |
bieleluk | 0:e36b454cc2e6 | 4 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 5 | Debug_register::Debug_register(PinName tx_pin, PinName rx_pin, int baudrate) : pc(tx_pin,rx_pin, baudrate) { |
bieleluk | 0:e36b454cc2e6 | 6 | init(); |
bieleluk | 0:e36b454cc2e6 | 7 | } |
bieleluk | 0:e36b454cc2e6 | 8 | |
bieleluk | 0:e36b454cc2e6 | 9 | // init function |
bieleluk | 0:e36b454cc2e6 | 10 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 11 | void Debug_register::init() { |
bieleluk | 12:a8ab6e018422 | 12 | pc.printf("\ec"); //clear entire screen |
bieleluk | 12:a8ab6e018422 | 13 | wait_ms(50); //wait until clearing is done |
bieleluk | 12:a8ab6e018422 | 14 | pc.printf("-----------------\n\r|\e[1m\e[97;40m\e[93;40mBREAKPOINT AREA\e[22m\e[97;40m|\n\r-----------------\n\r\033[s"); //print breakpoint label |
bieleluk | 0:e36b454cc2e6 | 15 | pc.printf("serial successfully initialised\n\r\e[32;40mto start program press any button\e[97;40m"); |
bieleluk | 15:83d4dced2a28 | 16 | breakpoint_count = 0; //set breakpoint count to 0 |
bieleluk | 12:a8ab6e018422 | 17 | pc.getc(); // wait until user sends any character |
bieleluk | 12:a8ab6e018422 | 18 | pc.printf("\r\e[2K\e[31;40mprogram is running\e[97;40m\r"); //running program message |
bieleluk | 12:a8ab6e018422 | 19 | pc.printf("\033[14;0H------------------\n\r|\e[1m\e[93;40mSERIAL PORT AREA\e[22m\e[97;40m|\n\r------------------\n\r\033[s"); //print serial port label |
bieleluk | 0:e36b454cc2e6 | 20 | } |
bieleluk | 0:e36b454cc2e6 | 21 | |
bieleluk | 0:e36b454cc2e6 | 22 | |
bieleluk | 0:e36b454cc2e6 | 23 | // perform one breakpoint and print one register |
bieleluk | 0:e36b454cc2e6 | 24 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 6:1ee26b7b9c2f | 25 | void Debug_register::breakpoint(int line_number, uint32_t address){ |
bieleluk | 3:3d7837ae4a37 | 26 | |
bieleluk | 12:a8ab6e018422 | 27 | uint32_t reg; //value of register |
bieleluk | 12:a8ab6e018422 | 28 | char sign; //received character |
bieleluk | 0:e36b454cc2e6 | 29 | |
bieleluk | 12:a8ab6e018422 | 30 | pc.printf("\e[s");//save actual cursor position |
bieleluk | 12:a8ab6e018422 | 31 | wait_ms(50);//wait until the position is saved |
bieleluk | 3:3d7837ae4a37 | 32 | |
bieleluk | 15:83d4dced2a28 | 33 | breakpoint_count++; // increment breakpoint count |
bieleluk | 3:3d7837ae4a37 | 34 | |
bieleluk | 12:a8ab6e018422 | 35 | while(1){ //endless cycle until Enter is pressed |
bieleluk | 12:a8ab6e018422 | 36 | clear_from_n_up_to_m(13,3); //clear breakpoint area |
bieleluk | 3:3d7837ae4a37 | 37 | |
bieleluk | 12:a8ab6e018422 | 38 | if (line_number < 0){ //print breakpoint and line number |
bieleluk | 3:3d7837ae4a37 | 39 | pc.printf(" Breakpoint number %d\t unknown line number\n\r",breakpoint_count); |
bieleluk | 3:3d7837ae4a37 | 40 | }else{ |
bieleluk | 3:3d7837ae4a37 | 41 | pc.printf("| Breakpoint number %d\tline number %d\n\r",breakpoint_count, line_number); |
bieleluk | 3:3d7837ae4a37 | 42 | } |
bieleluk | 3:3d7837ae4a37 | 43 | |
bieleluk | 15:83d4dced2a28 | 44 | // print address and register value |
bieleluk | 15:83d4dced2a28 | 45 | print_break(address - address%4); |
bieleluk | 3:3d7837ae4a37 | 46 | |
bieleluk | 15:83d4dced2a28 | 47 | // decide what to do next |
bieleluk | 12:a8ab6e018422 | 48 | pc.printf("\e[32;40mto continue press enter or p, to see higher press i, to see lower press j\n\rto read register press r, to write to register press w\e[97;40m"); |
bieleluk | 15:83d4dced2a28 | 49 | sign = pc.getc(); // wait for character to continue |
bieleluk | 15:83d4dced2a28 | 50 | |
bieleluk | 12:a8ab6e018422 | 51 | if (sign == 13 || sign == 'P' || sign == 'p'){ // if P or enter was pressed, end the breakpoint |
bieleluk | 15:83d4dced2a28 | 52 | pc.printf("\e[12;0H\e[2K\n\r\e[2K\e[31;40mprogram is running\e[97;40m\n\r\e[u"); |
bieleluk | 3:3d7837ae4a37 | 53 | break; |
bieleluk | 12:a8ab6e018422 | 54 | }else if (sign == 'i' || sign == 'I'){ // if i was pressed, show register on higher address |
bieleluk | 12:a8ab6e018422 | 55 | address += 0x4; // return cursor position to serial port area |
bieleluk | 3:3d7837ae4a37 | 56 | continue; |
bieleluk | 12:a8ab6e018422 | 57 | }else if (sign == 'k' || sign == 'K'){ // if i was pressed, show register on higher address |
bieleluk | 12:a8ab6e018422 | 58 | address -= 0x4; // return cursor position to serial port area |
bieleluk | 3:3d7837ae4a37 | 59 | continue; |
bieleluk | 12:a8ab6e018422 | 60 | }else if (sign == 'r' || sign == 'R'){ // if r was pressed, insert new address value |
bieleluk | 13:92533bcf6542 | 61 | pc.printf("\r\e[K\e[12;0H\r\e[K\e[32;40m use l or j to move the cursor, esc to delete value or enter to continue\e[97;40m"); |
bieleluk | 15:83d4dced2a28 | 62 | address = modify_value((address - address%4), 17); // insert or modify actual address(starting in 17th column) to read register value from it |
bieleluk | 3:3d7837ae4a37 | 63 | continue; |
bieleluk | 12:a8ab6e018422 | 64 | }else if (sign == 'w' || sign == 'W'){ // if r was pressed, insert address value and register value to write register value on that address |
bieleluk | 13:92533bcf6542 | 65 | pc.printf("\r\e[K\e[12;0H\r\e[K\e[32;40m use l or j to move the cursor, esc to delete value or enter to continue\e[97;40m"); |
bieleluk | 15:83d4dced2a28 | 66 | address = modify_value((address - address%4), 17); // insert or modify actual address(starting in 17th column) to write register value on that address |
bieleluk | 15:83d4dced2a28 | 67 | pc.printf("\e[6;17H%8x", (address - address%4)); |
bieleluk | 13:92533bcf6542 | 68 | pc.printf("\e[12;0H\r\e[K\e[32;40m use l or j to move the cursor, esc to delete value or enter to continue\e[97;40m"); |
bieleluk | 15:83d4dced2a28 | 69 | reg = *((volatile unsigned int *)(address - address%4)); //read register value from address |
bieleluk | 13:92533bcf6542 | 70 | |
bieleluk | 13:92533bcf6542 | 71 | pc.printf("\e[10;10H"); |
bieleluk | 15:83d4dced2a28 | 72 | print_binary(reg); |
bieleluk | 15:83d4dced2a28 | 73 | |
bieleluk | 12:a8ab6e018422 | 74 | reg = modify_value(reg, 40); // insert or modify actual register value(starting in 40th column) to that write register value on address |
bieleluk | 15:83d4dced2a28 | 75 | *((volatile unsigned int *)(address - address%4)) = reg; // write new register value on the address |
bieleluk | 3:3d7837ae4a37 | 76 | continue; |
bieleluk | 3:3d7837ae4a37 | 77 | }else{ |
bieleluk | 3:3d7837ae4a37 | 78 | } |
bieleluk | 0:e36b454cc2e6 | 79 | } |
bieleluk | 0:e36b454cc2e6 | 80 | } |
bieleluk | 0:e36b454cc2e6 | 81 | |
bieleluk | 0:e36b454cc2e6 | 82 | // print formatted string to debug serial port |
bieleluk | 0:e36b454cc2e6 | 83 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 84 | int Debug_register::printf(const char* format, ...){ |
bieleluk | 12:a8ab6e018422 | 85 | |
bieleluk | 12:a8ab6e018422 | 86 | int ret = pc.printf(format); |
bieleluk | 12:a8ab6e018422 | 87 | return ret; |
bieleluk | 12:a8ab6e018422 | 88 | } |
bieleluk | 0:e36b454cc2e6 | 89 | |
bieleluk | 12:a8ab6e018422 | 90 | // read formatted string from debug serial port |
bieleluk | 12:a8ab6e018422 | 91 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 12:a8ab6e018422 | 92 | int Debug_register::scanf(const char* format, ...){ |
bieleluk | 12:a8ab6e018422 | 93 | |
bieleluk | 12:a8ab6e018422 | 94 | int ret = pc.scanf(format); |
bieleluk | 0:e36b454cc2e6 | 95 | return ret; |
bieleluk | 0:e36b454cc2e6 | 96 | } |
bieleluk | 0:e36b454cc2e6 | 97 | |
bieleluk | 0:e36b454cc2e6 | 98 | // print character to debug serial port |
bieleluk | 0:e36b454cc2e6 | 99 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 100 | int Debug_register::putc(int character){ |
bieleluk | 0:e36b454cc2e6 | 101 | return pc.putc(character); |
bieleluk | 0:e36b454cc2e6 | 102 | } |
bieleluk | 0:e36b454cc2e6 | 103 | |
bieleluk | 0:e36b454cc2e6 | 104 | // read character from debug serial port |
bieleluk | 0:e36b454cc2e6 | 105 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 106 | int Debug_register::getc(){ |
bieleluk | 0:e36b454cc2e6 | 107 | return pc.getc(); |
bieleluk | 0:e36b454cc2e6 | 108 | } |
bieleluk | 0:e36b454cc2e6 | 109 | |
bieleluk | 12:a8ab6e018422 | 110 | // check whether there is any character to read |
bieleluk | 12:a8ab6e018422 | 111 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 112 | bool Debug_register::readable(){ |
bieleluk | 0:e36b454cc2e6 | 113 | return pc.readable(); |
bieleluk | 0:e36b454cc2e6 | 114 | } |
bieleluk | 0:e36b454cc2e6 | 115 | |
bieleluk | 12:a8ab6e018422 | 116 | // check whether it is possible to write a sign to debug serial port |
bieleluk | 12:a8ab6e018422 | 117 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 2:478ba8b83e3f | 118 | bool Debug_register::writable(){ |
bieleluk | 2:478ba8b83e3f | 119 | return pc.writable(); |
bieleluk | 2:478ba8b83e3f | 120 | } |
bieleluk | 2:478ba8b83e3f | 121 | |
bieleluk | 0:e36b454cc2e6 | 122 | // clear screen from m line up to n line |
bieleluk | 0:e36b454cc2e6 | 123 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 0:e36b454cc2e6 | 124 | void Debug_register::clear_from_n_up_to_m(int m, int n){ |
bieleluk | 15:83d4dced2a28 | 125 | pc.printf("\033[%d;0H",m); // go to line m |
bieleluk | 0:e36b454cc2e6 | 126 | wait(0.1); |
bieleluk | 0:e36b454cc2e6 | 127 | while (m > n){ |
bieleluk | 0:e36b454cc2e6 | 128 | m--; |
bieleluk | 15:83d4dced2a28 | 129 | pc.printf("\033[K\033[%d;0H",m); // clear lines until n-th line |
bieleluk | 0:e36b454cc2e6 | 130 | } |
bieleluk | 0:e36b454cc2e6 | 131 | pc.printf("\n\r"); |
bieleluk | 0:e36b454cc2e6 | 132 | |
bieleluk | 0:e36b454cc2e6 | 133 | } |
bieleluk | 0:e36b454cc2e6 | 134 | |
bieleluk | 15:83d4dced2a28 | 135 | // modify value of 32-bit number character by charater |
bieleluk | 15:83d4dced2a28 | 136 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 3:3d7837ae4a37 | 137 | uint32_t Debug_register::modify_value(uint32_t value, int horizontal){ |
bieleluk | 3:3d7837ae4a37 | 138 | |
bieleluk | 3:3d7837ae4a37 | 139 | uint32_t tmp = value; |
bieleluk | 15:83d4dced2a28 | 140 | char val_str[8]; // characters of bytes |
bieleluk | 15:83d4dced2a28 | 141 | int horizontal_min = horizontal; // position of first character |
bieleluk | 3:3d7837ae4a37 | 142 | char sign; |
bieleluk | 3:3d7837ae4a37 | 143 | |
bieleluk | 15:83d4dced2a28 | 144 | ESC_PUSHED: |
bieleluk | 15:83d4dced2a28 | 145 | pc.printf("\e[6;%dH", horizontal); // go to the begining of changed number |
bieleluk | 15:83d4dced2a28 | 146 | for (int i = 0; i < 8; i++){ // save actual value to individual characters |
bieleluk | 15:83d4dced2a28 | 147 | if ((tmp >> (28 - 4*i)) > 9){ // a, b, c, d, e, f |
bieleluk | 3:3d7837ae4a37 | 148 | val_str[i] = ((tmp >> (28 - 4*i)) + 87); |
bieleluk | 15:83d4dced2a28 | 149 | }else{ // 0, .. , 9 |
bieleluk | 3:3d7837ae4a37 | 150 | val_str[i] = ((tmp >> (28 - 4*i)) + 48); |
bieleluk | 3:3d7837ae4a37 | 151 | } |
bieleluk | 15:83d4dced2a28 | 152 | pc.putc(val_str[i]); // print character |
bieleluk | 3:3d7837ae4a37 | 153 | tmp -= ((tmp >> (28 - 4*i)) << (28 - 4*i)) ; |
bieleluk | 3:3d7837ae4a37 | 154 | } |
bieleluk | 15:83d4dced2a28 | 155 | pc.printf("\e[6;%dH", horizontal); // move cursor on the first char of value |
bieleluk | 9:59344a584e18 | 156 | |
bieleluk | 3:3d7837ae4a37 | 157 | |
bieleluk | 13:92533bcf6542 | 158 | |
bieleluk | 3:3d7837ae4a37 | 159 | while(1){ |
bieleluk | 3:3d7837ae4a37 | 160 | sign = pc.getc(); |
bieleluk | 15:83d4dced2a28 | 161 | if (sign == 13){ // if enter was received, save inserted value and end the function |
bieleluk | 15:83d4dced2a28 | 162 | value = (uint32_t)strtol(val_str, NULL, 16); // save inserted chars to number |
bieleluk | 3:3d7837ae4a37 | 163 | break; |
bieleluk | 15:83d4dced2a28 | 164 | }else if(sign == 'l' || sign == 'L'){ // move cursor one position right |
bieleluk | 3:3d7837ae4a37 | 165 | horizontal = min(horizontal+1,horizontal_min+7); |
bieleluk | 3:3d7837ae4a37 | 166 | pc.printf("\e[6;%dH",horizontal ); |
bieleluk | 3:3d7837ae4a37 | 167 | continue; |
bieleluk | 15:83d4dced2a28 | 168 | }else if(sign == 'j' || sign == 'J'){ // move cursor one position left |
bieleluk | 3:3d7837ae4a37 | 169 | horizontal = max(horizontal-1,horizontal_min); |
bieleluk | 3:3d7837ae4a37 | 170 | pc.printf("\e[6;%dH", horizontal); |
bieleluk | 3:3d7837ae4a37 | 171 | continue; |
bieleluk | 15:83d4dced2a28 | 172 | }else if ( ((sign >= 48 && sign <= 57) || (sign >= 65 && sign <= 70) || (sign >= 97 && sign <= 102)) && horizontal <= horizontal_min + 7 ){ // if allowed char for hexa number was received |
bieleluk | 15:83d4dced2a28 | 173 | if (sign >= 65 && sign <= 70){ // uppercase letter(a,b,c,d,e,f) was inserted |
bieleluk | 15:83d4dced2a28 | 174 | val_str[horizontal - horizontal_min] = sign+32; // save lowercase letter |
bieleluk | 15:83d4dced2a28 | 175 | pc.putc(sign+32); // print sign to serial port |
bieleluk | 3:3d7837ae4a37 | 176 | }else{ |
bieleluk | 15:83d4dced2a28 | 177 | val_str[horizontal - horizontal_min] = sign; // save as character |
bieleluk | 15:83d4dced2a28 | 178 | pc.putc(sign); // print character |
bieleluk | 3:3d7837ae4a37 | 179 | } |
bieleluk | 15:83d4dced2a28 | 180 | if (horizontal == (horizontal_min+7)){ // if cursor exceeded position of number |
bieleluk | 15:83d4dced2a28 | 181 | pc.putc('\b'); // return one char back |
bieleluk | 3:3d7837ae4a37 | 182 | }else{ |
bieleluk | 15:83d4dced2a28 | 183 | horizontal++; // move one character to the right |
bieleluk | 3:3d7837ae4a37 | 184 | } |
bieleluk | 3:3d7837ae4a37 | 185 | continue; |
bieleluk | 15:83d4dced2a28 | 186 | }else if(sign == 27){ // if esc was received, clear erase inserted number |
bieleluk | 15:83d4dced2a28 | 187 | horizontal = horizontal_min; // go to the first charaacter of number |
bieleluk | 15:83d4dced2a28 | 188 | tmp = value; //load original value |
bieleluk | 15:83d4dced2a28 | 189 | goto ESC_PUSHED; |
bieleluk | 3:3d7837ae4a37 | 190 | } |
bieleluk | 3:3d7837ae4a37 | 191 | } |
bieleluk | 3:3d7837ae4a37 | 192 | return value; |
bieleluk | 15:83d4dced2a28 | 193 | } |
bieleluk | 15:83d4dced2a28 | 194 | |
bieleluk | 15:83d4dced2a28 | 195 | // print entire breakpoint |
bieleluk | 15:83d4dced2a28 | 196 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 15:83d4dced2a28 | 197 | void Debug_register::print_break(uint32_t address){ |
bieleluk | 15:83d4dced2a28 | 198 | uint32_t reg = *((volatile unsigned int *)(address - address%4)); //read register value from address |
bieleluk | 15:83d4dced2a28 | 199 | pc.printf("---------------------------------------------------------------------------------------------------------\n\r"); |
bieleluk | 15:83d4dced2a28 | 200 | pc.printf("| address hex 0x%8x | value hex 0x%8x | address decimal %10u | value decimal %10u |\n\r", (address - address%4), reg, (address - address%4), reg); |
bieleluk | 15:83d4dced2a28 | 201 | pc.printf("---------------------------------------------------------------------------------------------------------\n\r"); |
bieleluk | 15:83d4dced2a28 | 202 | pc.printf("|bit_num|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|\n\r"); |
bieleluk | 15:83d4dced2a28 | 203 | pc.printf("---------------------------------------------------------------------------------------------------------\n\r|bit_val|"); |
bieleluk | 15:83d4dced2a28 | 204 | print_binary(reg); |
bieleluk | 15:83d4dced2a28 | 205 | pc.printf("\n\r---------------------------------------------------------------------------------------------------------\n\r"); |
bieleluk | 15:83d4dced2a28 | 206 | } |
bieleluk | 15:83d4dced2a28 | 207 | |
bieleluk | 15:83d4dced2a28 | 208 | // print 32-bit number in binary form |
bieleluk | 15:83d4dced2a28 | 209 | //------------------------------------------------------------------------------------------------------------------ |
bieleluk | 15:83d4dced2a28 | 210 | void Debug_register::print_binary(uint32_t value){ |
bieleluk | 15:83d4dced2a28 | 211 | for (int i = 0; i < 32; i++){ |
bieleluk | 15:83d4dced2a28 | 212 | pc.printf("%2d|",value >> (31 - i)); |
bieleluk | 15:83d4dced2a28 | 213 | value -= ((value >> (31 - i)) << (31 - i)); |
bieleluk | 15:83d4dced2a28 | 214 | } |
bieleluk | 15:83d4dced2a28 | 215 | } |