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