当前位置: 首页 > wzjs >正文

静态展示网站多少钱谷歌浏览器下载安装2022最新版

静态展示网站多少钱,谷歌浏览器下载安装2022最新版,福田网站建设费用,企业网站改版的好处文章目录 一、总体结构二、串口接收机制三、命令输入与处理逻辑四、命令编辑与显示五、历史命令管理六、命令执行七、初始化与使用八、小结 在嵌入式系统开发中,使用串口Shell控制台是一种非常常见且高效的调试方式。本文将基于STM32平台,分析一个简洁但…

文章目录

    • 一、总体结构
    • 二、串口接收机制
    • 三、命令输入与处理逻辑
    • 四、命令编辑与显示
    • 五、历史命令管理
    • 六、命令执行
    • 七、初始化与使用
    • 八、小结


在嵌入式系统开发中,使用串口Shell控制台是一种非常常见且高效的调试方式。本文将基于STM32平台,分析一个简洁但功能完整的Shell控制台实现,包括命令输入、编辑、历史记录以及命令执行等关键功能。

一、总体结构

该Shell控制台主要包含以下功能模块:

  1. 命令输入缓冲与解析
  2. 光标控制与编辑
  3. 命令历史管理
  4. 串口接收中断处理
  5. 命令执行与回显

二、串口接收机制

shell_uart_start_rx() 函数中,通过调用 HAL_UART_Receive_IT() 启动中断接收模式,确保串口能够异步接收字符:

HAL_UART_Receive_IT(&huart1, &uart_rx_ch, 1);

每当串口接收到一个字符,就会触发 HAL_UART_RxCpltCallback() 回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if (huart->Instance == USART1) {shell_input_char((char)uart_rx_ch);  // 处理字符HAL_UART_Receive_IT(&huart1, &uart_rx_ch, 1);  // 继续接收}
}

该回调函数负责将接收到的字符送入 shell_input_char() 进行处理,并重新启动中断接收。

三、命令输入与处理逻辑

shell_input_char(char ch) 是命令输入的核心处理函数,它处理普通字符、退格键、回车键、以及ESC转义序列(用于方向键)。

关键逻辑包括:

  • 普通字符:调用 shell_insert_char(ch) 插入到当前光标位置;
  • 回车键:调用 shell_handle_enter() 执行命令并保存历史;
  • 退格键:调用 shell_backspace() 删除前一个字符;
  • ESC序列:用于处理上下左右键,控制历史切换或光标移动。

四、命令编辑与显示

shell_refresh_line() 是命令行重绘函数,它会:

  1. 回车至行首;
  2. 显示提示符与当前命令;
  3. 移动光标到正确位置。

其原理是通过ANSI转义序列实现,例如 \x1b[C 表示右移光标一格。

在编辑命令时,插入字符或删除字符均会触发此函数以实时刷新显示。

五、历史命令管理

Shell控制台维护一个历史命令环形缓冲区,通过 history[][] 存储最多 SHELL_HISTORY_NUM 条命令。

关键函数:

  • shell_save_history(const char *cmd):保存新命令;
  • shell_show_history(int index):根据历史索引回显旧命令。

方向键 ↑ 和 ↓ 会通过修改 history_index 实现历史命令的切换回显。

六、命令执行

在按下回车后:

shell_handle_enter()

该函数会将命令字符串传入 cmd_execute()

if (cmd_len > 0) {shell_save_history(cmd_buf);cmd_execute(cmd_buf);  // 执行命令
}

cmd_execute() 是命令解析与执行的封装接口,可以根据具体项目自行实现命令注册与执行框架。

七、初始化与使用

Shell初始化函数 shell_init() 中:

cmd_init();  // 初始化命令表
printf("Welcome to STM32 Shell\r\n");
printf(PROMPT);

同时应在程序中调用 shell_uart_start_rx() 启动串口接收。

如果使用RTOS,Shell可以集成在一个独立的 shell_task() 线程中。

八、小结

该Shell控制台框架具有以下特点:

  • 支持插入、删除、方向键控制;
  • 支持多条命令历史;
  • 串口异步接收,适配RTOS或裸机环境;
  • 可扩展的命令执行接口。

适用于大多数STM32嵌入式项目,有助于提升调试效率和交互能力。


完整代码注释:

shell.c:

#include "shell.h"
#include <string.h>
#include <stdio.h>
#include "usart.h"  // 包含串口 huart1 的定义
#include "cmd.h"    // 包含命令执行相关定义#define PROMPT "> "  // 命令提示符// 命令行输入缓冲区
static char cmd_buf[SHELL_CMD_MAX_LEN];
// 当前命令的长度
static uint8_t cmd_len = 0;
// 当前光标在命令行中的位置
static uint8_t cursor_pos = 0;// 历史命令缓存(环形历史)
static char history[SHELL_HISTORY_NUM][SHELL_CMD_MAX_LEN];
// 历史命令条数
static int history_count = 0;
// 当前访问历史命令的索引,-1 表示未访问历史命令
static int history_index = -1;// ESC序列处理状态(0:无,1:收到 ESC,2:收到 ESC[)
static uint8_t esc_state = 0;// 串口接收字符缓冲
static uint8_t uart_rx_ch;/*** @brief 启动串口接收中断(初始化后调用一次)*/
void shell_uart_start_rx(void) {HAL_UART_Receive_IT(&huart1, &uart_rx_ch, 1);
}/*** @brief 串口接收完成中断回调函数(在stm32_hal库中调用)*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if (huart->Instance == USART1) {// 将接收到的字符交给 shell 处理shell_input_char((char)uart_rx_ch);// 继续接收下一个字符HAL_UART_Receive_IT(&huart1, &uart_rx_ch, 1);}
}/*** @brief 重绘整行命令和光标位置*/
static void shell_refresh_line(void)
{printf("\r");               // 回到行首printf(PROMPT);            // 打印提示符printf("%s", cmd_buf);     // 打印当前命令printf(" \r");             // 用空格覆盖残留字符,防止显示残留printf("\r");              // 再次回到行首// 将光标移到 cmd_buf 中 cursor_pos 的位置int pos = strlen(PROMPT) + cursor_pos;for (int i = 0; i < pos; i++) {printf("\x1b[C");      // ANSI 控制码,光标右移}
}/*** @brief 保存输入命令到历史记录*/
static void shell_save_history(const char *cmd)
{// 空命令不保存if (cmd[0] == '\0') return;// 如果和上一条命令相同则不重复保存if (history_count == 0 || strcmp(cmd, history[0]) != 0) {if (history_count < SHELL_HISTORY_NUM) {history_count++;}// 历史命令向后移动一位,腾出第一个位置for (int i = history_count - 1; i > 0; i--) {strcpy(history[i], history[i - 1]);}// 复制当前命令到历史[0]strncpy(history[0], cmd, SHELL_CMD_MAX_LEN);}history_index = -1;  // 重置历史访问状态
}/*** @brief 处理回车:执行命令并清空缓冲*/
static void shell_handle_enter(void)
{cmd_buf[cmd_len] = '\0';   // 确保字符串结尾printf("\r\n");if (cmd_len > 0) {shell_save_history(cmd_buf); // 保存历史cmd_execute(cmd_buf);        // 执行命令(调用命令系统)}// 重置缓冲区cmd_len = 0;cursor_pos = 0;memset(cmd_buf, 0, sizeof(cmd_buf));history_index = -1;printf(PROMPT);  // 打印提示符
}/*** @brief 删除光标前一个字符*/
static void shell_backspace(void)
{if (cursor_pos == 0) return;  // 光标在起点,不能删除// 后面字符左移覆盖当前字符memmove(&cmd_buf[cursor_pos - 1], &cmd_buf[cursor_pos], cmd_len - cursor_pos);cmd_len--;cursor_pos--;cmd_buf[cmd_len] = '\0';shell_refresh_line();  // 重绘命令行
}/*** @brief 插入字符到光标当前位置*/
static void shell_insert_char(char ch)
{if (cmd_len >= SHELL_CMD_MAX_LEN - 1) return;  // 缓冲区满// 将光标右侧字符右移,腾出插入空间memmove(&cmd_buf[cursor_pos + 1], &cmd_buf[cursor_pos], cmd_len - cursor_pos);cmd_buf[cursor_pos] = ch;cmd_len++;cursor_pos++;cmd_buf[cmd_len] = '\0';shell_refresh_line();  // 重绘命令行
}/*** @brief 显示某一条历史命令*/
static void shell_show_history(int index)
{if (index < 0 || index >= history_count) {return;}strcpy(cmd_buf, history[index]);cmd_len = strlen(cmd_buf);cursor_pos = cmd_len;shell_refresh_line();
}/*** @brief Shell 接收字符输入处理函数(包括普通字符、ESC序列、回车等)*/
void shell_input_char(char ch)
{if (esc_state == 0) {if (ch == 0x1B) {esc_state = 1;  // 收到 ESC,开始解析转义序列} else if (ch == '\r' || ch == '\n') {shell_handle_enter();  // 回车键} else if (ch == 127 || ch == '\b') {shell_backspace();     // 删除键} else if (ch >= 0x20 && ch <= 0x7E) {shell_insert_char(ch); // 可打印字符}} else if (esc_state == 1) {if (ch == '[') {esc_state = 2;  // 收到 ESC + [,进入方向键解析状态} else {esc_state = 0;  // 非预期,重置状态}} else if (esc_state == 2) {esc_state = 0;  // 处理完一组 ESC 序列后立即清空状态if (ch == 'A') {  // ↑ 上键if (history_count > 0 && history_index < history_count - 1) {history_index++;shell_show_history(history_index);}} else if (ch == 'B') {  // ↓ 下键if (history_index > 0) {history_index--;shell_show_history(history_index);} else if (history_index == 0) {history_index = -1;cmd_len = 0;cursor_pos = 0;cmd_buf[0] = '\0';shell_refresh_line();}} else if (ch == 'C') {  // → 右键if (cursor_pos < cmd_len) {cursor_pos++;shell_refresh_line();}} else if (ch == 'D') {  // ← 左键if (cursor_pos > 0) {cursor_pos--;shell_refresh_line();}}}
}/*** @brief Shell 初始化(显示欢迎信息和提示符)*/
void shell_init(void)
{cmd_init();  // 初始化命令系统printf("Welcome to STM32 Shell\r\n");printf(PROMPT);
}/*** @brief Shell任务(可集成到RTOS任务中,目前为空)*/
void shell_task(void)
{// 空任务占位
}

shell.h:

#ifndef __SHELL_H__
#define __SHELL_H__#include <stdint.h>#define SHELL_CMD_MAX_LEN     64
#define SHELL_HISTORY_NUM     5#ifdef __cplusplus
extern "C" {
#endif// 初始化 shell
void shell_init(void);// 串口接收到字符时调用
void shell_input_char(char ch);// 主循环处理函数(可选)
void shell_task(void);void shell_uart_start_rx(void); #ifdef __cplusplus
}
#endif#endif // __SHELL_H__

文章转载自:

http://HtWKX1of.yswxq.cn
http://hAj2goKW.yswxq.cn
http://NpaTk5Ro.yswxq.cn
http://qjQUgT0d.yswxq.cn
http://j0UGEbFm.yswxq.cn
http://M35u2pE4.yswxq.cn
http://CJdfWyOO.yswxq.cn
http://9UDvHbb3.yswxq.cn
http://5OPCofNX.yswxq.cn
http://pTkr7Oql.yswxq.cn
http://C4pDSPvd.yswxq.cn
http://xBbX43tr.yswxq.cn
http://JQMIxj7a.yswxq.cn
http://tcIfqJEI.yswxq.cn
http://yiR5AqeN.yswxq.cn
http://OzVTIW19.yswxq.cn
http://Ywdj7eeC.yswxq.cn
http://YNZEUZpc.yswxq.cn
http://e8Zh79Ut.yswxq.cn
http://OMa04bg9.yswxq.cn
http://vrLV0SwY.yswxq.cn
http://mxsgOTzD.yswxq.cn
http://9CbMATF5.yswxq.cn
http://eXD8ywEc.yswxq.cn
http://s5CBAUdS.yswxq.cn
http://fxbtl98N.yswxq.cn
http://utfwb4mJ.yswxq.cn
http://x74DYhmt.yswxq.cn
http://sgcmGifl.yswxq.cn
http://1DFbvBKM.yswxq.cn
http://www.dtcms.com/wzjs/753868.html

相关文章:

  • 网站建设前期上海网站搭建公司哪家好
  • 代理网站备案表wordpress 首页缓存
  • 音乐网站功能自己在家可以做网站吗
  • 网站系统繁忙怎么办vc6.0做网站
  • 河北建设信息平台网站网站导航字体大小
  • 网站建设人员培训asp网站作业下载
  • 做企业网站的尺寸是多少站长素材官网免费
  • 数码网站建设总体目标推广计划表格
  • 网站自适应屏幕云服务器可以用来做网站么
  • seo网站优化平台芜湖的网站建设公司
  • 海外网站建设推广app开发软件外包
  • 美容加盟网站建设注册公司那家网站做的比较好
  • 网站首页动画代码网站查外链
  • 简单的网站注册流程图大同市建设工程招标投标网站
  • 小榄网站长沙网络公司排行榜
  • 万网企业邮箱登陆界面如何嵌入到自己的网站做网站都需要买什么
  • 什么样的网站利于优化网站开发最新流程
  • 免费crm系统下载杭州seo搜索引擎优化公司
  • 杭州市城乡规划局建设局官方网站专业教育网站建设
  • 有了域名和空间怎么做网站内容太原专业做网站
  • 模拟ip访问网站深圳网站建设网站设计软文推广
  • 卓业网站建设优化营商环境存在问题及整改措施
  • 做网站用哪个写比较好网站免费正能量下载
  • 怎样构建网站建设摩托125图片大全
  • 广东省住房和城乡建设厅网站首页网站建设与管理实训报告
  • 小学科学可以做实验的网站网络设计工作好找吗
  • 移动商务网站开发课程基于node网站毕设代做
  • 住房与建设部网站首页wordpress注册带密码
  • 网站的空间价格吸引人的公众号名称大全
  • 找网站开发郑州互联网seo