|
|
|
@ -45,6 +45,11 @@ |
|
|
|
typedef struct { |
|
|
|
MsgModule_t stModule; |
|
|
|
rd_ringbuf_t *pstRingBuf; // 消息队列(ringbuffer)
|
|
|
|
#if defined(USE_FREERTOS) |
|
|
|
rd_mutex_t stMutex; // FreeRTOS互斥锁(任务上下文保护ringbuffer)
|
|
|
|
#endif |
|
|
|
volatile uint8_t bSpinLock; // 自旋锁(ISR安全,始终可用)
|
|
|
|
uint32_t uiPrimask; // 关中断前的PRIMASK快照(裸机用)
|
|
|
|
rd_sem_t stSem; // 信号量(阻塞等待)
|
|
|
|
} MsgModuleEntry_t; |
|
|
|
|
|
|
|
@ -68,6 +73,28 @@ static uint32_t g_uiNextModuleID = 1; // 从1开始,0表示无效 |
|
|
|
((uiModuleID) > 0 && (uiModuleID) <= g_uiModuleCount ? \ |
|
|
|
(uiModuleID) - 1 : -1) |
|
|
|
|
|
|
|
// 写入保护宏:FreeRTOS 用 mutex,裸机用关中断+自旋锁
|
|
|
|
#if defined(USE_FREERTOS) |
|
|
|
#define MSG_CENTER_LOCK(pEntry) Rd_MutexLock(&(pEntry)->stMutex, __func__, NULL) |
|
|
|
#define MSG_CENTER_UNLOCK(pEntry) Rd_MutexUnlock(&(pEntry)->stMutex, __func__, NULL) |
|
|
|
#define MSG_CENTER_LOCK_INIT(pEntry) ({ \ |
|
|
|
(pEntry)->bSpinLock = 0; \ |
|
|
|
Rd_MutexInit(&(pEntry)->stMutex); \ |
|
|
|
}) |
|
|
|
#define MSG_CENTER_LOCK_DESTROY(pEntry) Rd_MutexDestroy(&(pEntry)->stMutex) |
|
|
|
#else |
|
|
|
#define MSG_CENTER_LOCK(pEntry) do { \ |
|
|
|
(pEntry)->uiPrimask = rd_irq_save(); \ |
|
|
|
while (ATOMIC_EXCH(&(pEntry)->bSpinLock, 1, uint8_t, ATOMIC_ORDER_ACQUIRE)) {} \ |
|
|
|
} while(0) |
|
|
|
#define MSG_CENTER_UNLOCK(pEntry) do { \ |
|
|
|
ATOMIC_STORE(&(pEntry)->bSpinLock, 0, uint8_t, ATOMIC_ORDER_RELEASE); \ |
|
|
|
rd_irq_restore((pEntry)->uiPrimask); \ |
|
|
|
} while(0) |
|
|
|
#define MSG_CENTER_LOCK_INIT(pEntry) ({ (pEntry)->bSpinLock = 0; RD_SUCCESS; }) |
|
|
|
#define MSG_CENTER_LOCK_DESTROY(pEntry) ((void)(pEntry)) |
|
|
|
#endif |
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
函 数 名 : MsgCenter_Init |
|
|
|
功能描述 : 初始化消息中心 |
|
|
|
@ -128,9 +155,17 @@ uint32_t MsgCenter_Register(const char *pszName, MsgHandler_t pfHandler) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
// 初始化写入锁
|
|
|
|
if (MSG_CENTER_LOCK_INIT(&g_astModules[uiIndex]) != RD_SUCCESS) |
|
|
|
{ |
|
|
|
rd_RingbufferDestroy(g_astModules[uiIndex].pstRingBuf); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
// 初始化信号量(初始值为0,表示无消息)
|
|
|
|
if (Rd_SemInit(&g_astModules[uiIndex].stSem, 0, 0) != RD_SUCCESS) |
|
|
|
{ |
|
|
|
MSG_CENTER_LOCK_DESTROY(&g_astModules[uiIndex]); |
|
|
|
rd_RingbufferDestroy(g_astModules[uiIndex].pstRingBuf); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
@ -185,9 +220,13 @@ int MsgCenter_Send(const Msg_t *pstMsg) |
|
|
|
return RD_FAILURE; |
|
|
|
} |
|
|
|
|
|
|
|
// MPSC安全写入(ringbuffer内部关中断+自旋锁)
|
|
|
|
int iRet = rd_RingbufferPutSafe(g_astModules[iDstIndex].pstRingBuf, |
|
|
|
(const char *)pstMsg, sizeof(Msg_t)); |
|
|
|
// 加锁保护ringbuffer(FreeRTOS: mutex, 裸机: 关中断+自旋锁)
|
|
|
|
MSG_CENTER_LOCK(&g_astModules[iDstIndex]); |
|
|
|
|
|
|
|
int iRet = rd_RingbufferPut(g_astModules[iDstIndex].pstRingBuf, |
|
|
|
(const char *)pstMsg, sizeof(Msg_t)); |
|
|
|
|
|
|
|
MSG_CENTER_UNLOCK(&g_astModules[iDstIndex]); |
|
|
|
|
|
|
|
if (iRet > 0) |
|
|
|
{ |
|
|
|
@ -276,12 +315,19 @@ int MsgCenter_SendFromISR(const char *pszDstName, uint32_t uiMsgID, const void * |
|
|
|
stMsg.m_uiDataLen = uiDataLen; |
|
|
|
} |
|
|
|
|
|
|
|
// MPSC安全写入(ringbuffer内部关中断+自旋锁)
|
|
|
|
int iRet = rd_RingbufferPutSafe(g_astModules[iDstIndex].pstRingBuf, |
|
|
|
(const char *)&stMsg, sizeof(Msg_t)); |
|
|
|
// ISR安全:始终使用关中断+自旋锁(不依赖FreeRTOS mutex)
|
|
|
|
volatile uint8_t *pLock = &g_astModules[iDstIndex].bSpinLock; |
|
|
|
uint32_t primask = rd_irq_save(); |
|
|
|
while (ATOMIC_EXCH(pLock, 1, uint8_t, ATOMIC_ORDER_ACQUIRE)) {} |
|
|
|
|
|
|
|
int iRet = rd_RingbufferPut(g_astModules[iDstIndex].pstRingBuf, |
|
|
|
(const char *)&stMsg, sizeof(Msg_t)); |
|
|
|
|
|
|
|
ATOMIC_STORE(pLock, 0, uint8_t, ATOMIC_ORDER_RELEASE); |
|
|
|
rd_irq_restore(primask); |
|
|
|
|
|
|
|
if (iRet > 0) |
|
|
|
{ |
|
|
|
// 信号量在CMSIS-RTOS2中自动识别ISR上下文
|
|
|
|
Rd_SemPost(&g_astModules[iDstIndex].stSem, __func__, NULL); |
|
|
|
return RD_SUCCESS; |
|
|
|
} |
|
|
|
@ -299,9 +345,14 @@ int MsgCenter_SendFromISR(const char *pszDstName, uint32_t uiMsgID, const void * |
|
|
|
*****************************************************************************/ |
|
|
|
static int MsgCenter_ProcessOne(int iIndex, Msg_t *pstMsg) |
|
|
|
{ |
|
|
|
// 加锁保护ringbuffer
|
|
|
|
MSG_CENTER_LOCK(&g_astModules[iIndex]); |
|
|
|
|
|
|
|
int iRet = rd_RingbufferGet(g_astModules[iIndex].pstRingBuf, |
|
|
|
(char *)pstMsg, sizeof(Msg_t)); |
|
|
|
|
|
|
|
MSG_CENTER_UNLOCK(&g_astModules[iIndex]); |
|
|
|
|
|
|
|
return (iRet > 0) ? 1 : 0; |
|
|
|
} |
|
|
|
|
|
|
|
|