You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
11 KiB
374 lines
11 KiB
|
3 weeks ago
|
/******************************************************************************
|
||
|
|
|
||
|
|
版权所有 (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;
|
||
|
|
}
|