/****************************************************************************** 版权所有 (C), 2018-2099, Radkil ****************************************************************************** 文 件 名 : msg_center.c 版 本 号 : 初稿 作 者 : radkil 生成日期 : 2026年7月13日 最近修改 : 功能描述 : 模块间消息分发中心(跨线程通信) 修改历史 : 1.日 期 : 2026年7月13日 作 者 : radkil 修改内容 : 创建文件 ******************************************************************************/ #include "msg_center.h" #include "rd_thread.h" #include "ringbuffer.h" /*----------------------------------------------* * 外部变量说明 * *----------------------------------------------*/ /*----------------------------------------------* * 外部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 内部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 全局变量 * *----------------------------------------------*/ /*----------------------------------------------* * 模块级变量 * *----------------------------------------------*/ // 模块注册表 typedef struct { MsgModule_t stModule; rd_ringbuf_t *pstRingBuf; // 消息队列(ringbuffer) rd_mutex_t stMutex; // 互斥锁(保护ringbuffer) rd_sem_t stSem; // 信号量(阻塞等待) } MsgModuleEntry_t; static MsgModuleEntry_t g_astModules[MSG_CENTER_MAX_MODULES]; static uint32_t g_uiModuleCount = 0; static uint32_t g_uiNextModuleID = 1; // 从1开始,0表示无效 /*----------------------------------------------* * 常量定义 * *----------------------------------------------*/ // ringbuffer大小:每个模块可缓存的消息数量 #define MSG_RING_BUFFER_SIZE (MSG_CENTER_QUEUE_SIZE * sizeof(Msg_t)) /*----------------------------------------------* * 宏定义 * *----------------------------------------------*/ // 查找模块索引 #define FIND_MODULE_INDEX(uiModuleID) \ ((uiModuleID) > 0 && (uiModuleID) <= g_uiModuleCount ? \ (uiModuleID) - 1 : -1) /***************************************************************************** 函 数 名 : MsgCenter_Init 功能描述 : 初始化消息中心 输入参数 : 无 输出参数 : 无 返 回 值 : void *****************************************************************************/ void MsgCenter_Init(void) { g_uiModuleCount = 0; g_uiNextModuleID = 1; RD_MEMSET(g_astModules, 0, sizeof(g_astModules)); } /***************************************************************************** 函 数 名 : MsgCenter_Register 功能描述 : 注册模块到消息中心 输入参数 : const char *pszName 模块名称 MsgHandler_t pfHandler 消息处理回调 输出参数 : 无 返 回 值 : uint32_t 模块ID,失败返回0 *****************************************************************************/ uint32_t MsgCenter_Register(const char *pszName, MsgHandler_t pfHandler) { if (NULL == pszName || NULL == pfHandler) { return 0; } if (g_uiModuleCount >= MSG_CENTER_MAX_MODULES) { return 0; // 模块数已满 } // 检查名称是否重复 for (uint32_t i = 0; i < g_uiModuleCount; i++) { if (RD_STRCMP(g_astModules[i].stModule.m_szName, pszName) == 0) { return 0; // 名称重复 } } // 注册模块 uint32_t uiIndex = g_uiModuleCount; uint32_t uiModuleID = g_uiNextModuleID++; RD_STRNCPY(g_astModules[uiIndex].stModule.m_szName, pszName, MSG_CENTER_MAX_NAME_LEN - 1); g_astModules[uiIndex].stModule.m_szName[MSG_CENTER_MAX_NAME_LEN - 1] = '\0'; g_astModules[uiIndex].stModule.m_uiModuleID = uiModuleID; g_astModules[uiIndex].stModule.m_pfHandler = pfHandler; // 创建 ringbuffer g_astModules[uiIndex].pstRingBuf = rd_RingbufferCreate(MSG_RING_BUFFER_SIZE); if (NULL == g_astModules[uiIndex].pstRingBuf) { return 0; } // 初始化互斥锁 if (Rd_MutexInit(&g_astModules[uiIndex].stMutex) != RD_SUCCESS) { rd_RingbufferDestroy(g_astModules[uiIndex].pstRingBuf); return 0; } // 初始化信号量(初始值为0,表示无消息) if (Rd_SemInit(&g_astModules[uiIndex].stSem, 0, 0) != RD_SUCCESS) { Rd_MutexDestroy(&g_astModules[uiIndex].stMutex); rd_RingbufferDestroy(g_astModules[uiIndex].pstRingBuf); return 0; } g_uiModuleCount++; return uiModuleID; } /***************************************************************************** 函 数 名 : MsgCenter_FindModule 功能描述 : 通过名称查找模块ID 输入参数 : const char *pszName 模块名称 输出参数 : 无 返 回 值 : uint32_t 模块ID,未找到返回0 *****************************************************************************/ uint32_t MsgCenter_FindModule(const char *pszName) { if (NULL == pszName) { return 0; } for (uint32_t i = 0; i < g_uiModuleCount; i++) { if (RD_STRCMP(g_astModules[i].stModule.m_szName, pszName) == 0) { return g_astModules[i].stModule.m_uiModuleID; } } return 0; } /***************************************************************************** 函 数 名 : MsgCenter_Send 功能描述 : 发送消息(异步,跨线程安全) 输入参数 : const Msg_t *pstMsg 消息指针 输出参数 : 无 返 回 值 : int 0成功,非0失败 *****************************************************************************/ int MsgCenter_Send(const Msg_t *pstMsg) { if (NULL == pstMsg) { return RD_NULL; } int iDstIndex = FIND_MODULE_INDEX(pstMsg->m_uiDstModule); if (iDstIndex < 0 || NULL == g_astModules[iDstIndex].pstRingBuf) { return RD_FAILURE; } // 加锁保护ringbuffer Rd_MutexLock(&g_astModules[iDstIndex].stMutex, __func__, NULL); // 写入ringbuffer int iRet = rd_RingbufferPut(g_astModules[iDstIndex].pstRingBuf, (const char *)pstMsg, sizeof(Msg_t)); Rd_MutexUnlock(&g_astModules[iDstIndex].stMutex, __func__, NULL); if (iRet > 0) { // 发送信号量,通知有新消息 Rd_SemPost(&g_astModules[iDstIndex].stSem, __func__, NULL); return RD_SUCCESS; } return RD_FAILURE; // 队列满 } /***************************************************************************** 函 数 名 : MsgCenter_SendTo 功能描述 : 发送消息给指定模块(便捷函数) 输入参数 : const char *pszDstName 目标模块名称 MsgID_t uiMsgID 消息ID const void *pData 数据指针(可为NULL) uint32_t uiDataLen 数据长度 输出参数 : 无 返 回 值 : int 0成功,非0失败 *****************************************************************************/ int MsgCenter_SendTo(const char *pszDstName, MsgID_t uiMsgID, const void *pData, uint32_t uiDataLen) { if (NULL == pszDstName) { return RD_NULL; } uint32_t uiDstModuleID = MsgCenter_FindModule(pszDstName); if (0 == uiDstModuleID) { return RD_FAILURE; } Msg_t stMsg; RD_MEMSET(&stMsg, 0, sizeof(Msg_t)); stMsg.m_uiDstModule = uiDstModuleID; stMsg.m_uiMsgID = uiMsgID; if (NULL != pData && uiDataLen > 0) { if (uiDataLen > MSG_CENTER_MAX_DATA_SIZE) { uiDataLen = MSG_CENTER_MAX_DATA_SIZE; } RD_MEMCPY(stMsg.m_aucData, pData, uiDataLen); stMsg.m_uiDataLen = uiDataLen; } return MsgCenter_Send(&stMsg); } /***************************************************************************** 函 数 名 : MsgCenter_ProcessOne 功能描述 : 从ringbuffer读取一条消息 输入参数 : int iIndex 模块索引 Msg_t *pstMsg 输出消息 输出参数 : 无 返 回 值 : int 1成功,0无数据 *****************************************************************************/ static int MsgCenter_ProcessOne(int iIndex, Msg_t *pstMsg) { // 加锁保护ringbuffer Rd_MutexLock(&g_astModules[iIndex].stMutex, __func__, NULL); int iRet = rd_RingbufferGet(g_astModules[iIndex].pstRingBuf, (char *)pstMsg, sizeof(Msg_t)); Rd_MutexUnlock(&g_astModules[iIndex].stMutex, __func__, NULL); return (iRet > 0) ? 1 : 0; } /***************************************************************************** 函 数 名 : MsgCenter_Process 功能描述 : 处理当前模块的消息(在模块线程中调用) 输入参数 : uint32_t uiModuleID 模块ID 输出参数 : 无 返 回 值 : int 处理的消息数量 *****************************************************************************/ int MsgCenter_Process(uint32_t uiModuleID) { int iIndex = FIND_MODULE_INDEX(uiModuleID); if (iIndex < 0 || NULL == g_astModules[iIndex].pstRingBuf) { return 0; } int iCount = 0; Msg_t stMsg; // 非阻塞读取所有待处理消息 while (MsgCenter_ProcessOne(iIndex, &stMsg)) { if (g_astModules[iIndex].stModule.m_pfHandler != NULL) { g_astModules[iIndex].stModule.m_pfHandler(&stMsg); } iCount++; } return iCount; } /***************************************************************************** 函 数 名 : MsgCenter_ProcessWait 功能描述 : 处理当前模块的消息(带超时等待) 输入参数 : uint32_t uiModuleID 模块ID uint32_t uiTimeoutMs 超时时间(毫秒),0表示不等待 输出参数 : 无 返 回 值 : int 处理的消息数量,-1表示超时 *****************************************************************************/ int MsgCenter_ProcessWait(uint32_t uiModuleID, uint32_t uiTimeoutMs) { int iIndex = FIND_MODULE_INDEX(uiModuleID); if (iIndex < 0 || NULL == g_astModules[iIndex].pstRingBuf) { return -1; } Msg_t stMsg; // 等待信号量(有新消息到达) if (uiTimeoutMs > 0) { // 带超时等待 Rd_SemWait(&g_astModules[iIndex].stSem, __func__, NULL); } else { // 非阻塞,直接检查ringbuffer if (!MsgCenter_ProcessOne(iIndex, &stMsg)) { return 0; } // 处理第一条消息 if (g_astModules[iIndex].stModule.m_pfHandler != NULL) { g_astModules[iIndex].stModule.m_pfHandler(&stMsg); } // 继续处理剩余消息 int iCount = 1; while (MsgCenter_ProcessOne(iIndex, &stMsg)) { if (g_astModules[iIndex].stModule.m_pfHandler != NULL) { g_astModules[iIndex].stModule.m_pfHandler(&stMsg); } iCount++; } return iCount; } // 信号量被触发,处理消息 int iCount = 0; while (MsgCenter_ProcessOne(iIndex, &stMsg)) { if (g_astModules[iIndex].stModule.m_pfHandler != NULL) { g_astModules[iIndex].stModule.m_pfHandler(&stMsg); } iCount++; } return iCount; }