From 83b013c678ed3ae711b41ec997b55517a2ee50f9 Mon Sep 17 00:00:00 2001 From: zhangzhaopeng Date: Tue, 30 Dec 2025 15:39:29 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=A0=BC=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A=E5=92=8C=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mw/has_task_msg_manager/README | 6 + mw/has_task_msg_manager/has_task_msg.h | 23 +++- .../has_task_msg_mamanger.c | 124 ++++++++++++++---- 3 files changed, 127 insertions(+), 26 deletions(-) create mode 100644 mw/has_task_msg_manager/README diff --git a/mw/has_task_msg_manager/README b/mw/has_task_msg_manager/README new file mode 100644 index 0000000..f5f0e86 --- /dev/null +++ b/mw/has_task_msg_manager/README @@ -0,0 +1,6 @@ +这个软件用于代码模块之间的消息传递,采用发布-订阅的方式传递消息 +使用方法: +1. 在 has_task_msg_os_port.h 选择操作系统,更改宏MSG_OPT_OS。或选择自定义自己实现接口。 +2. 在 has_task_msg.h 中添加自己负责的软件模块id号(has_module_ID_e),并且完成订阅表 SUBSCIBE_INFO + 填表,要把模块的id、模块要订阅的id等信息填好。 +3. 代码中使用:初始化、发布、订阅和消息回调即可。请参考示例 msg_example.c \ No newline at end of file diff --git a/mw/has_task_msg_manager/has_task_msg.h b/mw/has_task_msg_manager/has_task_msg.h index 2f6fe3b..c974b14 100644 --- a/mw/has_task_msg_manager/has_task_msg.h +++ b/mw/has_task_msg_manager/has_task_msg.h @@ -20,19 +20,34 @@ typedef enum { { \ {GUI, 4, {ACM, SENSOR, WIFI, VOICE}}, \ {SENSOR, 1, {GUI}}, \ - {ACM, 1, {WIFI}}, \ - {WIFI, 0}, \ - {VOICE, 3, {ACM, VOICE, GUI}}, \ } -/* 消息处理回调 */ +// #define SUBSCIBE_INFO \ +// { \ +// {GUI, 4, {ACM, WIFI, VOICE, SENSOR}}, \ +// {SENSOR, 5, {ACM, GUI, WIFI, VOICE, SENSOR}}, \ +// {ACM, 4, {GUI, WIFI, VOICE, SENSOR}}, \ +// {WIFI, 4, {ACM, GUI, VOICE, SENSOR}}, \ +// {VOICE, 4, {ACM, WIFI, GUI, SENSOR}}, \ +// } + +/** + * @brief 消息处理回调类型 + * @param module_id:发布者的id号 + * @param buf:消息数据指针 + * @param len:消息数据长度 + * @return 0:成功 -1:失败 + */ typedef int (*has_msg_handle_cb)(unsigned char module_id, const unsigned char *buf, unsigned int len); /* 基础功能 */ int has_msg_init(void); +int has_msg_init_module(has_module_ID_e module_id); // HAS OS调用 int has_msg_publish(has_module_ID_e module_id, void *buffer, unsigned int length); int has_msg_handle(has_module_ID_e module_id, has_msg_handle_cb cb); +int has_msg_os_init(void); + unsigned int has_msg_is_message_empty(has_module_ID_e module_id); unsigned int has_msg_get_message_number(has_module_ID_e module_id); int has_msg_delete_all_message(has_module_ID_e module_id); diff --git a/mw/has_task_msg_manager/has_task_msg_mamanger.c b/mw/has_task_msg_manager/has_task_msg_mamanger.c index 5160dae..e8fe096 100644 --- a/mw/has_task_msg_manager/has_task_msg_mamanger.c +++ b/mw/has_task_msg_manager/has_task_msg_mamanger.c @@ -1,3 +1,12 @@ +/* + * has_task_msg_manager/has_task_msg_manager.c + * + * Author: zhangzhaopeng + * Version: 1.0 + * Created on : 2025-12-29 + * 这个软件用于代码模块之间的消息传递,采用发布-订阅的方式传递消息 + * + */ #include #include "list.h" #include "has_task_msg.h" @@ -76,6 +85,11 @@ if (((id) >= MODULE_MAX) || ((id) == INVALID_ID)) { \ if (g_sub_list_index[(id)] == MODULE_MAX) { \ return (ret);} +/** + * @brief 初始化消息表 + * + * @return 0:成功 -1:失败 + */ int has_msg_init() { int j; @@ -85,7 +99,8 @@ int has_msg_init() for (int i = 0; i < (sizeof(g_sub_list) / sizeof(g_sub_list[0])); i++) { /* 检查各模块ID是否配置正确 */ if ((g_sub_list[i].module_id >= MODULE_MAX) || (g_sub_list[i].module_id == INVALID_ID)) { - msg_printf("module_id:%d is invalid, please check the macro:SUBSCIBE_INFO row:%d\n", g_sub_list[i].module_id, i); + msg_printf("module_id:%d is invalid, please check the macro:SUBSCIBE_INFO row:%d\n" + , g_sub_list[i].module_id, i); MSG_ASSERT; // 配置都能写错,必须进断言 return -1; } @@ -100,16 +115,18 @@ int has_msg_init() if (g_sub_list[i].sub_module[j] == INVALID_ID) { break; } else if (g_sub_list[i].sub_module[j] >= MODULE_MAX) { - msg_printf("sub_module id:%d is invalid, module:id %d\nplease check the macro:" - " SUBSCIBE_INFO row:%d, sub list:%d\n", g_sub_list[i].sub_module[j], g_sub_list[i].module_id, i, j); + msg_printf("sub_module id:%d is invalid, module:id %d\n" + "please check the macro: SUBSCIBE_INFO row:%d, sub list:%d\n" + , g_sub_list[i].sub_module[j] , g_sub_list[i].module_id, i, j); MSG_ASSERT; // 配置都能写错,必须进断言 return -1; } } /* 检查订阅数量是否配置正确 */ if (g_sub_list[i].sub_module_cnt != j) { - msg_printf("sub_module_cnt is config as %d, which actually is %d, please check the" - " macro: SUBSCIBE_INFO row:%d\n", g_sub_list[i].sub_module_cnt, j, i); + msg_printf("sub_module_cnt is config as %d, which actually is %d," + "please check the macro: SUBSCIBE_INFO row:%d\n" + , g_sub_list[i].sub_module_cnt, j, i); MSG_ASSERT; // 配置都能写错,必须进断言 return -1; } @@ -121,7 +138,9 @@ int has_msg_init() } /* 注册所找到发布者的发布表 */ - g_pub_list[g_sub_list[i].sub_module[k]].pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = g_sub_list[i].module_id; + g_pub_list[g_sub_list[i].sub_module[k]]. + pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] + = g_sub_list[i].module_id; g_pub_list[g_sub_list[i].sub_module[k]].pub_num ++; } msg_mutex_init(&g_sub_list[i].msg_mutex); // 初始化该模块互斥量 @@ -152,6 +171,13 @@ int has_msg_init() return 0; } +/** + * @brief 根据模块分别初始化消息表 + * + * @param module_id:模块id号 + * @return 0:成功 -1:失败 + * 用于HAS OS中的初始化 + */ int has_msg_init_module(has_module_ID_e module_id) { int i, j; @@ -177,8 +203,9 @@ int has_msg_init_module(has_module_ID_e module_id) if (g_sub_list[i].sub_module[j] == INVALID_ID) { break; } else if (g_sub_list[i].sub_module[j] >= MODULE_MAX) { - msg_printf("sub_module id:%d is invalid, module:id %d\nplease check the macro:" - " SUBSCIBE_INFO row:%d, sub list:%d\n", g_sub_list[i].sub_module[j], module_id, i, j); + msg_printf("sub_module id:%d is invalid, module:id %d\n" + "please check the macro: SUBSCIBE_INFO row:%d, sub list:%d\n" + , g_sub_list[i].sub_module[j], module_id, i, j); MSG_ASSERT; // 配置都能写错,必须进断言 return -1; } @@ -186,8 +213,9 @@ int has_msg_init_module(has_module_ID_e module_id) /* 检查订阅数量是否配置正确 */ if (g_sub_list[i].sub_module_cnt != j) { - msg_printf("sub_module_cnt is config as %d, which actually is %d, please check the" - " macro: SUBSCIBE_INFO row:%d\n", g_sub_list[i].sub_module_cnt, j, i); + msg_printf("sub_module_cnt is config as %d, which actually is %d," + "please check the macro: SUBSCIBE_INFO row:%d\n" + , g_sub_list[i].sub_module_cnt, j, i); MSG_ASSERT; // 配置都能写错,必须进断言 return -1; } @@ -200,7 +228,8 @@ int has_msg_init_module(has_module_ID_e module_id) } /* 注册所找到发布者的发布表 */ - g_pub_list[g_sub_list[i].sub_module[k]].pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = module_id; + g_pub_list[g_sub_list[i].sub_module[k]]. + pub_module[g_pub_list[g_sub_list[i].sub_module[k]].pub_num] = module_id; g_pub_list[g_sub_list[i].sub_module[k]].pub_num ++; } msg_mutex_init(&g_sub_list[i].msg_mutex); // 初始化该模块互斥量 @@ -208,7 +237,7 @@ int has_msg_init_module(has_module_ID_e module_id) break; } } - /* 初始化发布表 */ + #ifdef MSG_OPT_DEBUG if (i == (sizeof(g_sub_list) / sizeof(g_sub_list[0]))) { msg_debug("module:%d never subscribe any module\n", module_id); @@ -224,15 +253,21 @@ int has_msg_os_init() /* 设置无效,标记是否初始化 */ memset(g_sub_list_index, MODULE_MAX, sizeof(g_sub_list_index)); memset(g_pub_list, 0, sizeof(g_pub_list)); - // for(;;) - // has_msg_init_module(GUI); - // has_msg_init_module(SENSOR); - // has_msg_init_module(ACM); - // has_msg_init_module(WIFI); - // has_msg_init_module(VOICE); + for (int i = INVALID_ID + 1; i < MODULE_MAX; i++) + { + has_msg_init_module(i); + } } +/** + * @brief 发布一个消息 + * + * @param module_id:发布消息的模块id号 + * @param buffer:消息数据指针 + * @param length:消息数据长度 + * @return 0:成功 -1:失败 + */ int has_msg_publish(has_module_ID_e module_id, void *buffer, unsigned int length) { has_msg_node_t *node; @@ -246,13 +281,15 @@ int has_msg_publish(has_module_ID_e module_id, void *buffer, unsigned int length unsigned char sub_index; MSG_CHECK_MODULE_ID(module_id, -1); + // MSG_CHECK_ID_AND_INDEX TODO:如果使用这个,未初始化的模块也不能发布 if (g_pub_list[module_id].pub_num == 0) { // msg_printf("no one subscribe you:%d\n", module_id); return 0; } /* 根据订阅表分配内存 */ - node = (has_msg_node_t *)msg_malloc((sizeof(has_msg_node_t) * g_pub_list[module_id].pub_num) + sizeof(has_msg_buffer_t) + length); + node = (has_msg_node_t *)msg_malloc((sizeof(has_msg_node_t) * g_pub_list[module_id].pub_num) + + sizeof(has_msg_buffer_t) + length); if (node == NULL) { msg_printf("malloc fail,pub id:%d\n", module_id); return -1; @@ -296,6 +333,13 @@ static inline void msg_check_and_free_message(has_msg_node_t *node) } } +/** + * @brief 处理一个消息,先入先出 + * + * @param module_id:处理消息的模块id号 + * @param cb:消息处理回调 + * @return 0:成功 -1:失败 + */ int has_msg_handle(has_module_ID_e module_id, has_msg_handle_cb cb) { has_msg_node_t *node; @@ -325,7 +369,16 @@ int has_msg_handle(has_module_ID_e module_id, has_msg_handle_cb cb) return 0; } -int has_msg_handle_by_module(has_module_ID_e module_id, has_msg_handle_cb cb, has_module_ID_e pub_module_id) +/** + * @brief 处理一个指定发布者的消息,先入先出 + * + * @param module_id:处理消息的模块id号 + * @param cb:消息处理回调 + * @param pub_module_id:指定发布者的id号 + * @return 0:成功 -1:失败 + */ +int has_msg_handle_by_module(has_module_ID_e module_id, has_msg_handle_cb cb, + has_module_ID_e pub_module_id) { has_msg_node_t *node, *temp; has_static_sub_list_t *sub_list; @@ -359,6 +412,13 @@ int has_msg_handle_by_module(has_module_ID_e module_id, has_msg_handle_cb cb, ha return 0; } +/** + * @brief 处理一个最近收到的消息 + * + * @param module_id:处理消息的模块id号 + * @param cb:消息处理回调 + * @return 0:成功 -1:失败 + */ int has_msg_handle_latest(has_module_ID_e module_id, has_msg_handle_cb cb) { has_msg_node_t *node; @@ -390,7 +450,8 @@ int has_msg_handle_latest(has_module_ID_e module_id, has_msg_handle_cb cb) /* 将消息复制出接口处理,不建议使用 */ #if 1 -unsigned int has_msg_receive(has_module_ID_e module_id, unsigned char *pub_module_id, unsigned char *buf_out) +unsigned int has_msg_receive(has_module_ID_e module_id, unsigned char *pub_module_id, + unsigned char *buf_out) { has_msg_node_t *node; has_static_sub_list_t *sub_list; @@ -424,7 +485,8 @@ unsigned int has_msg_receive(has_module_ID_e module_id, unsigned char *pub_modul return len; } -unsigned int has_msg_receive_latest(has_module_ID_e module_id, unsigned char *pub_module_id, unsigned char *buf_out) +unsigned int has_msg_receive_latest(has_module_ID_e module_id, unsigned char *pub_module_id, + unsigned char *buf_out) { has_msg_node_t *node; has_static_sub_list_t *sub_list; @@ -459,6 +521,12 @@ unsigned int has_msg_receive_latest(has_module_ID_e module_id, unsigned char *pu } #endif +/** + * @brief 判断消息链表是否是空,没有消息要处理就是空 + * + * @param module_id:要查空的模块id号 + * @return 0:没有消息 -1:有消息待处理 + */ unsigned int has_msg_is_message_empty(has_module_ID_e module_id) { has_msg_node_t *node, *temp; @@ -478,6 +546,12 @@ unsigned int has_msg_is_message_empty(has_module_ID_e module_id) } } +/** + * @brief 获取待处理消息的个数 + * + * @param module_id:处理消息的模块id号 + * @return num : 消息数量 + */ unsigned int has_msg_get_message_number(has_module_ID_e module_id) { has_msg_node_t *node, *temp; @@ -510,6 +584,12 @@ int has_msg_printf_subscribe(has_module_ID_e module_id) return 0; } +/** + * @brief 删除所有未处理的消息 + * + * @param module_id:处理消息的模块id号 + * @return 0:成功 -1:失败 + */ int has_msg_delete_all_message(has_module_ID_e module_id) { has_msg_node_t *node, *temp;