diff --git a/.vscode/settings.json b/.vscode/settings.json index df4410f..ff85c6b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,7 +20,8 @@ "dji_motor.h": "c", "master_process.h": "c", "seasky_protocol.h": "c", - "bsp_usart.h": "c" + "bsp_usart.h": "c", + "message_center.h": "c" }, "C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools", } \ No newline at end of file diff --git a/HAL_N_Middlewares/Src/main.c b/HAL_N_Middlewares/Src/main.c index 35646a1..88a5292 100644 --- a/HAL_N_Middlewares/Src/main.c +++ b/HAL_N_Middlewares/Src/main.c @@ -44,6 +44,7 @@ #include "master_process.h" #include "led_task.h" #include "bsp_led.h" +#include "message_center.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -150,6 +151,16 @@ int main(void) Vision_Recv_s* recv=VisionInit(&huart1); Vision_Send_s send={.pitch=1,.roll=2,.yaw=3}; LED_init(); + + + float *subsub; + float* sub2; + float test=1; + PublisherRegister("test",&test); + SubscribeEvent("test",&subsub); + SubscribeEvent("test",&sub2); + PublisherRegister("test",sub2); + MessageInit(); /* USER CODE END 2 */ /* Call init function for freertos objects (in freertos.c) */ diff --git a/Makefile b/Makefile index f17a255..9c21a48 100644 --- a/Makefile +++ b/Makefile @@ -129,6 +129,7 @@ modules/referee/referee_communication.c \ modules/remote/remote_control.c \ modules/super_cap/super_cap.c \ modules/can_comm/can_comm.c \ +modules/message_center/message_center.c \ application/gimbal/gimbal.c \ application/chassis/chassis.c \ application/shoot/shoot.c \ @@ -224,7 +225,8 @@ C_INCLUDES = \ -Imodules/referee \ -Imodules/remote \ -Imodules/super_cap \ --Imodules/can_comm +-Imodules/can_comm \ +-Imodules/message_center # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections diff --git a/modules/message_center/message_center.c b/modules/message_center/message_center.c new file mode 100644 index 0000000..848a221 --- /dev/null +++ b/modules/message_center/message_center.c @@ -0,0 +1,55 @@ +#include "message_center.h" +#include "string.h" + +/* 消息初始化用 */ +static char pname[MAX_EVENT_COUNT][MAX_EVENT_NAME_LEN+1]; +static char sname[MAX_EVENT_COUNT][MAX_EVENT_NAME_LEN+1]; +static void* p_ptr[MAX_EVENT_COUNT]={NULL}; +static void** s_pptr[MAX_EVENT_COUNT]={NULL}; // 因为要修改指针,所以需要二重指针 + +void MessageInit() +{ + // pub必须唯一,即消息名称不能重复,不得有多个pub发布相同消息名称 + // 对每一个subscriber,寻找相同消息名称的publisher,可能有多个sub从相同pub获取消息 + for (size_t i = 0; i < MAX_EVENT_COUNT; i++) + { + if(s_pptr[i]!=NULL) + for (size_t j = 0; j < MAX_EVENT_COUNT; j++) //遍历publisher + { + if(p_ptr[j]!=NULL) //不为空 + if(strcmp(&sname[i],pname[j])==0) //比较消息名是否一致 + {volatile size_t ss=strlen(sname[i]); + volatile size_t sss=strlen(pname[j]); + *s_pptr[i]=p_ptr[j]; // 将sub的指针指向pub的数据 + break; + } + + + else //到结尾,退出 + while(1); //如果你卡在这里,说明没有找到消息发布者!请确认消息名称是否键入错误 + } + else //说明已经遍历完所有的subs + break; + } +} + +/* 传入数据地址 */ +void PublisherRegister(char* name,void* data) +{ + static uint8_t idx; + for (size_t i = 0; i < idx; i++) + { + if(strcmp(pname[i],name)==0) + while(1); //运行至此说明pub的消息发布名称冲突 + } + strcpy(pname[idx],name); + p_ptr[idx++]=data; +} + +/* 注意传入的是指针的地址,传参时使用&对数据指针取地址 */ +void SubscribeEvent(char* name,void** data_ptr) +{ + static uint8_t idx; + strcpy(sname[idx],name); + s_pptr[idx++]=data_ptr; +} \ No newline at end of file diff --git a/modules/message_center/message_center.h b/modules/message_center/message_center.h new file mode 100644 index 0000000..957646b --- /dev/null +++ b/modules/message_center/message_center.h @@ -0,0 +1,51 @@ +/** + * @file message_center.h + * @author NeoZeng neozng1@hnu.edu.cn + * @brief 这是一个伪pubsub机制,仅对应用之间的通信进行了隔离 + * @todo 实现基于链表-队列的pubsub机制 + * @version 0.1 + * @date 2022-11-30 + * + * @copyright Copyright (c) 2022 + * + */ + +#ifndef PUBSUB_H +#define PUBSUB_H + +#include "stdlib.h" +#include "stdint-gcc.h" + + +#define MAX_EVENT_NAME_LEN 32 //最大的事件名长度,每个事件都有字符串来命名 +#define MAX_EVENT_COUNT 12 //最多支持的事件数量 + + +/** + * @brief 在所有应用初始化结束之后调用,当作app的"回调函数" + * + */ +void MessageInit(); + +/** + * @brief 注册成为消息发布者 + * + * @param name 消息标识名,注意不要超过MAX_EVENT_NAME_LEN + * @param data 发布者的数据地址 + */ +void PublisherRegister(char* name,void* data); + +/** + * @brief 订阅消息,成为消息订阅者 + * + * @param name 消息标识名 + * @param data 保存数据的指针的地址,注意这是一个二级指针,传入的时候对数据指针取地址(&) + */ +void SubscribeEvent(char* name,void** data); + +#endif // !PUBSUB_H + + + + +/* 以下是队列版的pubsub,TODO */ diff --git a/modules/message_center/message_center.md b/modules/message_center/message_center.md new file mode 100644 index 0000000..e69de29