点击下方名片,关注公众号,获取更多精彩内容▼
欢迎关注【玩转单片机与嵌入式】公众号,回复关键字获取更多免费视频和资料
回复【加群】,【单片机】、【STM32】、【硬件知识】、【硬件设计】、【经典电路】、【论文】、【毕业设计】、【3D封装库】、【PCB】、【电容】、【TVS】、【阻抗匹配】、【资料】、【终端电阻】、【Keil】、【485】、【CAN】、【振荡器】、[USBCAN]、【PCB】、【智能手环】、【智能家居】、【智能小车】、【555】、【I2C】、【华为】、【中兴】,等……
在嵌入式系统开发中,命令解析是一个关键的环节,它负责解析用户或其他系统发送的命令,并执行相应的操作。传统的命令解析方法通常采用switch case语句,这种方式虽然经典,但在功能扩展和代码维护上存在一些不足。下面小编为大家推荐一种更为灵活和模块化的命令解析方法,即通过回调函数实现功能码的动态绑定,提高系统的可维护性和可扩展性。
传统方法的缺陷
在传统的命令解析中,如下图所示的协议内容:
void poll_task(rt_uint8_t cmd, rt_uint8_t *msg, uint8_t len){
switch (cmd){
case cmd1:
func1();
break;
case cmd2:
func2();
break;
case cmd3:
func3();
break;
case cmd4:
func4();
break;
default:
default_func();
break;
}
}
这样的写法存在一个明显的问题,即在增加新的功能码时需要修改poll_task函数,不够灵活。而且,若要统计功能码的个数,只能手动数,不够智能。
创新的回调函数应用
typedef struct
{
rt_uint8_t CMD;
rt_uint8_t (*callback_func)(rt_uint8_t cmd, rt_uint8_t *msg, uint8_t len);
} _FUNCCALLBACK;
_FUNCCALLBACK callback_list[] =
{
{cmd1, func_callback1},
{cmd2, func_callback2},
{cmd3, func_callback3},
{cmd4, func_callback4},
// 添加新的功能码和回调函数只需在这里新增
};
void poll_task(rt_uint8_t cmd, rt_uint8_t *msg, uint8_t len){
int cmd_indexmax = sizeof(callback_list) / sizeof(_FUNCCALLBACK);
int cmd_index = 0;
for (cmd_index = 0; cmd_index < cmd_indexmax; cmd_index++)
{
if (callback_list[cmd_index].CMD == cmd)
{
if(callback_list[cmd_index].callback_func)
{
// 处理逻辑
callback_list[cmd_index].callback_func(cmd, msg, len);
}
}
}
}
进一步优化
// 将命令解析放入队列的伪代码
void command_queue_handler(void)
{
// 从队列中获取命令
rt_uint8_t cmd = get_command_from_queue();
rt_uint8_t msg[MAX_MESSAGE_SIZE];
rt_uint8_t len = get_message_length();
// 调用命令解析函数
poll_task(cmd, msg, len);
}
E N D
欢迎关注我的公众号,回复【加群】或扫码加我好友,限时免费进入技术交流群,也可免费加入我的知识星球。
推荐阅读
感谢大家阅读,如果喜欢
请点赞和“在看”吧,或者分享到朋友圈。
点击跳转到原文,限时优惠加入我们的知识星球(加好友获取免费券)