网站开发项目经理岗位职责手机网址大全哪个好
2026/1/14 8:41:30 网站建设 项目流程
网站开发项目经理岗位职责,手机网址大全哪个好,wordpress有什么好看的主题,建设网站教程论坛一、整体结构说明 嵌入式系统#xff08;基于FreeRTOS#xff09;串口命令行调试工具#xff0c;采用模块化设计#xff0c;核心结构分层如下#xff1a;模块层级功能说明1. 配置与宏定义调试开关、缓冲区大小、密码/超时配置、硬件适配宏#xff08;UART/FreeRTOS#…一、整体结构说明嵌入式系统基于FreeRTOS串口命令行调试工具采用模块化设计核心结构分层如下模块层级功能说明1. 配置与宏定义调试开关、缓冲区大小、密码/超时配置、硬件适配宏UART/FreeRTOS2. 类型定义命令处理函数类型、命令表结构体、全局状态枚举3. 全局变量命令行缓冲、参数数组、认证/超时状态、命令表4. 基础工具函数UART硬件收发需用户适配、十六/十进制解析、字符串辅助函数5. 命令处理函数help/read/write/tasklist/info 核心功能实现6. 核心解析逻辑命令行分割、命令查找、主处理流程7. UART字符处理行缓冲、回显、退格、密码输入、超时检查8. 安全保护逻辑编译开关禁用、密码认证、超时自动登出9. 初始化与任务CLI初始化、FreeRTOS任务入口可选二、完整代码实现/************************************************************************* * 文件名: cli_debug_tool.c * 功能: 嵌入式串口命令行调试工具基于FreeRTOS * 适配: ARM Cortex-M系列需用户适配UART硬件驱动 * 编译开关: ENABLE_CLI_DEBUG - 启用调试工具生产版本注释/undef *************************************************************************/#includestdint.h#includestddef.h#includestring.h#includestdio.h/* 1. 配置与宏定义 */// 调试工具总开关生产版本注释此行或undef#defineENABLE_CLI_DEBUG1// UART硬件配置用户根据实际硬件修改#defineUART_BAUDRATE115200// 串口波特率#defineUART_TX_PIN0// 发送引脚示例#defineUART_RX_PIN1// 接收引脚示例// 命令行缓冲区配置#defineMAX_CMD_LENGTH128// 最大命令行长度#defineMAX_ARGC16// 最大参数个数#defineCMD_PROMPT // 命令行提示符// 安全保护配置#defineCLI_PASSWORDEmbedDebug2025// 认证密码#defineCLI_TIMEOUT_MS(5*60*1000)// 5分钟超时登出#defineADDR_VALID_MIN0x20000000// 合法内存起始地址SRAM#defineADDR_VALID_MAX0x20020000// 合法内存结束地址/* 2. 类型定义 */// 命令处理函数类型argc参数个数argv参数数组返回0成功/非0失败typedefint(*cmd_handler_t)(intargc,char*argv[]);// 命令表项结构体关联命令名、帮助信息、处理函数typedefstruct{constchar*cmd_name;// 命令名称如readconstchar*help_info;// 帮助描述cmd_handler_thandler;// 处理函数指针}cmd_entry_t;/* 3. 全局变量 */#ifdefENABLE_CLI_DEBUG// 命令行缓冲区存储用户输入的字符行缓冲staticcharcmd_buffer[MAX_CMD_LENGTH];staticuint8_tcmd_index0;// 缓冲区当前索引// 参数解析全局变量argc参数个数argv参数指针数组staticchar*argv[MAX_ARGC];staticintargc0;// 安全保护相关变量staticbool cli_authenticatedfalse;// 认证状态false未认证true已认证staticcharpassword_buffer[32];// 密码输入缓冲区staticuint8_tpassword_index0;// 密码缓冲区索引staticuint32_tlast_activity_time0;// 最后操作时间用于超时// FreeRTOS相关portTICK_PERIOD_MS需在FreeRTOSConfig.h中定义#ifndefportTICK_PERIOD_MS#defineportTICK_PERIOD_MS(1000/configTICK_RATE_HZ)#endif#endif/* 4. 基础工具函数 */#ifdefENABLE_CLI_DEBUG/************************************************************************* * 函数名: uart_send_char * 功能: 发送单个字符到UART需用户适配硬件驱动 * 参数: ch - 要发送的字符 * 返回: 无 *************************************************************************/voiduart_send_char(uint8_tch){// 【用户适配】替换为实际硬件UART发送函数// 示例伪代码// while(!UART_TX_BUFFER_EMPTY);// UART_DR_REG ch;}/************************************************************************* * 函数名: uart_send_string * 功能: 发送字符串到UART换行用\r\n适配串口终端 * 参数: str - 要发送的字符串 * 返回: 无 *************************************************************************/voiduart_send_string(constchar*str){if(strNULL)return;while(*str!\0){uart_send_char(*str);}}/************************************************************************* * 函数名: parse_hex * 功能: 解析十六进制字符串为32位无符号整数支持0x前缀 * 参数: str - 输入字符串如0x1234、FFvalue - 输出解析结果 * 返回: 0成功-1失败格式错误/空指针 *************************************************************************/staticintparse_hex(constchar*str,uint32_t*value){if(strNULL||valueNULL)return-1;// 跳过0x/0X前缀if(str[0]0(str[1]x||str[1]X)){str2;}*value0;while(*str!\0){charc*str;uint32_tdigit0;// 解析数字/字母if(c0c9){digitc-0;}elseif(cacf){digitc-a10;}elseif(cAcF){digitc-A10;}else{return-1;// 非法字符}*value(*value4)|digit;// 左移4位16进制 拼接}return0;}/************************************************************************* * 函数名: parse_dec * 功能: 解析十进制字符串为32位有符号整数支持负数 * 参数: str - 输入字符串如123、-456value - 输出解析结果 * 返回: 0成功-1失败格式错误/空指针 *************************************************************************/staticintparse_dec(constchar*str,int32_t*value){if(strNULL||valueNULL)return-1;intsign1;// 处理负号if(*str-){sign-1;str;}*value0;while(*str!\0){charc*str;if(c0c9){*value*value*10(c-0);}else{return-1;// 非法字符}}*value*sign;return0;}#endif/* 5. 命令处理函数实现 */#ifdefENABLE_CLI_DEBUG/************************************************************************* * 命令: help * 功能: 列出所有支持的命令及帮助信息 * 参数: argc - 参数个数argv - 参数数组无参数 * 返回: 0成功 *************************************************************************/staticintcmd_help(intargc,char*argv[]){uart_send_string(\r\n Available Commands \r\n);// 提前声明命令表避免编译报错externconstcmd_entry_tcmd_table[];// 遍历命令表格式化输出for(inti0;cmd_table[i].cmd_name!NULL;i){uart_send_string( );uart_send_string(cmd_table[i].cmd_name);// 对齐帮助信息命令名占12个字符宽度intname_lenstrlen(cmd_table[i].cmd_name);intspaces12-name_len;for(intj0;jspaces;j){uart_send_char( );}uart_send_string(cmd_table[i].help_info);uart_send_string(\r\n);}uart_send_string(\r\n);return0;}/************************************************************************* * 命令: read * 功能: 读取指定内存地址的32位值仅允许合法地址范围 * 参数: argc2argv[1]内存地址十六进制如0x20000000 * 返回: 0成功-1参数错误/地址非法 *************************************************************************/staticintcmd_read(intargc,char*argv[]){// 参数检查必须传入地址参数if(argc2){uart_send_string(Usage: read addr (hex, e.g. read 0x20000000)\r\n);return-1;}// 解析十六进制地址uint32_taddr;if(parse_hex(argv[1],addr)!0){uart_send_string(Error: Invalid hex address format\r\n);return-1;}// 地址合法性检查防止访问非法内存导致崩溃if(addrADDR_VALID_MIN||addrADDR_VALID_MAX){uart_send_string(Error: Address out of range ();uart_send_string(argv[1]);uart_send_string()\r\n);return-1;}// 读取内存volatile防止编译器优化确保读取实际内存volatileuint32_t*ptr(volatileuint32_t*)addr;uint32_tvalue*ptr;// 格式化输出结果charbuffer[64];snprintf(buffer,sizeof(buffer),Read: 0x%08X 0x%08X\r\n,addr,value);uart_send_string(buffer);return0;}/************************************************************************* * 命令: write * 功能: 写入32位值到指定内存地址仅允许合法地址范围 * 参数: argc3argv[1]地址十六进制argv[2]值十六进制 * 返回: 0成功-1参数错误/地址非法/写入失败 *************************************************************************/staticintcmd_write(intargc,char*argv[]){// 参数检查if(argc3){uart_send_string(Usage: write addr value (hex, e.g. write 0x20000000 0x12345678)\r\n);return-1;}// 解析地址uint32_taddr;if(parse_hex(argv[1],addr)!0){uart_send_string(Error: Invalid hex address format\r\n);return-1;}// 解析写入值uint32_tvalue;if(parse_hex(argv[2],value)!0){uart_send_string(Error: Invalid hex value format\r\n);return-1;}// 地址合法性检查if(addrADDR_VALID_MIN||addrADDR_VALID_MAX){uart_send_string(Error: Address out of range\r\n);return-1;}// 写入内存volatile确保写入实际内存volatileuint32_t*ptr(volatileuint32_t*)addr;*ptrvalue;// 验证写入结果if(*ptrvalue){charbuffer[64];snprintf(buffer,sizeof(buffer),Write OK: 0x%08X 0x%08X\r\n,addr,value);uart_send_string(buffer);return0;}else{uart_send_string(Error: Write failed (verify error)\r\n);return-1;}}/************************************************************************* * 命令: tasklist * 功能: 显示FreeRTOS任务列表、状态、栈使用情况 * 参数: 无 * 返回: 0成功-1内存分配失败 *************************************************************************/staticintcmd_tasklist(intargc,char*argv[]){uart_send_string(\r\n FreeRTOS Task List \r\n);uart_send_string(Name\t\tState\t\tStack High Water\r\n);uart_send_string(----------------------------------------\r\n);// 获取系统任务数量UBaseType_t num_tasksuxTaskGetNumberOfTasks();// 分配内存存储任务状态FreeRTOS动态内存TaskStatus_t*task_status(TaskStatus_t*)pvPortMalloc(num_tasks*sizeof(TaskStatus_t));if(task_statusNULL){uart_send_string(Error: Memory allocation failed\r\n);return-1;}// 获取所有任务状态num_tasksuxTaskGetSystemState(task_status,num_tasks,NULL);// 遍历任务列表格式化输出for(UBaseType_t i0;inum_tasks;i){charbuffer[128];constchar*state_str;// 转换任务状态为字符串switch(task_status[i].eCurrentState){caseeRunning:state_strRunning;break;caseeReady:state_strReady;break;caseeBlocked:state_strBlocked;break;caseeSuspended:state_strSuspended;break;caseeDeleted:state_strDeleted;break;default:state_strUnknown;break;}// 栈高水位剩余栈空间越小越危险uint32_tstack_hwtask_status[i].usStackHighWaterMark;// 格式化输出任务名占12字符状态占12字符snprintf(buffer,sizeof(buffer),%-12s\t%-12s\t%lu bytes\r\n,task_status[i].pcTaskName,state_str,stack_hw);uart_send_string(buffer);}// 释放内存vPortFree(task_status);uart_send_string(\r\n);return0;}/************************************************************************* * 命令: info * 功能: 显示系统基本信息运行时间、任务数、堆内存 * 参数: 无 * 返回: 0成功 *************************************************************************/staticintcmd_info(intargc,char*argv[]){uart_send_string(\r\n System Information \r\n);charbuffer[64];// 系统运行时间msuint32_tuptimexTaskGetTickCount()*portTICK_PERIOD_MS;snprintf(buffer,sizeof(buffer),Uptime: %lu ms (%lu s)\r\n,uptime,uptime/1000);uart_send_string(buffer);// 任务数量UBaseType_t num_tasksuxTaskGetNumberOfTasks();snprintf(buffer,sizeof(buffer),Total Tasks: %lu\r\n,num_tasks);uart_send_string(buffer);// 空闲任务栈剩余UBaseType_t idle_stackuxTaskGetStackHighWaterMark(NULL);snprintf(buffer,sizeof(buffer),Idle Task Stack Left: %lu bytes\r\n,idle_stack);uart_send_string(buffer);// 当前空闲堆内存size_tfree_heapxPortGetFreeHeapSize();snprintf(buffer,sizeof(buffer),Free Heap: %lu bytes\r\n,free_heap);uart_send_string(buffer);// 历史最小空闲堆反映内存峰值使用size_tmin_free_heapxPortGetMinimumEverFreeHeapSize();snprintf(buffer,sizeof(buffer),Min Free Heap: %lu bytes\r\n,min_free_heap);uart_send_string(buffer);uart_send_string(\r\n);return0;}#endif/* 6. 核心解析逻辑 */#ifdefENABLE_CLI_DEBUG/************************************************************************* * 函数名: parse_command * 功能: 将命令行字符串分割为参数数组argc/argv * 参数: cmd_line - 输入的命令行字符串如read 0x20000000 * 返回: 无 *************************************************************************/staticvoidparse_command(char*cmd_line){argc0;char*tokencmd_line;// 跳过前导空格/制表符while(*token ||*token\t){token;}// 分割字符串为参数while(*token!\0argcMAX_ARGC){argv[argc]token;// 记录参数起始地址// 查找参数结束位置空格/制表符while(*token! *token!\t*token!\0){token;}// 替换分隔符为字符串结束符if(*token!\0){*token\0;token;// 跳过连续分隔符while(*token ||*token\t){token;}}}}/************************************************************************* * 函数名: find_command * 功能: 根据命令名查找命令表中的对应项 * 参数: cmd_name - 要查找的命令名如read * 返回: 命令表项指针NULL未找到 *************************************************************************/staticconstcmd_entry_t*find_command(constchar*cmd_name){externconstcmd_entry_tcmd_table[];for(inti0;cmd_table[i].cmd_name!NULL;i){if(strcmp(cmd_table[i].cmd_name,cmd_name)0){returncmd_table[i];}}returnNULL;}/************************************************************************* * 函数名: process_command * 功能: 命令行主处理逻辑解析→查找→执行 * 参数: cmd_line - 输入的命令行字符串 * 返回: 无 *************************************************************************/staticvoidprocess_command(char*cmd_line){// 解析命令行为argc/argvparse_command(cmd_line);// 空命令直接返回if(argc0){return;}// 查找命令constcmd_entry_t*cmdfind_command(argv[0]);if(cmdNULL){uart_send_string(Error: Unknown command - );uart_send_string(argv[0]);uart_send_string(\r\n);return;}// 执行命令处理函数intresultcmd-handler(argc,argv);if(result!0){uart_send_string(Command execution failed\r\n);}}#endif/* 7. UART字符处理 */#ifdefENABLE_CLI_DEBUG/************************************************************************* * 函数名: cli_debug_process_char * 功能: 处理单个UART接收字符行缓冲、回显、退格、密码认证、超时检查 * 参数: ch - 接收到的字符 * 返回: 无 *************************************************************************/voidcli_debug_process_char(uint8_tch){// 1. 超时检查已认证且超时则登出uint32_tcurrent_timexTaskGetTickCount();if(cli_authenticated(current_time-last_activity_time)(CLI_TIMEOUT_MS/portTICK_PERIOD_MS)){cli_authenticatedfalse;uart_send_string(\r\n[Timeout] Session closed\r\nPassword: );password_index0;return;}last_activity_timecurrent_time;// 更新最后操作时间// 2. 未认证进入密码输入模式if(!cli_authenticated){// 回车验证密码if(ch\r||ch\n){password_buffer[password_index]\0;if(strcmp(password_buffer,CLI_PASSWORD)0){cli_authenticatedtrue;uart_send_string(\r\n[Success] Access granted\r\n);uart_send_string(CMD_PROMPT);// 显示命令提示符}else{uart_send_string(\r\n[Failed] Wrong password\r\nPassword: );}password_index0;// 重置密码缓冲区return;}// 退格/删除删除最后一个字符回显为← 空格 ←if(ch\b||ch0x7F){if(password_index0){password_index--;uart_send_string(\b \b);// 视觉上删除字符}return;}// 普通字符存入密码缓冲区回显为*隐藏明文if(password_indexsizeof(password_buffer)-1){password_buffer[password_index]ch;uart_send_char(*);// 不显示明文密码}return;}// 3. 已认证正常命令行处理// 回车执行命令if(ch\r||ch\n){uart_send_string(\r\n);// 换行cmd_buffer[cmd_index]\0;process_command(cmd_buffer);// 处理命令cmd_index0;// 重置命令缓冲区uart_send_string(CMD_PROMPT);// 显示提示符return;}// 退格/删除删除最后一个字符if(ch\b||ch0x7F){if(cmd_index0){cmd_index--;uart_send_string(\b \b);// 视觉删除}return;}// 普通字符存入缓冲区并回显if(cmd_indexMAX_CMD_LENGTH-1){cmd_buffer[cmd_index]ch;uart_send_char(ch);// 回显字符}}#endif/* 8. 命令表定义 */#ifdefENABLE_CLI_DEBUG// 命令表按命令名-帮助信息-处理函数关联最后一项为NULL结束constcmd_entry_tcmd_table[]{{help,Show all commands and usage,cmd_help},{read,Read 32-bit value from memory: read addr,cmd_read},{write,Write 32-bit value to memory: write addr val,cmd_write},{tasklist,Show FreeRTOS task list and stack info,cmd_tasklist},{info,Show system information (uptime/heap/tasks),cmd_info},{NULL,NULL,NULL}// 结束标记};#endif/* 9. 初始化与任务 *//************************************************************************* * 函数名: uart_init * 功能: UART硬件初始化需用户适配实际硬件 * 参数: 无 * 返回: 无 *************************************************************************/voiduart_init(void){#ifdefENABLE_CLI_DEBUG// 【用户适配】添加UART初始化代码// 1. 配置引脚复用TX/RX// 2. 设置波特率UART_BAUDRATE// 3. 启用接收中断或DMA// 4. 启用UART收发// 初始化完成后提示密码输入uart_send_string(\r\n Embedded CLI Debug Tool \r\n);uart_send_string(Please enter password: );last_activity_timexTaskGetTickCount();// 初始化超时时间#endif}/************************************************************************* * 函数名: cli_debug_task * 功能: FreeRTOS CLI任务可选若UART用中断接收则无需此任务 * 参数: pvParameters - 任务参数未使用 * 返回: 无 *************************************************************************/#ifdefENABLE_CLI_DEBUGvoidcli_debug_task(void*pvParameters){(void)pvParameters;uint8_tch;// 任务主循环while(1){// 【用户适配】读取UART接收字符非阻塞// 示例if (uart_rx_available()) { ch uart_read_char(); cli_debug_process_char(ch); }vTaskDelay(pdMS_TO_TICKS(10));// 10ms延时降低CPU占用}}#endif/************************************************************************* * 函数名: cli_debug_init * 功能: CLI调试工具初始化UART初始化 创建FreeRTOS任务 * 参数: 无 * 返回: 无 *************************************************************************/voidcli_debug_init(void){#ifdefENABLE_CLI_DEBUG// 初始化UARTuart_init();// 创建CLI处理任务优先级低于业务任务栈大小按需调整xTaskCreate(cli_debug_task,CLI_Task,1024,NULL,1,NULL);#else// 生产版本无操作#endif}/* 10. 生产版本兼容宏 */#ifndefENABLE_CLI_DEBUG// 生产版本空宏定义避免编译错误#definecli_debug_init()((void)0)#definecli_debug_process_char(ch)((void)0)#definecli_debug_task(pv)((void)0)#endif三、代码使用说明1. 硬件适配UART收发函数uart_send_char/uart_init需要用户根据实际MCU如STM32、NXP的HAL/LL库适配UART接收方式推荐用「中断接收」字符到达后调用cli_debug_process_char也可使用FreeRTOS任务轮询cli_debug_task内存地址范围修改ADDR_VALID_MIN/ADDR_VALID_MAX适配目标MCU的SRAM/Flash地址。2. 编译控制开发版本保留#define ENABLE_CLI_DEBUG 1编译时包含调试工具生产版本注释/删除ENABLE_CLI_DEBUG所有CLI相关函数会被空宏替换无代码冗余。3. 安全保护密码认证默认密码EmbedDebug2025建议根据项目修改超时登出5分钟无操作自动登出可修改CLI_TIMEOUT_MS调整内存保护read/write命令仅允许访问合法地址范围防止非法内存操作。4. 扩展命令添加新命令只需两步实现命令处理函数如cmd_xxx在cmd_table中添加一行{xxx, Help info, cmd_xxx}。四、典型使用流程设备上电后串口终端显示Please enter password:输入正确密码回显为*回车后显示提示符输入命令调试help查看所有命令read 0x20000000读取0x20000000地址的32位值write 0x20000000 0x12345678写入值到指定地址tasklist查看FreeRTOS任务状态info查看系统运行信息5分钟无操作自动登出需重新输入密码。五、关键注意事项中断安全若在UART中断中调用cli_debug_process_char需确保FreeRTOS API如xTaskGetTickCount在中断中可用启用configUSE_TIMERS栈大小cli_debug_task的栈大小1024需根据实际命令复杂度调整内存保护write命令禁止写入程序Flash/寄存器地址避免系统崩溃字符编码仅支持ASCII字符不支持中文兼容性代码基于FreeRTOS若使用其他RTOS需替换xTaskGetTickCount/uxTaskGetSystemState等API。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询