# cx_debug **Repository Path**: char-x/cx_debug ## Basic Information - **Project Name**: cx_debug - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-11-29 - **Last Updated**: 2023-12-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### CX_Library::Debug #### Version 1.0 基本框架+示例代码   该库是依赖了格式化库cx_format和链表库cx_list以及C标准库stdio,string实现的一个高度硬件抽象的调试库,主要应用在裸机嵌入式平台串口调试(也可用于PC端控制台)。 ##### Macro - PUTC_ENABLED putc函数可用标志宏,用于debug库输出调试信息,若该宏不启用,则无法使用GET方法 ##### Enum typedef enum { CX_DATATYPE_INT8, CX_DATATYPE_UINT8, CX_DATATYPE_INT16, CX_DATATYPE_UINT16, CX_DATATYPE_INT32, CX_DATATYPE_UINT32, CX_DATATYPE_INT64, CX_DATATYPE_UINT64, CX_DATATYPE_FLOAT, CX_DATATYPE_DOUBLE, CX_DATATYPE_CHAR, CX_DATATYPE_STRING, }cx_datatype_t; 用于指明变量类型 ##### Struct - struct cx_debug_variable Member: - const char *name:变量名,检索变量时的关键词 - cx_datatype_t type:变量的数据类型,务必正确指定,因为使用SET方法时会对下面的pdata指针做相应的强制指针转换,若设置不当可能造成内存访问越界 - void * pdata:指向的实际内部变量的指针 - struct cx_debug_command Member: - const char *name:命令名称,检索命令时的关键词 - cx_cb_func_t handler: 命令回调函数格式为void (*func)(void *args),其中args为CMD中的参数部分    ##### Function - cx_err_t cx_debug_addVariable(cx_debug_variable_t *var);该函数用于注册一个监控变量 - var:变量结构体指针 - 返回值:CX_ERR_OK - cx_err_t cx_debug_addCommand(cx_debug_command_t *cmd);该函数用于注册一个命令 - cmd:命令结构体指针 - 返回值:CX_ERR_OK - cx_err_t cx_debug_handler(char *input); - input:出入的命令字符串,如:"SET a 100",设置变量a的值为100 - 返回值: - CX_ERR_OK,成功解析 - CX_ERR_NOMATCH, 命令错误,命令头不是SET GET 或 CMD - char * getStringField(char *dst, char *src);获取src字符串中的第一个值,同时返回下一个词的开始指针 - dst:提取出的字符串存放位置 - src:被解析的字符串 - 返回值:从提取该词后方第一个非空格字符位置指针,如果后方已经无有效字符,则返回CX_NULL 串口/命令行使用方法: SET Variable_name Value,设置变量值Variable_name=Value GET Variable_name,返回变量信息,名称,类型和值 CMD Command_name args,调用命令Command_name(args) ##### 示例代码片段(STM32 USART1) `````` C /**main.c**/ unsigned char led_status = 0; void led_controller(void) { if(led_status) { LED_ON(); } else { LED_OFF(); } } int main(void) { /**创建内部实际变量**/ int a = 0; cx_int16_t PWM_Compare; float f; char char_buf[100]; cx_debug_variable_t va = //声明一个调试变量 { .name = "a",// 名称为"a",检索式使用这个字符串,比如 SET a 100,变量a的值设置为100 .pdata = &a, //绑定到内部变量a .type = CX_DATATYPE_INT32 //声明变量类型为int32 }; cx_debug_variable_t vled = //同理 { .name = "led", .pdata = &led_status, .type = CX_DATATYPE_UINT8 }; cx_debug_variable_t cmp = { .name = "cmp", .pdata = &PWM_Compare, .type = CX_DATATYPE_INT16 }; cx_debug_variable_t vf = { .name = "f", .pdata = &f, .type = CX_DATATYPE_FLOAT }; cx_debug_command_t getInfo = //声明一个调试命令 { .name = "getInfo", // 命令名称是getInfo用法: CMD getInfo args(args也可以是空,后面这一串字符串都会传递到下面那个回调函数) .handler = print_all_variable_info //命令回调函数,例如CMD getInfo string 等价于内部执行print_all_variable_info("string"); }; /**以下五句用于将声明的调试变量和调试函数注册到内部,只有注册后才能被使用**/ cx_debug_addVariable(&va); cx_debug_addVariable(&vled); cx_debug_addVariable(&cmp); cx_debug_addVariable(&vf); cx_debug_addCommand(&getInfo); while(1) { led_controller(); } } /**stm32f10x_it.c**/ char debug_input[64]; //串口输入缓冲区 cx_uint8_t current_pos = 0; //下一个字符串该插入的位置 void USART2_IRQHandler(void) { if(USART_GetITFlags(USART1, USART_FLAGS_RXE) != RESET) { //接受中断,将受到的字符写入缓冲区,下一位置自增 debug_input[current_pos] = USART2->DR; current_pos++; USART_ClearITPendingBit(USART1, USART_FLAGS_RXE); } if(USART_GetITStatus(USART1, USART_FLAGS_IDLE) != RESET) { //总线空闲中断,也就是发送结束中断,标志一次接受已经结束,给最后一个位置写入'\0'作为字符串终结符,把输入的命令传入cx_debug_handler()处理。完成后复位写入位置(current_pos = 0) USART_ClearITPendingBit(USART1, USART_FLAGS_IDLE); USART_ClearFlag(USART1, USART_FLAGS_IDLE); USART_ReceiveData(USART1); // IDLE中断需要再加一句读取DR寄存器来清除中断标志位,否则会一直卡中断 debug_input[current_pos] = '\0'; current_pos = 0; cx_debug_handler(debug_input); } } `````` 串口命令: ````` Shell SET led 1/0 就可以开灯 GET led 即可获取led_status的值,返回格式是: name:led,type:uint8,value:led_status ```````