12 changed files with 310 additions and 38 deletions
@ -0,0 +1,56 @@ |
|||
/*
|
|||
* bsp_devic_moniter.h |
|||
* |
|||
* Created on: 2026年6月1日 |
|||
* Author: bm673 |
|||
*/ |
|||
|
|||
#ifndef BASE_INC_BSP_BSP_DEVIC_MONITER_H_ |
|||
#define BASE_INC_BSP_BSP_DEVIC_MONITER_H_ |
|||
|
|||
#include <stdint.h> |
|||
#include "stm32h7xx_hal.h" |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/*==========================
|
|||
* 设备ID |
|||
*==========================*/ |
|||
typedef enum { |
|||
//DEV_GYRO = 0,
|
|||
//DEV_SBUS,
|
|||
DEV_LEFT_MOTOR=0, |
|||
//DEV_RIGHT_MOTOR,
|
|||
DEV_COUNT // 总设备数
|
|||
} DeviceId; |
|||
|
|||
/*==========================
|
|||
* 错误码,每位对应一个设备 |
|||
*==========================*/ |
|||
extern uint32_t g_error_code; |
|||
|
|||
/*==========================
|
|||
* 接口函数 |
|||
*==========================*/ |
|||
|
|||
/* 初始化链表及错误码 */ |
|||
void DevMon_Init(); |
|||
|
|||
/* 心跳上报 */ |
|||
void DevMon_Feed(DeviceId id); |
|||
|
|||
/* 轮询检测超时,更新错误码 */ |
|||
void DevMon_Task(); |
|||
|
|||
/* 判断设备是否在线 */ |
|||
uint8_t DevMon_IsOnline(DeviceId id); |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
|
|||
|
|||
#endif /* BASE_INC_BSP_BSP_DEVIC_MONITER_H_ */ |
|||
@ -0,0 +1,140 @@ |
|||
/*
|
|||
* Devic_moniter.c |
|||
* |
|||
* Created on: 2026年6月1日 |
|||
* Author: bm673 |
|||
*/ |
|||
/*
|
|||
* bsp_devic_monitor.c |
|||
* 静态链表版设备心跳监测 |
|||
*/ |
|||
|
|||
#include "bsp_devic_moniter.h" |
|||
#include <string.h> |
|||
#include "BSP/bsp_include.h" |
|||
|
|||
/* 注册设备到链表 */ |
|||
void DevMon_Register(DeviceId id,uint32_t timeout_ms, uint32_t first_delay_ms); |
|||
/*==========================
|
|||
* 节点结构 |
|||
*==========================*/ |
|||
typedef struct { |
|||
DeviceId id; // 设备ID
|
|||
uint32_t timeout_ms; // 正常心跳超时
|
|||
uint32_t first_delay_ms; // 首次上报允许延迟
|
|||
uint32_t last_tick; // 上次心跳时间
|
|||
uint8_t first_reported; // 是否收到首次心跳
|
|||
int next; // 链表索引
|
|||
} DevNode_t; |
|||
|
|||
/*==========================
|
|||
* 静态链表池 |
|||
*==========================*/ |
|||
static DevNode_t s_node[DEV_COUNT]; |
|||
static int s_head = -1; // 链表头
|
|||
|
|||
/* 全局错误码 */ |
|||
uint32_t g_error_code = 0; |
|||
|
|||
/*==========================
|
|||
* 初始化 |
|||
*==========================*/ |
|||
void DevMon_Init() |
|||
{ |
|||
uint32_t tick=HAL_GetTick(); |
|||
memset(s_node, 0, sizeof(s_node));//将节点数组都置位
|
|||
s_head = -1; //设置链表为空
|
|||
g_error_code = 0; //设置错误为空
|
|||
|
|||
for (int i = 0; i < DEV_COUNT; i++) { |
|||
s_node[i].last_tick = tick; //更新系统失控
|
|||
s_node[i].next = -1; //这为啥都置位-1我是不理解的
|
|||
s_node[i].id = (DeviceId)i; // 初始化ID
|
|||
|
|||
} |
|||
|
|||
//DevMon_Register(DEV_GYRO, 1000, 1000);
|
|||
//DevMon_Register(DEV_SBUS, 1000, 3000);
|
|||
DevMon_Register(DEV_LEFT_MOTOR, 1000, 30000); |
|||
//DevMon_Register(DEV_RIGHT_MOTOR, 200, 4000);
|
|||
|
|||
GF_BSP_Interrupt_Add_CallBack(DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, DevMon_Task); |
|||
} |
|||
|
|||
/*==========================
|
|||
* 注册设备 |
|||
*==========================*/ |
|||
void DevMon_Register(DeviceId id, |
|||
uint32_t timeout_ms, |
|||
uint32_t first_delay_ms) |
|||
{ |
|||
if (id >= DEV_COUNT) return; |
|||
|
|||
s_node[id].timeout_ms = timeout_ms; |
|||
s_node[id].first_delay_ms = first_delay_ms; |
|||
s_node[id].first_reported = 0; |
|||
s_node[id].next = s_head; |
|||
s_head = id; |
|||
|
|||
|
|||
g_error_code &= ~(1U << id); // 清除错误位
|
|||
} |
|||
|
|||
/*==========================
|
|||
* 心跳上报 |
|||
*==========================*/ |
|||
void DevMon_Feed(DeviceId id) |
|||
{ |
|||
uint32_t tick=HAL_GetTick(); |
|||
|
|||
if (id >= DEV_COUNT) return; //
|
|||
|
|||
s_node[id].last_tick = tick; |
|||
s_node[id].first_reported = 1; |
|||
|
|||
g_error_code &= ~(1U << id); //把第id位清0,其他不变
|
|||
} |
|||
|
|||
/*==========================
|
|||
* 周期检测 |
|||
*==========================*/ |
|||
uint32_t elapsed; |
|||
uint32_t timeout; |
|||
uint32_t last_time; |
|||
uint32_t now_time; |
|||
void DevMon_Task() |
|||
{ |
|||
uint32_t tick=HAL_GetTick(); |
|||
int curr = s_head; |
|||
while (curr != -1) |
|||
{ |
|||
DevNode_t *node = &s_node[curr]; //这句话,我不太理解
|
|||
|
|||
elapsed = tick - node->last_tick; //这句话我理解,就是在判断是否超时
|
|||
last_time=node->last_tick; |
|||
now_time=tick; |
|||
timeout = node->first_reported ? node->timeout_ms : node->first_delay_ms; |
|||
|
|||
|
|||
if (elapsed > timeout) |
|||
g_error_code |= (1U << node->id); //把第id位置1,其他不变
|
|||
else |
|||
g_error_code &= ~(1U << node->id); //把第id位清0,其他不变
|
|||
|
|||
curr = node->next; |
|||
} |
|||
// 也可以用for替代
|
|||
} |
|||
|
|||
/*==========================
|
|||
* 判断在线 |
|||
*==========================*/ |
|||
uint8_t DevMon_IsOnline(DeviceId id) |
|||
{ |
|||
if (id >= DEV_COUNT) return 0; |
|||
|
|||
return (g_error_code & (1U << id)) ? 0 : 1; |
|||
} |
|||
|
|||
|
|||
|
|||
Loading…
Reference in new issue