|
本帖最后由 Gorgon_Meducer 于 2014-5-8 23:12 编辑
傻孩子工作室出品
模块简介:
这个控制台模块是一个使用全状态机编写的、移植性强的模块。
模块内置help 与 clear两个命令。
可以静态或者动态扩展需要的命令。
支持上下方向键回溯历史命令功能,历史命令的保存数量可配置。
支持F1 F3键回溯上一条历史命令功能,这个功能可以配置打开或者关闭。
效果图:
准备工作:
你现在需要一个有串口、有两个独立按键、有独立LED指示灯的单片机系统。
为了体现平台无关,请参考文档 《平台搭建》 搭建平台。
该平台提供了串口收发函数、LED控制接口函数、独立按键读取函数。
这样我们就拥有一个共同讨论的基础。
我现在使用的是STM32F103C8T6的板子,提供了一个使用MDK编写的、基于STM32F103C8T6的范例。
基于之前搭建的平台,代码移植起来是非常容易的。
在平台的基础上,使用者需要提供两个函数来使用该模块:写数据函数、读取数据函数。
范例下载:
使用MDK的软件仿真即刻体验 ~虽然不能实现F1 F3 / 方向键上下 / clear命令 等功能
模块下载:
解压后可以看到:模块由console文件夹下的三个文件组成:console.c console.h app_cfg.h
移植console模块:
将模块文件夹复制到你工程的代码文件夹,然后包含console.c。
提供写数据函数与读取数据函数:
范例中:main.c提供了如下函数:
- bool console_serial_out(uint8_t chByte)
- {
- return serial_out(chByte);
- }
- bool console_serial_in(uint8_t *pchByte)
- {
- return serial_in(pchByte);
- }
复制代码
在顶层app_cfg.h中通过如下插入宏来注册这两个函数:
- // console 读写数据插入宏
- #define CONSOLE_WRITE_BYTE(__BYTE) console_serial_out(__BYTE)
- extern bool console_serial_out(uint8_t chByte);
- #define CONSOLE_READ_BYTE(__BYTE) console_serial_in(__BYTE)
- extern bool console_serial_in(uint8_t *pchByte);
复制代码
该app_cfg.h被console模块中的app_cfg.h包含;进而被console.c包含。
经过以上的步骤,console模块的移植工作就完成了。使用时,需包含头文件console.h
使用console模块:
接口函数:
- // console_task 函数
- // 返回值: 状态机运行状态
- extern fsm_rt_t console_task(void);
- // 动态扩展命令消息地图注册函数
- // 参数: ptMSG -- 待注册的消息地图首指针
- // chMSGNum -- 待注册消息地图中消息的数量
- // 返回值: true -- 注册成功
- // false -- 参数错误
- extern bool console_register_command(const msg_t *ptMSG, uint8_t chMSGNum);
复制代码
console_task 函数为console模块任务函数,该函数需要在主程序中被反复调用。
console_register_command函数为动态扩展命令消息地图注册函数。
静态扩展命令:
在顶层 app_cfg.h 中提供消息处理函数原型插入宏 CONSOLE_MSG_MAP_FUN_EXTERN
提供方法举例:
- #define CONSOLE_MSG_MAP_FUN_EXTERN \
- extern fsm_rt_t test_handler(const msg_t *ptMSG, uint8_t *pchStr, uint8_t chNum);
复制代码
并且提供消息地图插入宏 CONSOLE_MSG_MAP_SET
提供方法举例:
- #define CONSOLE_MSG_MAP_SET { "test", &test_handler, "test -- this is a test command" }
复制代码
动态扩展命令:
参见范例main.c中声明消息地图:
- /* 动态扩展命令消息地图 ------------------------------------------------ */
- const static msg_t s_tExpandMSGMap[] = {
- { "expand", &expand_handler, "expand -- this is a expand command" },
- { "abc", &abc_handler, "abc -- this is abc command" }
- };
复制代码
编写处理函数:
- // expand 命令的处理函数
- // 参数: ptMSG -- 消息指针
- // pchStr -- 后续 token 指针
- // chNum -- 后续 token 数量
- // 返回值: 状态机运行状态
- static fsm_rt_t expand_handler(const msg_t *ptMSG, uint8_t *pchStr, uint8_t chNum)
- {
- ……
- }
- // abc 命令的处理函数
- // 参数: ptMSG -- 消息指针
- // pchStr -- 后续 token 指针
- // chNum -- 后续 token 数量
- // 返回值: 状态机运行状态
- static fsm_rt_t abc_handler(const msg_t *ptMSG, uint8_t *pchStr, uint8_t chNum)
- {
- ……
- }
复制代码
注册扩展命令:
- console_register_command(s_tExpandMSGMap, UBOUND(s_tExpandMSGMap));
复制代码
配置历史命令回溯数量:
通过在顶层app_cfg.h中提供插入宏实现:
- // 配置记录历史命令数量
- #define CONSOLE_HIS_CMD_NUM 10
复制代码
配置F1 F3回溯功能的开启与关闭:
通过在顶层app_cfg.h中提供插入宏实现:
- // 配置命令重复功能
- #define CONSOLE_CMD_REPEAT_EN ENABLED
复制代码
注意事项:
1 console_task函数必须在主循环中被反复调用。
2 扩展命令的处理函数不能阻塞。
接口文件console.h:
- /* console 模块的输出接口文件 */
- #ifndef __CONSOLE_H__
- #define __CONSOLE_H__
- /* 文件包含 ----------------------------------------------------------------- */
- #include".\app_cfg.h"
- /* 模块说明 ----------------------------------------------------------------- */
- // 使用本模块应在上层 app_cfg.h 中提供 写数据插入宏 CONSOLE_WRITE_BYTE(__BYTE)
- // 与读取数据插入红 CONSOLE_READ_BYTE(__BYTE)
- // 并且提供插入宏展开后的原型
- //
- // 应在上层 app_cfg.h 中提供用以配置最大命令字符数的 CONSOLE_CMD_CHAR_NUM 插入宏
- // 如没有提供该插入宏,会产生一条警告信息;并且默认配置为最大64字符数
- //
- // 应在上层 app_cfg.h 中提供用以配置是否需要重复功能 ( F1 F3 等 )
- // 的插入宏 CONSOLE_CMD_REPEAT_EN ENABLED(1)--启用 DISABLED(0)--禁止
- // 如没有提供该插入宏,会产生一条警告信息;并且默认启用该功能
- //
- // 应在上层 app_cfg.h 中提供用以配置历史命令记录数量的插入宏
- // CONSOLE_HIS_CMD_NUM 至少为 1 每一条历史指令都将消耗 CONSOLE_CMD_CHAR_NUM + 2 字节RAM
- // 如没有提供该插入宏,会产生一条警告信息;并且默认保存4条历史指令
- //
- // 应在上层 app_cfg.h 中提供用以配置 token 分隔符的插入宏 CONSOLE_TOKEN_CODE
- // 提供方法举例: #define CONSOLE_TOKEN_CODE " ,;- ."
- // 如没有提供该插入宏,会产生一条警告系你系;并默认采用空格为 token 分隔符
- //
- // 静态扩展命令:
- // 在上层 app_cfg.h 中提供消息处理函数原型插入宏 CONSOLE_MSG_MAP_FUN_EXTERN
- // 提供方法举例:
- // #define CONSOLE_MSG_MAP_FUN_EXTERN \
- // extern fsm_rt_t test_handler(const msg_t *ptMSG, uint8_t *pchStr, uint8_t chNum);
- // 并且提供消息地图插入宏 CONSOLE_MSG_MAP_SET
- // 提供方法举例:
- // #define CONSOLE_MSG_MAP_SET { "test", &test_handler, "test -- this is a test command" }
- /* 类型定义 ----------------------------------------------------------------- */
- typedef struct _msg_t msg_t;
- typedef fsm_rt_t MSG_HANDLER(const msg_t *ptMSG, uint8_t *pchStr, uint8_t chNum); // 消息处理函数类型
- struct _msg_t {
- uint8_t *pchMsgStr; // 消息
- MSG_HANDLER *fnHandler; // 消息处理函数
- uint8_t *pchHelpStr; // 帮助信息指针
- };
- /* 输出接口 ----------------------------------------------------------------- */
- // console_task 函数
- // 返回值: 状态机运行状态
- extern fsm_rt_t console_task(void);
- // 动态扩展命令消息地图注册函数
- // 参数: ptMSG -- 待注册的消息地图首指针
- // chMSGNum -- 待注册消息地图中消息的数量
- // 返回值: true -- 注册成功
- // false -- 参数错误
- extern bool console_register_command(const msg_t *ptMSG, uint8_t chMSGNum);
- #endif
- /* EOF */
复制代码
接口文件向外部提供了模块的使用说明以及需要用到的数据类型:消息类型的定义以及消息处理函数的原型。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|