Debugging tool for mbed enabled microcontrollers, especially for NUCLEO-F303RE and STM32F042F6P6.

Committer:
bieleluk
Date:
Sun Mar 21 20:43:16 2021 +0000
Revision:
25:cda8a4f9874a
Parent:
15:83d4dced2a28
;

Who changed what in which revision?

UserRevisionLine numberNew 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 }