/****************************************************************************** 版权所有 (C), 2018-2099, Radkil ****************************************************************************** 文 件 名 : daemon_task.c 版 本 号 : 初稿 作 者 : radkil 生成日期 : 2026年9月14日 最近修改 : 功能描述 : 守护线程,用于处理各种异常 修改历史 : 1.日 期 : 2026年9月14日 作 者 : radkil 修改内容 : 创建文件 ******************************************************************************/ #include "BHBF.h" #include "msg_center.h" #include "bsp_Error.pb.h" #include "rd_time.h" /*----------------------------------------------* * 常量/宏定义(前置,供模块级变量与函数使用) * *----------------------------------------------*/ #define COM_ERROR_MODULE_NUM 7 // ComError 模块数量(位 0~6) #define COM_ERROR_TIMEOUT_THRESHOLD 2000 // 连续 N 次未收到正常信号判定为模块异常 /*----------------------------------------------* * 外部变量说明 * *----------------------------------------------*/ /*----------------------------------------------* * 外部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 内部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 全局变量 * *----------------------------------------------*/ /*----------------------------------------------* * 模块级变量 * *----------------------------------------------*/ static uint32_t g_uidaemonModuleID = 0; static int32_t g_iCom_Error_Code = 0; static uint32_t g_auiComErrorCount[COM_ERROR_MODULE_NUM] = {0}; // 各模块失联计数 static int32_t g_iCom_Error_Status = 0; // 按位记录模块异常状态:1=异常,0=正常 /*----------------------------------------------* * 常量定义 * *----------------------------------------------*/ /*----------------------------------------------* * 宏定义 * *----------------------------------------------*/ void SET_BIT_1(int32_t* num,int32_t k) { *num=((*num) | (1 << (k))); } void SET_BIT_0(int32_t* num,int32_t k) { *num=((*num) & ~(1 << (k))); } int32_t Get_BIT(int32_t* num,int32_t k) { return (*num >> (k)) & 1; } /***************************************************************************** 函 数 名 : daemon_PollComError 功能描述 : 按位轮询通信错误标志,实现各模块心跳/存活检测 位为 1 表示本周期收到模块正常信号,消费该标志并清零失联计数; 位为 0 表示本周期未收到正常信号,失联计数递增,达到阈值判定异常。 输入参数 : 无 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void daemon_PollComError(void) { static uint32_t uiLastSendTick = 0; for (int32_t i = 0; i < COM_ERROR_MODULE_NUM; i++) { if (Get_BIT(&g_iCom_Error_Code, i) == 1) { // 收到正常信号:消费标志位,等待下周期模块重新置位 SET_BIT_0(&g_iCom_Error_Code, i); g_auiComErrorCount[i] = 0; // 失联计数清零 SET_BIT_0(&g_iCom_Error_Status, i); // 标记模块正常 uint32_t uiNowTick = Rd_GetTime(); if ((int32_t)(uiNowTick - uiLastSendTick) >= 1000) { uiLastSendTick = uiNowTick; MsgCenter_SendTo(MODULE_NAME_CUSTOM, CUSTOM_GET_DAEMON_CODE, &g_iCom_Error_Status, sizeof(int32_t)); } } else { // 未收到正常信号:失联计数递增 g_auiComErrorCount[i]++; if (g_auiComErrorCount[i] >= COM_ERROR_TIMEOUT_THRESHOLD) { SET_BIT_1(&g_iCom_Error_Status, i); // 判定模块异常 g_auiComErrorCount[i] = COM_ERROR_TIMEOUT_THRESHOLD; // 计数封顶,避免溢出 MsgCenter_SendTo(MODULE_NAME_CUSTOM, CUSTOM_GET_DAEMON_CODE, &g_iCom_Error_Status, sizeof(int32_t)); } } } } static void daemon_ModuleHandler(const Msg_t *pstMsg) { if (NULL == pstMsg) { return; } switch (pstMsg->m_uiMsgID) { case DAEMON_SET_MK32_SBUS: { SET_BIT_1(&g_iCom_Error_Code, ComError_MK32_SBus); break; } case DAEMON_SET_TL720D: { SET_BIT_1(&g_iCom_Error_Code, ComError_TL720D); break; } case DAEMON_SET_LEFT_MOTOR: { SET_BIT_1(&g_iCom_Error_Code, ComError_LS_LeftMotor); break; } case DAEMON_SET_RIGHT_MOTOR: { SET_BIT_1(&g_iCom_Error_Code, ComError_LS_RightMotor); break; } case DAEMON_SET_BUTTON_RESET: { SET_BIT_1(&g_iCom_Error_Code, ComError_Remote_Button_Reset_State); break; } case DAEMON_SET_MK32_SERIAL: { SET_BIT_1(&g_iCom_Error_Code, ComError_MK32_Serial); break; } case DAEMON_SET_MK32_UDP: { SET_BIT_1(&g_iCom_Error_Code, ComError_MK32_UDP); break; } default: break; } } void daemon_task(void *argument) { while(1) { MsgCenter_ProcessWait(g_uidaemonModuleID, 2); daemon_PollComError(); } } void daemon_Init(void) { g_uidaemonModuleID = MsgCenter_Register(MODULE_NAME_DAEMON, daemon_ModuleHandler); const osThreadAttr_t daemon_attributes = { .name = MODULE_NAME_DAEMON, .stack_size = THREAD_DEFAULT_STACK, .priority = (osPriority_t) osPriorityRealtime1, }; (void)osThreadNew(daemon_task, NULL, &daemon_attributes); }