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

debug_serial.cpp

Committer:
bieleluk
Date:
2021-03-21
Revision:
25:cda8a4f9874a
Parent:
22:ac9b2cbb31a8

File content as of revision 25:cda8a4f9874a:

#include "Debug.h"

// create object of class Debug_serial
//------------------------------------------------------------------------------------------------------------------ 
Debug_serial::Debug_serial(PinName tx_pin, PinName rx_pin, int baudrate) : pc(tx_pin,rx_pin, baudrate) {
    init();
}

// init function
//------------------------------------------------------------------------------------------------------------------ 
void Debug_serial::init() {
    pc.printf("\ec"); //clear entire screen
    wait_ms(50); //wait until clearing is done
    pc.printf("-----------------\n\r|\e[1m\e[97;40m\e[93;40mBREAKPOINT AREA\e[22m\e[97;40m|\n\r-----------------\n\r\033[s");
    pc.printf("serial successfully initialised\n\r\e[32;40mto start program press any button\e[97;40m");
    breakpoint_count = 0; //set breakpoint count to 0
    pc.getc(); // wait until user sends any character
    pc.printf("\r\e[2K\e[31;40mprogram is running\e[97;40m\r");
    
    // information about last three breakpoints
    break_line[0] = -1;
    break_line[1] = -1;
    break_line[2] = -1;
    strcpy(var[0], "\0");
    strcpy(var[1], "\0");
    strcpy(var[2], "\0");
    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");
}

// perform one breakpoint without printing variable
//------------------------------------------------------------------------------------------------------------------  
void Debug_serial::breakpoint(int line_number) {
    strcpy(var[2], var[1]);
    strcpy(var[1], var[0]);
    sprintf(var[0],"\0");
    print_3_breaks(line_number);     
}

// perform one breakpoint and print variable of type int
//------------------------------------------------------------------------------------------------------------------  
void Debug_serial::breakpoint(int line_number, char name[20], int variable){

    strcpy(var[2], var[1]);
    strcpy(var[1], var[0]);
    sprintf(var[0],"int %s = %d",name,variable);
    print_3_breaks(line_number);

}

// perform one breakpoint and print variable of type char
//------------------------------------------------------------------------------------------------------------------ 
void Debug_serial::breakpoint(int line_number, char name[20], char variable){

    strcpy(var[2], var[1]);
    strcpy(var[1], var[0]);
    sprintf(var[0],"char %s = %c",name,variable);
    print_3_breaks(line_number);
    
}

// perform one breakpoint and print variable of type float
//------------------------------------------------------------------------------------------------------------------ 
void Debug_serial::breakpoint(int line_number, char name[20], float variable){
   
    strcpy(var[2], var[1]);
    strcpy(var[1], var[0]);
    sprintf(var[0],"float %s = %f",name,variable);
    print_3_breaks(line_number);

}

// perform one breakpoint and print variable of type string
//------------------------------------------------------------------------------------------------------------------ 
void Debug_serial::breakpoint(int line_number, char name[20], char * variable){

    strcpy(var[2], var[1]);
    strcpy(var[1], var[0]);
    sprintf(var[0],"string %s = %s",name,variable);
    print_3_breaks(line_number);

}

// perform one breakpoint and print register
//------------------------------------------------------------------------------------------------------------------ 
void Debug_serial::breakpoint(int line_number, uint32_t address){

    strcpy(var[2], var[1]);
    strcpy(var[1], var[0]);
    sprintf(var[0],"Address 0x%8x   Value 0x%8x", address - address%4, *((volatile unsigned int *)(address - address % 4)));
    print_3_breaks(line_number);

}
// print formatted string to debug serial port
//------------------------------------------------------------------------------------------------------------------ 
int Debug_serial::printf(const char* format, ...){
    
    int ret = pc.printf(format);
    return ret;
}

// read formatted string from debug serial port
//------------------------------------------------------------------------------------------------------------------ 
int Debug_serial::scanf(const char* format, ...){
    
    int ret = pc.scanf(format);
    return ret;
}

// print character to debug serial port
//------------------------------------------------------------------------------------------------------------------ 
int Debug_serial::putc(int character){
    return pc.putc(character);
}

// read character from debug serial port
//------------------------------------------------------------------------------------------------------------------ 
int Debug_serial::getc(){
    return pc.getc();
}

// check whether there is any character to read
//------------------------------------------------------------------------------------------------------------------ 
bool Debug_serial::readable(){
    return pc.readable();
}

// check whether it is possible to write a sign to debug serial port
//------------------------------------------------------------------------------------------------------------------ 
bool Debug_serial::writable(){
    return pc.writable();
}

// clear screen from m line up to n line
//------------------------------------------------------------------------------------------------------------------
void Debug_serial::clear_from_n_up_to_m(int m, int n){
    pc.printf("\033[%d;0H",m); //replace cursor to m-th row, 0 column
    wait(0.1);
    while (m > n){ 
        m--;
        pc.printf("\033[K\033[%d;0H",m); // clear entire line
    }
    pc.printf("\n\r");// go to new line

}

// print information about 3 last breakpoints
//------------------------------------------------------------------------------------------------------------------
void Debug_serial::print_3_breaks(int line_number){
    pc.printf("\e[s"); //save current cursor position
    wait_ms(50); // wait until saving is done
    breakpoint_count++;
    break_line[2] = break_line[1]; //save information about line of breakpoints
    break_line[1] = break_line[0];
    break_line[0] = line_number;
    
    clear_from_n_up_to_m(12,3); // clear screen from 12th to 3rd line
    
    int i = (breakpoint_count>=3)?3:breakpoint_count; //print 3 previous breakpoints if possible
    while (i > 0){
        if (i == 1 ){
            pc.printf("\e[96;40m"); //change color of the last breakpoint
            print_one_break(i);
            pc.printf("\e[22m\e[97;40m"); //return to normal color
        }else{
            print_one_break(i);        
        }
        i--;
    }  
    pc.printf("\e[32;40mto continue press any button\e[97;40m");
    pc.getc();
    pc.printf("\r\e[2K\e[31;40mprogram is running\e[97;40m\n\r");  
    pc.printf("\e[u"); // return cursor to serial port part
  
}

// print one breakpoint
//------------------------------------------------------------------------------------------------------------------
void Debug_serial::print_one_break(int n){
    if (break_line[n-1] < 0){
        pc.printf("Breakpoint number %d\t unknown line number\n\r%s\n\n\r",breakpoint_count - n + 1,var[n-1]);
    }else{
        pc.printf("Breakpoint number %d\tline number %d\n\r%s\n\n\r",breakpoint_count - n + 1,break_line[n-1],var[n-1]);
    }
}