news 2026/4/27 11:28:33

嵌入式系统(基于FreeRTOS)串口命令行调试工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
嵌入式系统(基于FreeRTOS)串口命令行调试工具

一、整体结构说明

嵌入式系统(基于FreeRTOS)串口命令行调试工具,采用模块化设计,核心结构分层如下:

模块层级功能说明
1. 配置与宏定义调试开关、缓冲区大小、密码/超时配置、硬件适配宏(UART/FreeRTOS)
2. 类型定义命令处理函数类型、命令表结构体、全局状态枚举
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) *************************************************************************/#include<stdint.h>#include<stddef.h>#include<string.h>#include<stdio.h>/* ========================== 1. 配置与宏定义 ========================== */// 调试工具总开关:生产版本注释此行或undef#defineENABLE_CLI_DEBUG1// UART硬件配置(用户根据实际硬件修改)#defineUART_BAUDRATE115200// 串口波特率#defineUART_TX_PIN0// 发送引脚(示例)#defineUART_RX_PIN1// 接收引脚(示例)// 命令行缓冲区配置#defineMAX_CMD_LENGTH128// 最大命令行长度#defineMAX_ARGC16// 最大参数个数#defineCMD_PROMPT"> "// 命令行提示符// 安全保护配置#defineCLI_PASSWORD"EmbedDebug@2025"// 认证密码#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;// 命令名称(如"read")constchar*help_info;// 帮助描述cmd_handler_thandler;// 处理函数指针}cmd_entry_t;/* ========================== 3. 全局变量 ========================== */#ifdefENABLE_CLI_DEBUG// 命令行缓冲区:存储用户输入的字符(行缓冲)staticcharcmd_buffer[MAX_CMD_LENGTH];staticuint8_tcmd_index=0;// 缓冲区当前索引// 参数解析全局变量:argc=参数个数,argv=参数指针数组staticchar*argv[MAX_ARGC];staticintargc=0;// 安全保护相关变量staticbool cli_authenticated=false;// 认证状态:false=未认证,true=已认证staticcharpassword_buffer[32];// 密码输入缓冲区staticuint8_tpassword_index=0;// 密码缓冲区索引staticuint32_tlast_activity_time=0;// 最后操作时间(用于超时)// 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(str==NULL)return;while(*str!='\0'){uart_send_char(*str++);}}/************************************************************************* * 函数名: parse_hex * 功能: 解析十六进制字符串为32位无符号整数(支持0x前缀) * 参数: str - 输入字符串(如"0x1234"、"FF");value - 输出解析结果 * 返回: 0=成功,-1=失败(格式错误/空指针) *************************************************************************/staticintparse_hex(constchar*str,uint32_t*value){if(str==NULL||value==NULL)return-1;// 跳过0x/0X前缀if(str[0]=='0'&&(str[1]=='x'||str[1]=='X')){str+=2;}*value=0;while(*str!='\0'){charc=*str++;uint32_tdigit=0;// 解析数字/字母if(c>='0'&&c<='9'){digit=c-'0';}elseif(c>='a'&&c<='f'){digit=c-'a'+10;}elseif(c>='A'&&c<='F'){digit=c-'A'+10;}else{return-1;// 非法字符}*value=(*value<<4)|digit;// 左移4位(16进制)+ 拼接}return0;}/************************************************************************* * 函数名: parse_dec * 功能: 解析十进制字符串为32位有符号整数(支持负数) * 参数: str - 输入字符串(如"123"、"-456");value - 输出解析结果 * 返回: 0=成功,-1=失败(格式错误/空指针) *************************************************************************/staticintparse_dec(constchar*str,int32_t*value){if(str==NULL||value==NULL)return-1;intsign=1;// 处理负号if(*str=='-'){sign=-1;str++;}*value=0;while(*str!='\0'){charc=*str++;if(c>='0'&&c<='9'){*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(inti=0;cmd_table[i].cmd_name!=NULL;i++){uart_send_string(" ");uart_send_string(cmd_table[i].cmd_name);// 对齐帮助信息(命令名占12个字符宽度)intname_len=strlen(cmd_table[i].cmd_name);intspaces=12-name_len;for(intj=0;j<spaces;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位值(仅允许合法地址范围) * 参数: argc=2;argv[1]=内存地址(十六进制,如0x20000000) * 返回: 0=成功,-1=参数错误/地址非法 *************************************************************************/staticintcmd_read(intargc,char*argv[]){// 参数检查:必须传入地址参数if(argc<2){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(addr<ADDR_VALID_MIN||addr>ADDR_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位值到指定内存地址(仅允许合法地址范围) * 参数: argc=3;argv[1]=地址(十六进制);argv[2]=值(十六进制) * 返回: 0=成功,-1=参数错误/地址非法/写入失败 *************************************************************************/staticintcmd_write(intargc,char*argv[]){// 参数检查if(argc<3){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(addr<ADDR_VALID_MIN||addr>ADDR_VALID_MAX){uart_send_string("Error: Address out of range\r\n");return-1;}// 写入内存(volatile确保写入实际内存)volatileuint32_t*ptr=(volatileuint32_t*)addr;*ptr=value;// 验证写入结果if(*ptr==value){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_tasks=uxTaskGetNumberOfTasks();// 分配内存存储任务状态(FreeRTOS动态内存)TaskStatus_t*task_status=(TaskStatus_t*)pvPortMalloc(num_tasks*sizeof(TaskStatus_t));if(task_status==NULL){uart_send_string("Error: Memory allocation failed\r\n");return-1;}// 获取所有任务状态num_tasks=uxTaskGetSystemState(task_status,num_tasks,NULL);// 遍历任务列表,格式化输出for(UBaseType_t i=0;i<num_tasks;i++){charbuffer[128];constchar*state_str;// 转换任务状态为字符串switch(task_status[i].eCurrentState){caseeRunning:state_str="Running";break;caseeReady:state_str="Ready";break;caseeBlocked:state_str="Blocked";break;caseeSuspended:state_str="Suspended";break;caseeDeleted:state_str="Deleted";break;default:state_str="Unknown";break;}// 栈高水位:剩余栈空间(越小越危险)uint32_tstack_hw=task_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];// 系统运行时间(ms)uint32_tuptime=xTaskGetTickCount()*portTICK_PERIOD_MS;snprintf(buffer,sizeof(buffer),"Uptime: %lu ms (%lu s)\r\n",uptime,uptime/1000);uart_send_string(buffer);// 任务数量UBaseType_t num_tasks=uxTaskGetNumberOfTasks();snprintf(buffer,sizeof(buffer),"Total Tasks: %lu\r\n",num_tasks);uart_send_string(buffer);// 空闲任务栈剩余UBaseType_t idle_stack=uxTaskGetStackHighWaterMark(NULL);snprintf(buffer,sizeof(buffer),"Idle Task Stack Left: %lu bytes\r\n",idle_stack);uart_send_string(buffer);// 当前空闲堆内存size_tfree_heap=xPortGetFreeHeapSize();snprintf(buffer,sizeof(buffer),"Free Heap: %lu bytes\r\n",free_heap);uart_send_string(buffer);// 历史最小空闲堆(反映内存峰值使用)size_tmin_free_heap=xPortGetMinimumEverFreeHeapSize();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){argc=0;char*token=cmd_line;// 跳过前导空格/制表符while(*token==' '||*token=='\t'){token++;}// 分割字符串为参数while(*token!='\0'&&argc<MAX_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(inti=0;cmd_table[i].cmd_name!=NULL;i++){if(strcmp(cmd_table[i].cmd_name,cmd_name)==0){return&cmd_table[i];}}returnNULL;}/************************************************************************* * 函数名: process_command * 功能: 命令行主处理逻辑:解析→查找→执行 * 参数: cmd_line - 输入的命令行字符串 * 返回: 无 *************************************************************************/staticvoidprocess_command(char*cmd_line){// 解析命令行为argc/argvparse_command(cmd_line);// 空命令直接返回if(argc==0){return;}// 查找命令constcmd_entry_t*cmd=find_command(argv[0]);if(cmd==NULL){uart_send_string("Error: Unknown command - ");uart_send_string(argv[0]);uart_send_string("\r\n");return;}// 执行命令处理函数intresult=cmd->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_time=xTaskGetTickCount();if(cli_authenticated&&(current_time-last_activity_time)>(CLI_TIMEOUT_MS/portTICK_PERIOD_MS)){cli_authenticated=false;uart_send_string("\r\n[Timeout] Session closed\r\nPassword: ");password_index=0;return;}last_activity_time=current_time;// 更新最后操作时间// 2. 未认证:进入密码输入模式if(!cli_authenticated){// 回车:验证密码if(ch=='\r'||ch=='\n'){password_buffer[password_index]='\0';if(strcmp(password_buffer,CLI_PASSWORD)==0){cli_authenticated=true;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_index=0;// 重置密码缓冲区return;}// 退格/删除:删除最后一个字符(回显为"← 空格 ←")if(ch=='\b'||ch==0x7F){if(password_index>0){password_index--;uart_send_string("\b \b");// 视觉上删除字符}return;}// 普通字符:存入密码缓冲区,回显为*(隐藏明文)if(password_index<sizeof(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_index=0;// 重置命令缓冲区uart_send_string(CMD_PROMPT);// 显示提示符return;}// 退格/删除:删除最后一个字符if(ch=='\b'||ch==0x7F){if(cmd_index>0){cmd_index--;uart_send_string("\b \b");// 视觉删除}return;}// 普通字符:存入缓冲区并回显if(cmd_index<MAX_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_time=xTaskGetTickCount();// 初始化超时时间#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. 安全保护
  • 密码认证:默认密码EmbedDebug@2025,建议根据项目修改;
  • 超时登出:5分钟无操作自动登出,可修改CLI_TIMEOUT_MS调整;
  • 内存保护read/write命令仅允许访问合法地址范围,防止非法内存操作。
4. 扩展命令

添加新命令只需两步:

  1. 实现命令处理函数(如cmd_xxx);
  2. cmd_table中添加一行:{"xxx", "Help info", cmd_xxx}

四、典型使用流程

  1. 设备上电后,串口终端显示Please enter password:
  2. 输入正确密码(回显为*),回车后显示提示符>
  3. 输入命令调试:
    • help:查看所有命令;
    • read 0x20000000:读取0x20000000地址的32位值;
    • write 0x20000000 0x12345678:写入值到指定地址;
    • tasklist:查看FreeRTOS任务状态;
    • info:查看系统运行信息;
  4. 5分钟无操作自动登出,需重新输入密码。

五、关键注意事项

  1. 中断安全:若在UART中断中调用cli_debug_process_char,需确保FreeRTOS API(如xTaskGetTickCount)在中断中可用(启用configUSE_TIMERS);
  2. 栈大小cli_debug_task的栈大小(1024)需根据实际命令复杂度调整;
  3. 内存保护write命令禁止写入程序Flash/寄存器地址,避免系统崩溃;
  4. 字符编码:仅支持ASCII字符,不支持中文;
  5. 兼容性:代码基于FreeRTOS,若使用其他RTOS,需替换xTaskGetTickCount/uxTaskGetSystemState等API。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:35:05

实战避坑指南:小爱音箱变身智能AI助手的性能优化全攻略

实战避坑指南&#xff1a;小爱音箱变身智能AI助手的性能优化全攻略 【免费下载链接】mi-gpt &#x1f3e0; 将小爱音箱接入 ChatGPT 和豆包&#xff0c;改造成你的专属语音助手。 项目地址: https://gitcode.com/GitHub_Trending/mi/mi-gpt 还在为小爱音箱的"人工智…

作者头像 李华
网站建设 2026/4/23 18:52:35

探索ChinaAdminDivisonSHP:地理数据背后的数字艺术

为什么这个项目改变了地理数据处理方式&#xff1f; 【免费下载链接】ChinaAdminDivisonSHP 项目地址: https://gitcode.com/gh_mirrors/ch/ChinaAdminDivisonSHP 在数字时代&#xff0c;地理数据如同城市的脉络&#xff0c;而ChinaAdminDivisonSHP项目就像一位精心的城…

作者头像 李华
网站建设 2026/4/23 12:33:51

无人水下航行器(UUV)仿真研究附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

作者头像 李华
网站建设 2026/4/18 7:53:49

Linux tcpdump抓包实践(以http为例)

捕获HTTP流量并保存为wireshark格式文件(pcap格式文件)‌基本命令‌&#xff1a;使用tcpdump捕获所有流量的基本命令如下&#xff1a;sudo tcpdump -i any -w output.pcap port 80 or port 443这里&#xff0c;-i any表示监听所有网络接口&#xff0c;-w output.pcap指定输出文…

作者头像 李华
网站建设 2026/4/18 7:33:34

LobeChat能否实现AI评分系统?答案质量自动评估模型

LobeChat能否实现AI评分系统&#xff1f;答案质量自动评估模型 在大语言模型&#xff08;LLM&#xff09;日益渗透企业服务与个人应用的今天&#xff0c;一个隐性却关键的问题浮出水面&#xff1a;我们如何判断AI给出的回答到底好不好&#xff1f; 无论是智能客服、教育辅导还是…

作者头像 李华
网站建设 2026/4/27 6:08:25

polar2025年秋季个人挑战赛(困难部分)

狗黑子的eval 查看源码并没有什么信息&#xff0c;小习惯&#xff0c;扫一下目录 我们查看下 我们看admin.php 查看源代码 有一个payload.php <?php highlight_file(__FILE__); //goua,gougoub; $gou1"12gou";$gou5"16gou";$gou4"5gou";$g…

作者头像 李华