【esp32 控制台】-命令
文章目录
- 1 esp32控制台简介
- 2 控制台命令编程
- 2.1 控制台配置
- 交互设备初始化
- 控制台初始化
- 等待命令输入
- 2.2 命令实现
- 2.2.1 命令注册
- 踩坑记录
1 esp32控制台简介
可以通过idf.py monitor
调出idf的控制台,结束控制台用ctrl + ]
。
esp32的控制台就像linux中的shell一样,可以通过命令对程序进行配置。主要用于开发调试、系统监控和交互式操作。
控制台的作用
- 调试输出:显示程序运行时的日志信息、调试信息和错误消息
- 交互式命令:允许开发者通过命令行与 ESP32 交互
- 系统监控:查看内存使用情况、任务状态等系统信息
- 参数配置:设置和修改系统参数
- 固件更新:通过串口进行固件升级
2 控制台命令编程
控制台命令编程主要有两部分
1)控制台配置
2)命令实现
2.1 控制台配置
控制台配置包含如下几个部分
1)交互设备初始化(可以使用串口,USB CDC(虚拟串口),JTAG)
2)控制台初始化
3)等待命令输入
交互设备初始化
这一步必须要设置,即使用的usrt0,也要重新对串口进行设置。否则会看到串口一直输出数据。
串口设置包括如下内容:
- 文件虚拟化
- 配置串口数据(波特率、数据位、停止位、校验位等)
- 安装驱动
代码如下:
void initialize_console_peripheral(void)
{fflush(stdout);fsync(fileno(stdout));uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);const uart_config_t uart_config = {.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,.data_bits = UART_DATA_8_BITS,.parity = UART_PARITY_DISABLE,.stop_bits = UART_STOP_BITS_1,
#if SOC_UART_SUPPORT_REF_TICK.source_clk = UART_SCLK_REF_TICK,
#elif SOC_UART_SUPPORT_XTAL_CLK.source_clk = UART_SCLK_XTAL,
#endif};ESP_ERROR_CHECK( uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0) );ESP_ERROR_CHECK( uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config) );uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);setvbuf(stdin, NULL, _IONBF, 0);
}
控制台初始化
控制台的初始化包括控制台每行最大字节数,参数个数最大值,控制台字符输出颜色,是否使用tab建,历史记录功能等的配置。这时候需要用到linenoise
库对控制台进行设置。
/* 控制台设置 */
void initialize_console_config()
{esp_console_config_t console_config = {.max_cmdline_length = CONSOLE_MAX_CMDLINE_LENGTE,.max_cmdline_args = CONSOLE_MAX_CMDLINE_ARGS,.hint_color = atoi(CONSOLE_COLOR),};esp_console_init(&console_config);/* 使用多行编辑 */linenoiseSetMultiLine(1); // 命令在一行显示不完全会自动换行/* 使用tab建 */linenoiseSetCompletionCallback(&esp_console_get_completion);linenoiseSetHintsCallback((linenoiseHintsCallback *) &esp_console_get_hint);linenoiseSetMaxLineLen(console_config.max_cmdline_length);linenoiseAllowEmpty(false); // 空行时 linenosie的返回值是NULL// /* 设置历史记录设置 */// linenoiseHistorySetMaxLen(100);// linenoiseSetMaxLineLen(console_config.max_cmdline_length);// linenoiseHistoryLoad(history_patch);// const int probe_status = linenoiseProbe();// if (probe_status) {// linenoiseSetDumbMode(1);// }
}
等待命令输入
调用linenosie()
函数,此函数需要一直在while中循环。
1)在调用linenoise函数之前需要调用命令注册函数
2)每次执行完命令之后都需要调用linenoiseFree
函数释放命令
3)在退出主函数是需要调用esp_console_deinit
注销控制台
void app_main(void *pvParameters) {initialize_console_peripheral();initialize_console_config();/* 注册信息 */esp_console_register_help_command();register_wifi();register_led();while(1) {char* line = linenoise(PROMPT); // PROMPT 为提示符 "esp32->"if (line == NULL) { // linenoiseSllowEmpty设置为false时,空行返回NULLcontinue;}int ret;esp_err_t err = esp_console_run(line, &ret); // 执行控制台命令if (err == ESP_ERR_NOT_FOUND) {printf("Unrecognized command\n");} else if (err == ESP_ERR_INVALID_ARG) {// command was empty} else if (err == ESP_OK && ret != ESP_OK) {printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));} else if (err != ESP_OK) {printf("Internal error: %s\n", esp_err_to_name(err));}/* 释放line */linenoiseFree(line);}/* 注销控制台 */esp_console_deinit();
}
2.2 命令实现
命令实现需要使用到argtable3
库,该库的主要作用是对参数进行解析。
命令实现主要分为如下两个部分:
1)命令注册
2)参数解析
2.2.1 命令注册
命令注册和命令解析都需要用到一个用来保存命令参数的结构体,该结构体根据需要自定义,结构体中参数类型是argtable3
中的类型。结构体定义类似如下形式:
static struct {struct arg_str *color; // 也可以是arg_int、arg_file等类型struct arg_str *status;struct arg_end *end; // 参数的结束,必须有
}led_args;
命令注册格式如下:
1)定义参数
2)定义命令结构体
3)注册命令
void register_led(void)
{// 定义参数led_args.color = arg_str0(NULL, NULL, "[r g b]", "led color");led_args.status = arg_str1(NULL, NULL, "[on off shine]", "led status ");led_args.end = arg_end(2); // 2为参数最大长度// 定义命令结构体const esp_console_cmd_t led_cmd = {.command = "led", // 命令名称.help = "control led status", // 提示信息.func = led_parse, // 命令解析函数.argtable = &led_args, // 命令参数结构体};// 注册命令esp_console_cmd_register(&led_cmd);
}
arg_str0:定义一个可选参数
struct arg_str* arg_str0(const char* shortopts, // 长选项const char* longopts, // 短选项const char* datatype, // 参数占位符,提示用户输入格式const char* glossary // 帮助信息,说明参数用途
)
arg_str1:定义一个必选参数,参数含义同上
arg_end(n):标记参数解析结束,并指定最大参数数量n
esp_console_cmd_register():注册命令
该函数会将命令注册到命令列表中,执行命令的时候,esp_console_run()函数会根据命令名称找到对应的命令执行命令。
踩坑记录
1、配置控制台的时候没有配置串口
2、wifi链接报错堆栈错误,内容如图
Stack pointer:0x3fca01c0stack bounds:0x3fca01ec - 0x3fca09e0
错误产生原因:堆栈溢出,因为wifi的启动是在cmd_task任务重的,导致堆栈内存不足
解决方法:增加cmd_task任务内存
3、wifi连接时默认循环事件 esp_event_loop_create_default
只能创建一次,不能多次创建,