Debugging tool for mbed enabled microcontrollers, especially for NUCLEO-F303RE and STM32F042F6P6.
Debug.h
- Committer:
- bieleluk
- Date:
- 2021-03-21
- Revision:
- 24:014f13c3f871
- Parent:
- 23:e1ffe5277331
- Child:
- 25:cda8a4f9874a
File content as of revision 24:014f13c3f871:
#pragma once // include libraries //------------------------------------------------------------------------------------------------------------------ #include "mbed.h" #include <stdlib.h> // macros //------------------------------------------------------------------------------------------------------------------ #define name(var) #var #define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b)) typedef enum { GND = 0, BUTTON_GND = 0, VDD = 1, BUTTON_VDD = 1, VCC = 1, BUTTON_VCC = 1, } button_mode; //------------------------------------------------------------------------------------------------------------------ /** Debug_serial class. * Class for stepping the program, printing the curent position of breakpoint and optional print of one variable (int, float, char or char*). * Functions printf, putc and getc are also defined in the class. \n * * Example program for STM32F042F6P6:: * @code * // ---------------------------------------------------------------------------- * // Example program of Debug_serial class for STM32F042F6P6 * // Author: Lukas Bielesch * // Department of Measurement, Czech technical university in Prague, Czech Republic * // Date of publication: 20. March 2021 * // ---------------------------------------------------------------------------- * #include "mbed.h" * #include "Debug.h" * * // two pwm generators based on one timer TIM1 * PwmOut led1(PA_7); * PwmOut led2(PB_1); * * // debug serial port on PA_2 and PA_3 with default baudrate of 115200 Bd/s * Debug_serial pc(PA_2, PA_3); * * int main(){ * * float float_var = 3.14; * int int_var = 42; * char* str_var = "this is string"; * * // class Debug_serial works as normal serial port * pc.printf("insert character\n\r"); * while (!pc.readable()){} * pc.printf("you have inserted %c\n\r", pc.getc()); * * * led1.period(1); // set period of led1 to 1s * led1 = 0.6; // set stride of led1 to 60% * * // breakpoint with 3 parameters: line of the breakpoint, name and value of the variable to be shown * pc.breakpoint(__LINE__, name(float_var), float_var); * * // period of both LEDs is changed to 0.5s * led2.period(0.5); * * pc.breakpoint(__LINE__, name(int_var), int_var); * * // set stride of led2 to 40% * led2 = 0.4; * * pc.breakpoint(__LINE__, name(str_var), str_var); * * // period of both LEDs is changed to 2s * led2.period(2); * * // breakpoint with 2 parameters: line of the breakpoint and address of 4-byte word to be read * pc.breakpoint(__LINE__, 0x48000000); * * * pc.printf("end of program\n\r"); * * while(1){} * * } * @endcode */ class Debug_serial { public: /** Create object of Debug_serial class. * @param tx_pin TX pin of debug serial port * @param rx_pin RX pin of debug serial port * @param baudrate(optional) desired baudrate value of debug serial port, default baudrate is 115200 Bd/s */ Debug_serial(PinName tx_pin, PinName rx_pin, int baudrate = 115200); /** Perform one breakpoint. * @param line_number (optional) line number of breakpoint, macro __LINE__ could be used. */ void breakpoint(int line_number = -1); /** Perform one breakpoint and print variable of type int * @param line_number line number of breakpoint, macro __LINE__ could be used. * @param name name of printed variable(max length is 19) , macro name(variable) could be used. * @param variable variable of type int */ void breakpoint(int line_number, char name[20], int variable); /** Perform one breakpoint and print variable of type char * @param line_number line number of breakpoint, macro __LINE__ could be used. * @param name name of printed variable(max length is 19) , macro name(variable) could be used. * @param variable variable of type int */ void breakpoint(int line_number, char name[20], char variable); /** Perform one breakpoint and print string variable * @param line_number line number of breakpoint, macro __LINE__ could be used. * @param name name of printed variable(max length is 19) , macro name(variable) could be used. * @param variable variable of type char* */ void breakpoint(int line_number, char name[20], char * variable); /** Perform one breakpoint and print variable of type float * @param line_number line number of breakpoint, macro __LINE__ could be used. * @param name name of printed variable(max length is 19) , macro name(variable) could be used. * @param variable variable of type float */ void breakpoint(int line_number, char name[20], float variable); /** Perform one breakpoint and print one register value * @param line_number line number of breakpoint, macro __LINE__ could be used. * @param address address of register, must be divisible by 4 or it will be floored to value divisible by 4. */ void breakpoint(int line_number, uint32_t address); /** Print formatted string to debug serial port * @returns total number of printed characters or negative value if an output error or an encoding error */ int printf(const char* format, ...); /** Read formatted string from debug serial port * @returns total number of successfully read arguments or negative value if en error occured */ int scanf(const char* format, ...); /** Print one character to debug serial port * @param character * @returns character written as an unsigned char cast to an int */ int putc(int character); /** Read one character from debug serial port * @returns character written as an unsigned char cast to an int */ int getc(); /** Check whether there is some character available to read from debug serial port. * @returns true when there is something available to read */ bool readable(); /** Check whether it is possible to write a character to debug serial port. * @returns true when it is possible to write a character to debug serial port */ bool writable(); private: int break_line[3]; //store number of lines of three previous breakpoints char var[3][50]; //store variables of three previous breakpoints protected: // objects: Serial pc; //debug serial port // variables int breakpoint_count; //stores number of the current breakpoint // functions // initialization function void init(); // print 3 last breakpoints void print_3_breaks(int line_number); // print one breakpoint void print_one_break(int n); // clear screen from m line up to n line void clear_from_n_up_to_m(int m, int n); }; //------------------------------------------------------------------------------------------------------------------ /** Debug_led class. * Class for stepping the program with debug LED and button, that is connected to GND(default) or VCC. External pull up/down resistor does not have to be used.\n * Example program for STM32F042F6P6: * @code * // ---------------------------------------------------------------------------- * // Example program of Debug_led class for STM32F042F6P6 * // Author: Lukas Bielesch * // Department of Measurement, Czech technical university in Prague, Czech Republic * // Date of publication: 20. March 2021 * // ---------------------------------------------------------------------------- * #include "mbed.h" * #include "Debug.h" * * PwmOut pwm(PA_4); * DigitalOut led(PA_1); * Debug_led deb(PA_5, PA_7, GND); //debug led on PA_5, debug button connected to ground on PA_7 * * int main(){ * * led = 1; * deb.breakpoint(); // breakpoint with periodical flashing with 300 ms period until the button is pressed * pwm = 0.5; * pwm.period(1); * deb.breakpoint(2, 200); // breakpoint with periodical double-flashing with 200 ms period * * while(1){ * deb.breakpoint(3); // breakpoint with periodical triple-flashing until the button is pressed * pwm = pwm + 0.1f; * * //init pwm on the pin without pwm functionality causes MbedOS Error * // error message is sent to uart on PA_2 and PA_3 * PwmOut pwm2(PA_0); * * wait(2); * } * } * * @endcode */ // class Debug_led class Debug_led { public: /** Create an object of Debug_led class * @param led_pin pin of of debug led * @param button_pin pin of of debug button * @param mode mode of button connection(GND/VCC), default value value is GND */ Debug_led(PinName led_pin, PinName button_pin, button_mode mode = GND); /** Perform one breakpoint. * At first, the program waits until the the button is released (from the previous breakpoint). * Then it periodically flashes for number times with period of period_ms ms until the button is pressed, * @param number number of flashes of LED during the breakpoint, default value is 1 * @param period_ms period of flashing of the LED in ms, default value is 300ms */ void breakpoint(int number = 1, int period_ms = 300); private: // objects DigitalOut led; //debug led InterruptIn button; //debug button // variables int b_mode; // mode of button connection(GND = 0, VCC = 1) volatile bool end_breakpoint; //true when button was pushed // int number_of_breakpoints; //number of the current breakpoint /** Initialization */ void init(button_mode mode); /** Blink the debug led n-times with blink period wait_time_ms */ void flash_n_times(int wait_time_ms, int n); /** IRQ handler function, end breakpoint after the button is pushed */ void end_break(); }; //------------------------------------------------------------------------------------------------------------------ /** Debug_register class. * * Example program: * @code * // ---------------------------------------------------------------------------- * // Author: Lukas Bielesch * // Department of Measurement, Czech technical university in Prague, Czech Republic * // Date of publication: 15. Apr 2019 * // ---------------------------------------------------------------------------- * #include "Debug.h" * AnalogIn analog(PA_4); * PwmOut pwm(PA_6); * DigitalOut out(PA_5); * Debug_register pc(PA_2, PA_3, 115200); * * int main(){ * pc.breakpoint(__LINE__,0x48000000); * DigitalOut out2 (PA_0); * pc.breakpoint(__LINE__,0x48000001); * AnalogIn analog2 (PA_1); * pc.breakpoint(__LINE__,0x4800000C); * DigitalIn di1(PA_7, PullUp); * pc.breakpoint(__LINE__,0x4800000C); * pc.breakpoint(__LINE__,0x48000004); * while(1){ * if(pc.readable()){ * pc.putc(pc.getc()); * } * wait(0.1); * } * } * @endcode */ class Debug_register { public: /** Create object of Debug_register class * @param tx_pin TX pin of debug serial port * @param rx_pin RX pin of debug serial port * @param baudrate(optional) desired baudrate value of debug serial port, default baudrate is 115200 Bd/s */ Debug_register(PinName tx_pin, PinName rx_pin, int baudrate = 115200); /** Perform one breakpoint and print one register * @param line_number line number of breakpoint, macro __LINE__ is recommended * @param address address of register, must be divisible by 4 */ void breakpoint(int line_number, uint32_t address); /** Print formatted string to debug serial port * @returns total number of printed characters or negative value if an output error or an encoding error */ int printf(const char* format, ...); /** Read formatted string from debug serial port * @returns total number of successfully read arguments or negative value if en error occured */ int scanf(const char* format, ...); /** Print one character to debug serial port * @param character * @returns character written as an unsigned char cast to an int */ int putc(int character); /** Read one character from debug serial port * @returns character written as an unsigned char cast to an int */ int getc(); /** Check whether there is some character available to read from debug serial port. * @returns true when there is something available to read */ bool readable(); /** Check whether it is possible to write a character to debug serial port. * @returns true when it is possible to write a character to debug serial port */ bool writable(); protected: // objects: Serial pc; //debug serial device // variables: int breakpoint_count; //number of the current breakpoint // functions // initialization function void init(); // clear screen from m line up to n line void clear_from_n_up_to_m(int m, int n); // modify actual address or register value according to position in terminal uint32_t modify_value(uint32_t value, int horizontal); // print address and register value void print_break(uint32_t address); // print number in binary form void print_binary(uint32_t value); }; ////------------------------------------------------------------------------------------------------------------------ ///** Debug_register_print class. // * // * Example program: // * @code // * // ---------------------------------------------------------------------------- // * // Author: Lukas Bielesch // * // Department of Measurement, Czech technical university in Prague, Czech Republic // * // Date of publication: 15. Apr 2019 // * // ---------------------------------------------------------------------------- // * #include "Debug.h" // * AnalogIn analog(PA_4); // * PwmOut pwm(PA_6); // * DigitalOut out(PA_5); // * Debug_register_print pc(PA_2, PA_3, 115200); // * // * int main(){ // * pc.format(2,2,1,3);//breakpoint count,line number, address, value // * pc.breakpoint(__LINE__,0x48000001, 2); // * DigitalOut out2 (PA_0); // * pc.breakpoint(__LINE__,0x48000014, -3); // * AnalogIn analog2 (PA_1); // * pc.breakpoint(__LINE__,0x48000008); // * // * while(1){ // * wait(1); // * } // * } // * @endcode // */ class Debug_register_print { public: // /** Create object of Debug_register_print class // * @param tx_pin TX pin of debug serial port // * @param rx_pin RX pin of debug serial port // * @param baudrate(optional) desired baudrate value of debug serial port, default baudrate is 115200 Bd/s */ Debug_register_print(PinName tx_pin, PinName rx_pin, int baudrate = 115200); // /** Set format of breakpoint message // * @param break_number format of number of actual breakpoint: 0->not show, 1->show in hexadecimal, 2->show in decimal(default) // * @param line format of line of actual breakpoint: 0->not show, 1->show in hexadecimal, 2->show in decimal(default) // * @param address format of address of register: 0->not show, 1->show in hexadecimal(default), 2->show in decimal // * @param value format of register value: 0->not show, 1->show in hexadecimal, 2->show in decimal, 3->show in binary(default) // */ void format(int break_number = 2, int line = 2, int address = 1, int value = 3); // /** Perform one breakpoint and print one register value // * @param line_number line number of breakpoint, macro __LINE__ is recommended // * @param address address of register , must be divisible by 4 // */ void breakpoint(int line_number, uint32_t address, int number_of_words = 1); protected: // objects: Serial pc; //debug serial device // variables: int breakpoint_count; //number of the current breakpoint int count_format; // format of breakpoint count, 0->not show, 1->show in hexadecimal, 2->show in decimal int line_format; // format of lineof breakpoint, 0->not show, 1->show in hexadecimal, 2->show in decimal int address_format; // format of address of register, 0->not show, 1->show in hexadecimal, 2->show in decimal int register_format;// format of register value, 0->not show, 1->show in hexadecimal, 2->show in decimal, 3->show in binary // functions // initialization function void init(); };