Files
cbb 70daa4b0c6 feat(DCU_APP): 添加CPU负载监控和EtherCAT诊断功能
- 在DCU_APP项目中添加cpu_load.h和cpu_load.cpp模块用于CPU负载率监测
- 修改csolution配置将构建目标从Debug切换为Release
- 在EtherCAT PDO协议栈中新增段5诊断区(632-639字节),包含负载率和序列号
- 在所有关键中断服务程序中添加CpuLoad::isrEnter()/isrExit()钩子用于准确统计中断占用
- 增强EtherCAT同步中断处理,改进AL事件掩码守护机制,修复OP状态下PDI中断门控问题
- 解决SSC源码中指针地址对齐警告和打包成员访问警告问题
- 在主循环中集成CPU负载率采样tick()调用,实现1秒滚动窗口统计

BREAKING CHANGE: 构建配置从Debug改为Release,EtherCAT协议栈增加新的诊断数据区
2026-09-05 20:07:22 +08:00

115 lines
3.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file timer.cpp
* @brief 用户调度定时器模块实现。
*/
#include "main.h"
#include "device/timer.h"
#include "sys/task_manager.h"
#include "sys/systick.h"
#include "sys/cpu_load.h"
#include "sys/config.h"
/**
* @brief 配置用户调度定时器本体参数。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 使用 `CONFIG_SCHED_TIMER_*` 系列配置完成 TIMER2 的 100us 调度时基初始化。
*/
void SchedulerTimer::configureTimer()
{
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(CONFIG_SCHED_TIMER_RCU);
timer_deinit(CONFIG_SCHED_TIMER_INSTANCE);
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = CONFIG_SCHED_TIMER_PRESCALER;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = CONFIG_SCHED_TIMER_PERIOD;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(CONFIG_SCHED_TIMER_INSTANCE, &timer_initpara);
timer_interrupt_flag_clear(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_FLAG_UP);
timer_interrupt_enable(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_UP);
timer_enable(CONFIG_SCHED_TIMER_INSTANCE);
}
/**
* @brief 配置用户调度定时器对应的 NVIC。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 优先级分组已前移至 AppInitializer::init() 最开头统一设置;此处仅为调度定时器中断向量配置抢占优先级与子优先级。
*/
void SchedulerTimer::configureNvic()
{
nvic_irq_enable(CONFIG_SCHED_TIMER_IRQn, CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO, CONFIG_SCHED_TIMER_IRQ_SUB_PRIO);
}
/**
* @brief 初始化用户调度定时器模块并验证节拍运行。
* @param[in] 无。
* @param[out] 无。
* @retval uint8_t SchedulerTimer::InitFault 故障码(0=回读一致且 tick_100us 已前进)。
* @note 依次完成定时器本体配置与 NVIC 中断配置;
* 验证覆盖"中断向量/优先级配错导致调度器静默停摆"这类纯写配置发现不了的故障。
*/
uint8_t SchedulerTimer::init()
{
configureTimer();
configureNvic();
/* 回读:计数器已使能、PSC/CAR 与配置一致 */
if ((TIMER_CTL0(CONFIG_SCHED_TIMER_INSTANCE) & TIMER_CTL0_CEN) == 0U) {
return kFaultNotEnabled;
}
if (TIMER_PSC(CONFIG_SCHED_TIMER_INSTANCE) != CONFIG_SCHED_TIMER_PRESCALER) {
return kFaultPscMismatch;
}
if (TIMER_CAR(CONFIG_SCHED_TIMER_INSTANCE) != CONFIG_SCHED_TIMER_PERIOD) {
return kFaultCarMismatch;
}
/* 有界等待 100us 中断节拍前进(50ms 预算 = 500 个 tick) */
const uint32_t start = g_scheduler.tick_100us;
const uint32_t deadline = SysTickTimer::getMs() + 50U;
while (g_scheduler.tick_100us == start) {
if ((int32_t)(SysTickTimer::getMs() - deadline) >= 0) {
return kFaultNoTick;
}
}
return kFaultOk;
}
/**
* @brief 用户调度定时器中断处理入口。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 响应更新中断,清除中断标志后推进一次 `TaskManager::tick100us()`。
*/
void SchedulerTimer::onInterrupt()
{
if(timer_interrupt_flag_get(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_FLAG_UP) == RESET) return;
timer_interrupt_flag_clear(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_FLAG_UP);
TaskManager::tick100us();
}
/* ----- 中断入口 C 包装 ---------------------------------------------- */
/**
* @brief TIMER2 中断向量入口。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note C 向量包装函数,内部转调 `SchedulerTimer::onInterrupt()`。
*/
extern "C" void TIMER2_IRQHandler(void)
{
CpuLoad::isrEnter();
SchedulerTimer::onInterrupt();
CpuLoad::isrExit();
}