feat: 添加GD32E508 DCU应用工程的初始结构
- 新增完整的CMSIS解决方案配置,包含AC6/GCC/IAR/CLANG编译器支持 - 添加项目配置文件,定义了设备层、系统层、应用层的模块结构 - 配置ARM::CMSIS和GigaDevice::GD32E50x_DFP软件包依赖 - 创建多层代码架构:应用入口(main)、系统层(sys)、设备层(device) - 实现任务管理系统,包含任务调度器和任务执行器分离设计 - 集成ADC、CANFD、定时器、串口、温度采样等核心功能模块 - 添加详细的README文档说明项目结构和代码组织方式 - 配置AC6链接脚本和运行时环境文件 - 设置Git忽略规则以排除编译产物和临时文件
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 应用级集中配置项定义。
|
||||
* @note 用于统一管理当前项目中可调的外设、时序、通信与算法常量。
|
||||
*/
|
||||
#ifndef SYS_CONFIG_H
|
||||
#define SYS_CONFIG_H
|
||||
|
||||
/** @brief 应用启动横幅字符串。 */
|
||||
#define APP_BANNER_TEXT "GD32E508 DCU task scheduler start"
|
||||
|
||||
/** @brief USART0 默认波特率。 */
|
||||
#define CONFIG_USART0_BAUDRATE 115200U
|
||||
|
||||
/** @brief ADC 外设实例。 */
|
||||
#define CONFIG_ADC_INSTANCE ADC0
|
||||
/** @brief ADC 外部 VIN 检测通道号(原理图:PA6 -> VIN_ADC)。 */
|
||||
#define CONFIG_ADC_VIN_CHANNEL ADC_CHANNEL_6
|
||||
/** @brief ADC 内部温度通道号。 */
|
||||
#define CONFIG_ADC_TEMP_CHANNEL ADC_CHANNEL_16
|
||||
/** @brief ADC 内部参考电压通道号。 */
|
||||
#define CONFIG_ADC_VREFINT_CHANNEL ADC_CHANNEL_17
|
||||
/** @brief ADC 满量程计数值。 */
|
||||
#define CONFIG_ADC_MAX_VALUE 4095.0f
|
||||
/** @brief 内部参考电压典型值,单位 V。 */
|
||||
#define CONFIG_ADC_VREFINT_TYPICAL_VOLTAGE 1.20f
|
||||
/** @brief 温度传感器 25℃ 对应电压,单位 V。 */
|
||||
#define CONFIG_ADC_TEMP_V25 1.43f
|
||||
/** @brief 温度传感器平均斜率,单位 V/℃。 */
|
||||
#define CONFIG_ADC_TEMP_AVG_SLOPE 0.0043f
|
||||
/** @brief ADC 上电后稳定等待时间,单位 ms。 */
|
||||
#define CONFIG_ADC_STABILIZE_DELAY_MS 2U
|
||||
/** @brief ADC 规则通道采样时间配置。 */
|
||||
#define CONFIG_ADC_SAMPLE_TIME ADC_SAMPLETIME_239POINT5
|
||||
/** @brief ADC 空输入保护时默认 VDDA,单位 V。 */
|
||||
#define CONFIG_ADC_DEFAULT_VDDA 3.3f
|
||||
|
||||
/** @brief CAN 外设实例。 */
|
||||
#define CONFIG_CAN_INSTANCE CAN0
|
||||
/** @brief CAN 外设时钟使能枚举。 */
|
||||
#define CONFIG_CAN_RCU RCU_CAN0
|
||||
/** @brief CAN 状态报文标准帧 ID。 */
|
||||
#define CONFIG_CAN_STATUS_ID 0x321U
|
||||
/** @brief CAN 状态载荷中调试标识字符 0。 */
|
||||
#define CONFIG_CAN_STATUS_TAG0 0x43U
|
||||
/** @brief CAN 状态载荷中调试标识字符 1。 */
|
||||
#define CONFIG_CAN_STATUS_TAG1 0x41U
|
||||
/** @brief CAN 状态载荷中调试标识字符 2。 */
|
||||
#define CONFIG_CAN_STATUS_TAG2 0x4EU
|
||||
/** @brief CAN 状态载荷中调试标识字符 3。 */
|
||||
#define CONFIG_CAN_STATUS_TAG3 0x46U
|
||||
|
||||
/** @brief 用户调度定时器实例。 */
|
||||
#define CONFIG_SCHED_TIMER_INSTANCE TIMER2
|
||||
/** @brief 用户调度定时器中断号。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQn TIMER2_IRQn
|
||||
/** @brief 用户调度定时器时钟使能宏参数。 */
|
||||
#define CONFIG_SCHED_TIMER_RCU RCU_TIMER2
|
||||
/** @brief 用户调度定时器预分频值。 */
|
||||
#define CONFIG_SCHED_TIMER_PRESCALER 179U
|
||||
/** @brief 用户调度定时器周期重装值。 */
|
||||
#define CONFIG_SCHED_TIMER_PERIOD 99U
|
||||
/** @brief 用户调度定时器 NVIC 抢占优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO 1U
|
||||
/** @brief 用户调度定时器 NVIC 子优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_SUB_PRIO 0U
|
||||
|
||||
/** @brief 调度基准节拍:ADC VREF 采样周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS 5U
|
||||
/** @brief 调度基准节拍:ADC 温度采样/处理周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS 10U
|
||||
/** @brief 调度基准节拍:CAN 接收轮询/解析周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_RX_TICKS 100U
|
||||
/** @brief 调度基准节拍:CAN 发送/状态灯周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_TX_TICKS 1000U
|
||||
/** @brief 调度基准节拍:心跳/诊断打印周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_HEARTBEAT_TICKS 10000U
|
||||
|
||||
#endif /* SYS_CONFIG_H */
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 应用级集中配置项定义。
|
||||
* @note 用于统一管理当前项目中可调的外设、时序、通信与算法常量。
|
||||
*/
|
||||
#ifndef SYS_CONFIG_H
|
||||
#define SYS_CONFIG_H
|
||||
|
||||
/** @brief 应用启动横幅字符串。 */
|
||||
#define APP_BANNER_TEXT "GD32E508 DCU task scheduler start"
|
||||
|
||||
/** @brief USART0 默认波特率。 */
|
||||
#define CONFIG_USART0_BAUDRATE 115200U
|
||||
|
||||
/** @brief ADC 外设实例。 */
|
||||
#define CONFIG_ADC_INSTANCE ADC0
|
||||
/** @brief ADC 内部温度通道号。 */
|
||||
#define CONFIG_ADC_TEMP_CHANNEL ADC_CHANNEL_16
|
||||
/** @brief ADC 内部参考电压通道号。 */
|
||||
#define CONFIG_ADC_VREFINT_CHANNEL ADC_CHANNEL_17
|
||||
/** @brief ADC 满量程计数值。 */
|
||||
#define CONFIG_ADC_MAX_VALUE 4095.0f
|
||||
/** @brief 内部参考电压典型值,单位 V。 */
|
||||
#define CONFIG_ADC_VREFINT_TYPICAL_VOLTAGE 1.20f
|
||||
/** @brief 温度传感器 25℃ 对应电压,单位 V。 */
|
||||
#define CONFIG_ADC_TEMP_V25 1.43f
|
||||
/** @brief 温度传感器平均斜率,单位 V/℃。 */
|
||||
#define CONFIG_ADC_TEMP_AVG_SLOPE 0.0043f
|
||||
/** @brief ADC 上电后稳定等待时间,单位 ms。 */
|
||||
#define CONFIG_ADC_STABILIZE_DELAY_MS 2U
|
||||
/** @brief ADC 规则通道采样时间配置。 */
|
||||
#define CONFIG_ADC_SAMPLE_TIME ADC_SAMPLETIME_239POINT5
|
||||
/** @brief ADC 空输入保护时默认 VDDA,单位 V。 */
|
||||
#define CONFIG_ADC_DEFAULT_VDDA 3.3f
|
||||
|
||||
/** @brief CAN 外设实例。 */
|
||||
#define CONFIG_CAN_INSTANCE CAN0
|
||||
/** @brief CAN 外设时钟使能枚举。 */
|
||||
#define CONFIG_CAN_RCU RCU_CAN0
|
||||
/** @brief CAN 状态报文标准帧 ID。 */
|
||||
#define CONFIG_CAN_STATUS_ID 0x321U
|
||||
/** @brief CAN 标称波特率预分频值。 */
|
||||
#define CONFIG_CAN_NOMINAL_BAUD_PRESCALER 12U
|
||||
/** @brief CAN 状态载荷中调试标识字符 0。 */
|
||||
#define CONFIG_CAN_STATUS_TAG0 0x43U
|
||||
/** @brief CAN 状态载荷中调试标识字符 1。 */
|
||||
#define CONFIG_CAN_STATUS_TAG1 0x41U
|
||||
/** @brief CAN 状态载荷中调试标识字符 2。 */
|
||||
#define CONFIG_CAN_STATUS_TAG2 0x4EU
|
||||
/** @brief CAN 状态载荷中调试标识字符 3。 */
|
||||
#define CONFIG_CAN_STATUS_TAG3 0x46U
|
||||
|
||||
/** @brief 用户调度定时器实例。 */
|
||||
#define CONFIG_SCHED_TIMER_INSTANCE TIMER2
|
||||
/** @brief 用户调度定时器中断号。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQn TIMER2_IRQn
|
||||
/** @brief 用户调度定时器时钟使能宏参数。 */
|
||||
#define CONFIG_SCHED_TIMER_RCU RCU_TIMER2
|
||||
/** @brief 用户调度定时器预分频值。 */
|
||||
#define CONFIG_SCHED_TIMER_PRESCALER 179U
|
||||
/** @brief 用户调度定时器周期重装值。 */
|
||||
#define CONFIG_SCHED_TIMER_PERIOD 99U
|
||||
/** @brief 用户调度定时器 NVIC 抢占优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO 1U
|
||||
/** @brief 用户调度定时器 NVIC 子优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_SUB_PRIO 0U
|
||||
|
||||
/** @brief 调度基准节拍:ADC VREF 采样周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS 5U
|
||||
/** @brief 调度基准节拍:ADC 温度采样/处理周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS 10U
|
||||
/** @brief 调度基准节拍:CAN 接收轮询/解析周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_RX_TICKS 100U
|
||||
/** @brief 调度基准节拍:CAN 发送/状态灯周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_TX_TICKS 1000U
|
||||
/** @brief 调度基准节拍:心跳/诊断打印周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_HEARTBEAT_TICKS 10000U
|
||||
|
||||
#endif /* SYS_CONFIG_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 应用级集中配置项定义。
|
||||
* @note 用于统一管理当前项目中可调的外设、时序、通信与算法常量。
|
||||
*/
|
||||
#ifndef SYS_CONFIG_H
|
||||
#define SYS_CONFIG_H
|
||||
|
||||
/** @brief 应用启动横幅字符串。 */
|
||||
#define APP_BANNER_TEXT "GD32E508 DCU task scheduler start"
|
||||
|
||||
/** @brief USART0 默认波特率。 */
|
||||
#define CONFIG_USART0_BAUDRATE 115200U
|
||||
|
||||
/** @brief ADC 外设实例。 */
|
||||
#define CONFIG_ADC_INSTANCE ADC0
|
||||
/** @brief ADC 内部温度通道号。 */
|
||||
#define CONFIG_ADC_TEMP_CHANNEL ADC_CHANNEL_16
|
||||
/** @brief ADC 内部参考电压通道号。 */
|
||||
#define CONFIG_ADC_VREFINT_CHANNEL ADC_CHANNEL_17
|
||||
/** @brief ADC 满量程计数值。 */
|
||||
#define CONFIG_ADC_MAX_VALUE 4095.0f
|
||||
/** @brief 内部参考电压典型值,单位 V。 */
|
||||
#define CONFIG_ADC_VREFINT_TYPICAL_VOLTAGE 1.20f
|
||||
/** @brief 温度传感器 25℃ 对应电压,单位 V。 */
|
||||
#define CONFIG_ADC_TEMP_V25 1.43f
|
||||
/** @brief 温度传感器平均斜率,单位 V/℃。 */
|
||||
#define CONFIG_ADC_TEMP_AVG_SLOPE 0.0043f
|
||||
/** @brief ADC 上电后稳定等待时间,单位 ms。 */
|
||||
#define CONFIG_ADC_STABILIZE_DELAY_MS 2U
|
||||
/** @brief ADC 规则通道采样时间配置。 */
|
||||
#define CONFIG_ADC_SAMPLE_TIME ADC_SAMPLETIME_239POINT5
|
||||
/** @brief ADC 空输入保护时默认 VDDA,单位 V。 */
|
||||
#define CONFIG_ADC_DEFAULT_VDDA 3.3f
|
||||
|
||||
/** @brief CAN 外设实例。 */
|
||||
#define CONFIG_CAN_INSTANCE CAN0
|
||||
/** @brief CAN 状态报文标准帧 ID。 */
|
||||
#define CONFIG_CAN_STATUS_ID 0x321U
|
||||
/** @brief CAN 标称波特率预分频值。 */
|
||||
#define CONFIG_CAN_NOMINAL_BAUD_PRESCALER 12U
|
||||
/** @brief CAN 状态载荷中调试标识字符 0。 */
|
||||
#define CONFIG_CAN_STATUS_TAG0 0x43U
|
||||
/** @brief CAN 状态载荷中调试标识字符 1。 */
|
||||
#define CONFIG_CAN_STATUS_TAG1 0x41U
|
||||
/** @brief CAN 状态载荷中调试标识字符 2。 */
|
||||
#define CONFIG_CAN_STATUS_TAG2 0x4EU
|
||||
/** @brief CAN 状态载荷中调试标识字符 3。 */
|
||||
#define CONFIG_CAN_STATUS_TAG3 0x46U
|
||||
|
||||
/** @brief 用户调度定时器实例。 */
|
||||
#define CONFIG_SCHED_TIMER_INSTANCE TIMER2
|
||||
/** @brief 用户调度定时器中断号。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQn TIMER2_IRQn
|
||||
/** @brief 用户调度定时器时钟使能宏参数。 */
|
||||
#define CONFIG_SCHED_TIMER_RCU RCU_TIMER2
|
||||
/** @brief 用户调度定时器预分频值。 */
|
||||
#define CONFIG_SCHED_TIMER_PRESCALER 179U
|
||||
/** @brief 用户调度定时器周期重装值。 */
|
||||
#define CONFIG_SCHED_TIMER_PERIOD 99U
|
||||
/** @brief 用户调度定时器 NVIC 抢占优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO 1U
|
||||
/** @brief 用户调度定时器 NVIC 子优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_SUB_PRIO 0U
|
||||
|
||||
/** @brief 调度基准节拍:ADC VREF 采样周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS 5U
|
||||
/** @brief 调度基准节拍:ADC 温度采样/处理周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS 10U
|
||||
/** @brief 调度基准节拍:CAN 接收轮询/解析周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_RX_TICKS 100U
|
||||
/** @brief 调度基准节拍:CAN 发送/状态灯周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_TX_TICKS 1000U
|
||||
/** @brief 调度基准节拍:心跳/诊断打印周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_HEARTBEAT_TICKS 10000U
|
||||
|
||||
#endif /* SYS_CONFIG_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 应用级集中配置项定义。
|
||||
* @note 用于统一管理当前项目中可调的外设、时序、通信与算法常量。
|
||||
*/
|
||||
#ifndef SYS_CONFIG_H
|
||||
#define SYS_CONFIG_H
|
||||
|
||||
/** @brief 应用启动横幅字符串。 */
|
||||
#define APP_BANNER_TEXT "GD32E508 DCU task scheduler start"
|
||||
|
||||
/** @brief USART0 默认波特率。 */
|
||||
#define CONFIG_USART0_BAUDRATE 115200U
|
||||
|
||||
/** @brief ADC 外设实例。 */
|
||||
#define CONFIG_ADC_INSTANCE ADC0
|
||||
/** @brief ADC 内部温度通道号。 */
|
||||
#define CONFIG_ADC_TEMP_CHANNEL ADC_CHANNEL_16
|
||||
/** @brief ADC 内部参考电压通道号。 */
|
||||
#define CONFIG_ADC_VREFINT_CHANNEL ADC_CHANNEL_17
|
||||
/** @brief ADC 满量程计数值。 */
|
||||
#define CONFIG_ADC_MAX_VALUE 4095.0f
|
||||
/** @brief 内部参考电压典型值,单位 V。 */
|
||||
#define CONFIG_ADC_VREFINT_TYPICAL_VOLTAGE 1.20f
|
||||
/** @brief 温度传感器 25℃ 对应电压,单位 V。 */
|
||||
#define CONFIG_ADC_TEMP_V25 1.43f
|
||||
/** @brief 温度传感器平均斜率,单位 V/℃。 */
|
||||
#define CONFIG_ADC_TEMP_AVG_SLOPE 0.0043f
|
||||
/** @brief ADC 上电后稳定等待时间,单位 ms。 */
|
||||
#define CONFIG_ADC_STABILIZE_DELAY_MS 2U
|
||||
/** @brief ADC 规则通道采样时间配置。 */
|
||||
#define CONFIG_ADC_SAMPLE_TIME ADC_SAMPLETIME_239POINT5
|
||||
/** @brief ADC 空输入保护时默认 VDDA,单位 V。 */
|
||||
#define CONFIG_ADC_DEFAULT_VDDA 3.3f
|
||||
|
||||
/** @brief CAN 外设实例。 */
|
||||
#define CONFIG_CAN_INSTANCE CAN0
|
||||
/** @brief CAN 外设时钟使能枚举。 */
|
||||
#define CONFIG_CAN_RCU RCU_CAN0
|
||||
/** @brief CAN 状态报文标准帧 ID。 */
|
||||
#define CONFIG_CAN_STATUS_ID 0x321U
|
||||
/** @brief CAN 状态载荷中调试标识字符 0。 */
|
||||
#define CONFIG_CAN_STATUS_TAG0 0x43U
|
||||
/** @brief CAN 状态载荷中调试标识字符 1。 */
|
||||
#define CONFIG_CAN_STATUS_TAG1 0x41U
|
||||
/** @brief CAN 状态载荷中调试标识字符 2。 */
|
||||
#define CONFIG_CAN_STATUS_TAG2 0x4EU
|
||||
/** @brief CAN 状态载荷中调试标识字符 3。 */
|
||||
#define CONFIG_CAN_STATUS_TAG3 0x46U
|
||||
|
||||
/** @brief 用户调度定时器实例。 */
|
||||
#define CONFIG_SCHED_TIMER_INSTANCE TIMER2
|
||||
/** @brief 用户调度定时器中断号。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQn TIMER2_IRQn
|
||||
/** @brief 用户调度定时器时钟使能宏参数。 */
|
||||
#define CONFIG_SCHED_TIMER_RCU RCU_TIMER2
|
||||
/** @brief 用户调度定时器预分频值。 */
|
||||
#define CONFIG_SCHED_TIMER_PRESCALER 179U
|
||||
/** @brief 用户调度定时器周期重装值。 */
|
||||
#define CONFIG_SCHED_TIMER_PERIOD 99U
|
||||
/** @brief 用户调度定时器 NVIC 抢占优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO 1U
|
||||
/** @brief 用户调度定时器 NVIC 子优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_SUB_PRIO 0U
|
||||
|
||||
/** @brief 调度基准节拍:ADC VREF 采样周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS 5U
|
||||
/** @brief 调度基准节拍:ADC 温度采样/处理周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS 10U
|
||||
/** @brief 调度基准节拍:CAN 接收轮询/解析周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_RX_TICKS 100U
|
||||
/** @brief 调度基准节拍:CAN 发送/状态灯周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_TX_TICKS 1000U
|
||||
/** @brief 调度基准节拍:心跳/诊断打印周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_HEARTBEAT_TICKS 10000U
|
||||
|
||||
#endif /* SYS_CONFIG_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 应用级集中配置项定义。
|
||||
* @note 用于统一管理当前项目中可调的外设、时序、通信与算法常量。
|
||||
*/
|
||||
#ifndef SYS_CONFIG_H
|
||||
#define SYS_CONFIG_H
|
||||
|
||||
/** @brief 应用启动横幅字符串。 */
|
||||
#define APP_BANNER_TEXT "GD32E508 DCU task scheduler start"
|
||||
|
||||
/** @brief USART0 默认波特率。 */
|
||||
#define CONFIG_USART0_BAUDRATE 115200U
|
||||
|
||||
/** @brief ADC 外设实例。 */
|
||||
#define CONFIG_ADC_INSTANCE ADC0
|
||||
/** @brief ADC 内部温度通道号。 */
|
||||
#define CONFIG_ADC_TEMP_CHANNEL ADC_CHANNEL_16
|
||||
/** @brief ADC 内部参考电压通道号。 */
|
||||
#define CONFIG_ADC_VREFINT_CHANNEL ADC_CHANNEL_17
|
||||
/** @brief ADC 满量程计数值。 */
|
||||
#define CONFIG_ADC_MAX_VALUE 4095.0f
|
||||
/** @brief 内部参考电压典型值,单位 V。 */
|
||||
#define CONFIG_ADC_VREFINT_TYPICAL_VOLTAGE 1.20f
|
||||
/** @brief 温度传感器 25℃ 对应电压,单位 V。 */
|
||||
#define CONFIG_ADC_TEMP_V25 1.43f
|
||||
/** @brief 温度传感器平均斜率,单位 V/℃。 */
|
||||
#define CONFIG_ADC_TEMP_AVG_SLOPE 0.0043f
|
||||
/** @brief ADC 上电后稳定等待时间,单位 ms。 */
|
||||
#define CONFIG_ADC_STABILIZE_DELAY_MS 2U
|
||||
/** @brief ADC 规则通道采样时间配置。 */
|
||||
#define CONFIG_ADC_SAMPLE_TIME ADC_SAMPLETIME_239POINT5
|
||||
/** @brief ADC 空输入保护时默认 VDDA,单位 V。 */
|
||||
#define CONFIG_ADC_DEFAULT_VDDA 3.3f
|
||||
|
||||
/** @brief CAN 外设实例。 */
|
||||
#define CONFIG_CAN_INSTANCE CAN0
|
||||
/** @brief CAN 外设时钟使能枚举。 */
|
||||
#define CONFIG_CAN_RCU RCU_CAN0
|
||||
/** @brief CAN 状态报文标准帧 ID。 */
|
||||
#define CONFIG_CAN_STATUS_ID 0x321U
|
||||
/** @brief CAN 状态载荷中调试标识字符 0。 */
|
||||
#define CONFIG_CAN_STATUS_TAG0 0x43U
|
||||
/** @brief CAN 状态载荷中调试标识字符 1。 */
|
||||
#define CONFIG_CAN_STATUS_TAG1 0x41U
|
||||
/** @brief CAN 状态载荷中调试标识字符 2。 */
|
||||
#define CONFIG_CAN_STATUS_TAG2 0x4EU
|
||||
/** @brief CAN 状态载荷中调试标识字符 3。 */
|
||||
#define CONFIG_CAN_STATUS_TAG3 0x46U
|
||||
|
||||
/** @brief 用户调度定时器实例。 */
|
||||
#define CONFIG_SCHED_TIMER_INSTANCE TIMER2
|
||||
/** @brief 用户调度定时器中断号。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQn TIMER2_IRQn
|
||||
/** @brief 用户调度定时器时钟使能宏参数。 */
|
||||
#define CONFIG_SCHED_TIMER_RCU RCU_TIMER2
|
||||
/** @brief 用户调度定时器预分频值。 */
|
||||
#define CONFIG_SCHED_TIMER_PRESCALER 179U
|
||||
/** @brief 用户调度定时器周期重装值。 */
|
||||
#define CONFIG_SCHED_TIMER_PERIOD 99U
|
||||
/** @brief 用户调度定时器 NVIC 抢占优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO 1U
|
||||
/** @brief 用户调度定时器 NVIC 子优先级。 */
|
||||
#define CONFIG_SCHED_TIMER_IRQ_SUB_PRIO 0U
|
||||
|
||||
/** @brief 调度基准节拍:ADC VREF 采样周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS 5U
|
||||
/** @brief 调度基准节拍:ADC 温度采样/处理周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS 10U
|
||||
/** @brief 调度基准节拍:CAN 接收轮询/解析周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_RX_TICKS 100U
|
||||
/** @brief 调度基准节拍:CAN 发送/状态灯周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_CAN_TX_TICKS 1000U
|
||||
/** @brief 调度基准节拍:心跳/诊断打印周期,单位 100us tick。 */
|
||||
#define CONFIG_TASK_PERIOD_HEARTBEAT_TICKS 10000U
|
||||
|
||||
#endif /* SYS_CONFIG_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file initial.cpp
|
||||
* @brief 应用启动初始化实现。
|
||||
*/
|
||||
|
||||
#include "sys/initial.h"
|
||||
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "device/usart0.h"
|
||||
#include "device/Timer.h"
|
||||
#include "device/adc.h"
|
||||
#include "sys/systick.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
void AppInitializer::init()
|
||||
{
|
||||
SysTickTimer::initMs();
|
||||
Usart0::configurePins();
|
||||
Usart0::init();
|
||||
TempSensor::init();
|
||||
while(!Adc::dmaReady()) { }
|
||||
CanFd::init();
|
||||
TaskManager::init();
|
||||
SchedulerTimer::init();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file initial.cpp
|
||||
* @brief 应用启动初始化实现。
|
||||
*/
|
||||
|
||||
#include "sys/initial.h"
|
||||
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "device/usart0.h"
|
||||
#include "device/Timer.h"
|
||||
#include "sys/systick.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
/**
|
||||
* @brief 执行应用启动所需的底层模块初始化。
|
||||
* @note 初始化顺序:系统时基 → 串口 → 温度采集 → CAN 通信 → 任务调度 → 定时器。
|
||||
*/
|
||||
void app_init(void)
|
||||
{
|
||||
systick_config_ms();
|
||||
usart0_gpio_config();
|
||||
usart0_config();
|
||||
temp_sensor_init();
|
||||
canfd_init();
|
||||
task_manager_init();
|
||||
user_timer_init();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file initial.cpp
|
||||
* @brief 应用启动初始化实现。
|
||||
*/
|
||||
|
||||
#include "sys/initial.h"
|
||||
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "device/usart0.h"
|
||||
#include "device/Timer.h"
|
||||
#include "sys/systick.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
/**
|
||||
* @brief 执行应用启动所需的底层模块初始化。
|
||||
* @note 初始化顺序:系统时基 → 串口 → 温度采集 → CAN 通信 → 任务调度 → 定时器。
|
||||
*/
|
||||
void app_init(void)
|
||||
{
|
||||
systick_config_ms();
|
||||
usart0_gpio_config();
|
||||
usart0_config();
|
||||
temp_sensor_init();
|
||||
canfd_init();
|
||||
task_manager_init();
|
||||
user_timer_init();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @file initial.cpp
|
||||
* @brief 应用启动初始化实现。
|
||||
*/
|
||||
|
||||
#include "sys/initial.h"
|
||||
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "device/usart0.h"
|
||||
#include "device/Timer.h"
|
||||
#include "device/adc.h"
|
||||
#include "sys/systick.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
/**
|
||||
* @brief 执行应用启动所需的底层模块初始化。
|
||||
* @note 初始化顺序:系统时基 → 串口 → 温度采集 → CAN 通信 → 任务调度 → 定时器。
|
||||
*/
|
||||
void app_init(void)
|
||||
{
|
||||
systick_config_ms();
|
||||
usart0_gpio_config();
|
||||
usart0_config();
|
||||
temp_sensor_init();
|
||||
while(adc_dma_ready() == 0U) {
|
||||
}
|
||||
canfd_init();
|
||||
task_manager_init();
|
||||
user_timer_init();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file initial.cpp
|
||||
* @brief 应用启动初始化实现。
|
||||
*/
|
||||
|
||||
#include "initial.h"
|
||||
|
||||
#include "../device/canfd.h"
|
||||
#include "../device/temp_sensor.h"
|
||||
#include "../device/usart0.h"
|
||||
#include "../device/Timer.h"
|
||||
#include "systick.h"
|
||||
#include "task_manager.h"
|
||||
|
||||
/**
|
||||
* @brief 执行应用启动所需的底层模块初始化。
|
||||
* @note 初始化顺序:系统时基 → 串口 → 温度采集 → CAN 通信 → 任务调度 → 定时器。
|
||||
*/
|
||||
void app_init(void)
|
||||
{
|
||||
systick_config_ms();
|
||||
usart0_gpio_config();
|
||||
usart0_config();
|
||||
temp_sensor_init();
|
||||
canfd_init();
|
||||
task_manager_init();
|
||||
user_timer_init();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef SYS_INITIAL_H
|
||||
#define SYS_INITIAL_H
|
||||
|
||||
/**
|
||||
* @brief 应用初始化器。
|
||||
* @note 负责组织系统时基、串口、采样、通信、调度器等模块的启动顺序。
|
||||
*/
|
||||
class AppInitializer {
|
||||
public:
|
||||
static void init();
|
||||
};
|
||||
|
||||
#endif /* SYS_INITIAL_H */
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @file initial.h
|
||||
* @brief 应用初始化入口接口定义。
|
||||
*/
|
||||
#ifndef SYS_INITIAL_H
|
||||
#define SYS_INITIAL_H
|
||||
|
||||
/**
|
||||
* @brief 执行应用启动所需的底层模块初始化。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
* @note 按既定顺序初始化系统时基、串口、采样、通信与任务调度相关模块。
|
||||
*/
|
||||
void app_init(void);
|
||||
|
||||
#endif /* SYS_INITIAL_H */
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file systick.cpp
|
||||
* @brief SysTick 时基模块实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/systick.h"
|
||||
|
||||
volatile uint32_t SysTickTimer::s_ms = 0U;
|
||||
|
||||
void SysTickTimer::onInterrupt()
|
||||
{
|
||||
s_ms++;
|
||||
}
|
||||
|
||||
void SysTickTimer::delayMs(uint32_t ms)
|
||||
{
|
||||
uint32_t start = s_ms;
|
||||
while((s_ms - start) < ms) { }
|
||||
}
|
||||
|
||||
void SysTickTimer::initMs()
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
SysTick_Config(SystemCoreClock / 1000U);
|
||||
}
|
||||
|
||||
/* ----- 中断入口 C 包装 ---------------------------------------------- */
|
||||
void SysTick_Handler(void) { SysTickTimer::onInterrupt(); }
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file systick.cpp
|
||||
* @brief SysTick 时基配置、中断处理与毫秒延时实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/systick.h"
|
||||
|
||||
/** @brief 自启动后累计的系统节拍毫秒数。 */
|
||||
static volatile uint32_t systick_ms = 0U;
|
||||
|
||||
/**
|
||||
* @brief SysTick 中断服务例程,每毫秒递增一次节拍计数器。
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
systick_ms++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行阻塞式毫秒延时。
|
||||
* @param[in] ms 需要延时的毫秒数。
|
||||
*/
|
||||
void delay_ms(uint32_t ms)
|
||||
{
|
||||
uint32_t start = systick_ms;
|
||||
while((systick_ms - start) < ms) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 配置 SysTick 为 1ms 系统节拍。
|
||||
*/
|
||||
void systick_config_ms(void)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
SysTick_Config(SystemCoreClock / 1000U);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file systick.cpp
|
||||
* @brief SysTick 时基配置、中断处理与毫秒延时实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/systick.h"
|
||||
|
||||
/** @brief 自启动后累计的系统节拍毫秒数。 */
|
||||
static volatile uint32_t systick_ms = 0U;
|
||||
|
||||
/**
|
||||
* @brief SysTick 中断服务例程,每毫秒递增一次节拍计数器。
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
systick_ms++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行阻塞式毫秒延时。
|
||||
* @param[in] ms 需要延时的毫秒数。
|
||||
*/
|
||||
void delay_ms(uint32_t ms)
|
||||
{
|
||||
uint32_t start = systick_ms;
|
||||
while((systick_ms - start) < ms) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 配置 SysTick 为 1ms 系统节拍。
|
||||
*/
|
||||
void systick_config_ms(void)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
SysTick_Config(SystemCoreClock / 1000U);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file systick.cpp
|
||||
* @brief SysTick 时基配置、中断处理与毫秒延时实现。
|
||||
*/
|
||||
|
||||
#include "../main.h"
|
||||
#include "systick.h"
|
||||
|
||||
/** @brief 自启动后累计的系统节拍毫秒数。 */
|
||||
static volatile uint32_t systick_ms = 0U;
|
||||
|
||||
/**
|
||||
* @brief SysTick 中断服务例程,每毫秒递增一次节拍计数器。
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
systick_ms++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行阻塞式毫秒延时。
|
||||
* @param[in] ms 需要延时的毫秒数。
|
||||
*/
|
||||
void delay_ms(uint32_t ms)
|
||||
{
|
||||
uint32_t start = systick_ms;
|
||||
while((systick_ms - start) < ms) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 配置 SysTick 为 1ms 系统节拍。
|
||||
*/
|
||||
void systick_config_ms(void)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
SysTick_Config(SystemCoreClock / 1000U);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef SYS_SYSTICK_H
|
||||
#define SYS_SYSTICK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief SysTick 时基模块。
|
||||
* @note 负责 1ms 系统节拍维护与阻塞式毫秒延时。
|
||||
*/
|
||||
class SysTickTimer {
|
||||
public:
|
||||
static void initMs();
|
||||
static void delayMs(uint32_t ms);
|
||||
static void onInterrupt();
|
||||
|
||||
private:
|
||||
static volatile uint32_t s_ms;
|
||||
};
|
||||
|
||||
#endif /* SYS_SYSTICK_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file systick.h
|
||||
* @brief SysTick 时基配置与毫秒延时接口定义。
|
||||
*/
|
||||
#ifndef SYS_SYSTICK_H
|
||||
#define SYS_SYSTICK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief 配置 SysTick 为 1ms 系统节拍。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
*/
|
||||
void systick_config_ms(void);
|
||||
|
||||
/**
|
||||
* @brief 执行阻塞式毫秒延时。
|
||||
* @param[in] ms 需要延时的毫秒数。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
*/
|
||||
void delay_ms(uint32_t ms);
|
||||
|
||||
#endif /* SYS_SYSTICK_H */
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "main.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
task_scheduler_t g_scheduler = {0};
|
||||
|
||||
void task_manager_init(void)
|
||||
{
|
||||
g_scheduler.task_flags = 0U;
|
||||
g_scheduler.tick_100us = 0U;
|
||||
g_scheduler.tick_1ms = 0U;
|
||||
g_scheduler.tick_10ms = 0U;
|
||||
g_scheduler.tick_100ms = 0U;
|
||||
g_scheduler.tick_1s = 0U;
|
||||
}
|
||||
|
||||
void task_manager_set(uint32_t task_mask)
|
||||
{
|
||||
g_scheduler.task_flags |= task_mask;
|
||||
}
|
||||
|
||||
uint32_t task_manager_take_pending(void)
|
||||
{
|
||||
uint32_t pending;
|
||||
|
||||
__disable_irq();
|
||||
pending = g_scheduler.task_flags;
|
||||
g_scheduler.task_flags &= ~pending;
|
||||
__enable_irq();
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
void task_manager_tick_100us(void)
|
||||
{
|
||||
g_scheduler.tick_100us++;
|
||||
|
||||
if((g_scheduler.tick_100us % 5U) == 0U) {
|
||||
task_manager_set(1UL << TASK_ADC_VREF_SAMPLE);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10U) == 0U) {
|
||||
g_scheduler.tick_1ms++;
|
||||
task_manager_set((1UL << TASK_ADC_TEMP_SAMPLE) |
|
||||
(1UL << TASK_ADC_PROCESS));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 100U) == 0U) {
|
||||
g_scheduler.tick_10ms++;
|
||||
task_manager_set(1UL << TASK_CAN_POLL);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 1000U) == 0U) {
|
||||
g_scheduler.tick_100ms++;
|
||||
task_manager_set((1UL << TASK_CAN_REPORT) |
|
||||
(1UL << TASK_STATUS_LED));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10000U) == 0U) {
|
||||
g_scheduler.tick_1s++;
|
||||
task_manager_set((1UL << TASK_HEARTBEAT) |
|
||||
(1UL << TASK_DIAGNOSTIC_PRINT));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @file task_manager.cpp
|
||||
* @brief 任务调度管理器实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/task_manager.h"
|
||||
#include "sys/config.h"
|
||||
|
||||
task_scheduler_t g_scheduler = {0};
|
||||
|
||||
void TaskManager::init()
|
||||
{
|
||||
g_scheduler.task_flags = 0U;
|
||||
g_scheduler.tick_100us = 0U;
|
||||
g_scheduler.tick_1ms = 0U;
|
||||
g_scheduler.tick_10ms = 0U;
|
||||
g_scheduler.tick_100ms = 0U;
|
||||
g_scheduler.tick_1s = 0U;
|
||||
}
|
||||
|
||||
void TaskManager::set(uint32_t taskMask)
|
||||
{
|
||||
g_scheduler.task_flags |= taskMask;
|
||||
}
|
||||
|
||||
uint32_t TaskManager::takePending()
|
||||
{
|
||||
uint32_t pending;
|
||||
__disable_irq();
|
||||
pending = g_scheduler.task_flags;
|
||||
g_scheduler.task_flags &= ~pending;
|
||||
__enable_irq();
|
||||
return pending;
|
||||
}
|
||||
|
||||
void TaskManager::tick100us()
|
||||
{
|
||||
g_scheduler.tick_100us++;
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS) == 0U) {
|
||||
set(1UL << TASK_ADC_VREF_SAMPLE);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS) == 0U) {
|
||||
g_scheduler.tick_1ms++;
|
||||
set((1UL << TASK_ADC_TEMP_SAMPLE) | (1UL << TASK_ADC_PROCESS));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_CAN_RX_TICKS) == 0U) {
|
||||
g_scheduler.tick_10ms++;
|
||||
set((1UL << TASK_CAN_RX_POLL) | (1UL << TASK_CAN_RX_PARSE));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_CAN_TX_TICKS) == 0U) {
|
||||
g_scheduler.tick_100ms++;
|
||||
set((1UL << TASK_CAN_TX_PREPARE) | (1UL << TASK_CAN_TX_SEND) | (1UL << TASK_STATUS_LED));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_HEARTBEAT_TICKS) == 0U) {
|
||||
g_scheduler.tick_1s++;
|
||||
set((1UL << TASK_HEARTBEAT) | (1UL << TASK_DIAGNOSTIC_PRINT));
|
||||
}
|
||||
}
|
||||
|
||||
task_scheduler_t &TaskManager::state()
|
||||
{
|
||||
return g_scheduler;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file task_manager.cpp
|
||||
* @brief 任务标志调度与时基驱动实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
task_scheduler_t g_scheduler = {0};
|
||||
|
||||
/**
|
||||
* @brief 初始化任务管理器内部状态。
|
||||
*/
|
||||
void task_manager_init(void)
|
||||
{
|
||||
g_scheduler.task_flags = 0U;
|
||||
g_scheduler.tick_100us = 0U;
|
||||
g_scheduler.tick_1ms = 0U;
|
||||
g_scheduler.tick_10ms = 0U;
|
||||
g_scheduler.tick_100ms = 0U;
|
||||
g_scheduler.tick_1s = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置一个或多个待执行任务标志。
|
||||
* @param[in] task_mask 待置位的任务位图掩码。
|
||||
*/
|
||||
void task_manager_set(uint32_t task_mask)
|
||||
{
|
||||
g_scheduler.task_flags |= task_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 原子地取出当前所有待执行任务标志并清零。
|
||||
* @retval 返回当前待执行任务位图。
|
||||
*/
|
||||
uint32_t task_manager_take_pending(void)
|
||||
{
|
||||
uint32_t pending;
|
||||
|
||||
__disable_irq();
|
||||
pending = g_scheduler.task_flags;
|
||||
g_scheduler.task_flags &= ~pending;
|
||||
__enable_irq();
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 推进一次 100us 调度节拍并按周期置位待执行任务。
|
||||
* @note 按 500us / 1ms / 10ms / 100ms / 1s 档次分别置位对应任务组。
|
||||
*/
|
||||
void task_manager_tick_100us(void)
|
||||
{
|
||||
g_scheduler.tick_100us++;
|
||||
|
||||
if((g_scheduler.tick_100us % 5U) == 0U) {
|
||||
task_manager_set(1UL << TASK_ADC_VREF_SAMPLE);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10U) == 0U) {
|
||||
g_scheduler.tick_1ms++;
|
||||
task_manager_set((1UL << TASK_ADC_TEMP_SAMPLE) |
|
||||
(1UL << TASK_ADC_PROCESS));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 100U) == 0U) {
|
||||
g_scheduler.tick_10ms++;
|
||||
task_manager_set((1UL << TASK_CAN_RX_POLL) |
|
||||
(1UL << TASK_CAN_RX_PARSE));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 1000U) == 0U) {
|
||||
g_scheduler.tick_100ms++;
|
||||
task_manager_set((1UL << TASK_CAN_TX_PREPARE) |
|
||||
(1UL << TASK_CAN_TX_SEND) |
|
||||
(1UL << TASK_STATUS_LED));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10000U) == 0U) {
|
||||
g_scheduler.tick_1s++;
|
||||
task_manager_set((1UL << TASK_HEARTBEAT) |
|
||||
(1UL << TASK_DIAGNOSTIC_PRINT));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file task_manager.cpp
|
||||
* @brief 任务标志调度与时基驱动实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/task_manager.h"
|
||||
|
||||
task_scheduler_t g_scheduler = {0};
|
||||
|
||||
/**
|
||||
* @brief 初始化任务管理器内部状态。
|
||||
*/
|
||||
void task_manager_init(void)
|
||||
{
|
||||
g_scheduler.task_flags = 0U;
|
||||
g_scheduler.tick_100us = 0U;
|
||||
g_scheduler.tick_1ms = 0U;
|
||||
g_scheduler.tick_10ms = 0U;
|
||||
g_scheduler.tick_100ms = 0U;
|
||||
g_scheduler.tick_1s = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置一个或多个待执行任务标志。
|
||||
* @param[in] task_mask 待置位的任务位图掩码。
|
||||
*/
|
||||
void task_manager_set(uint32_t task_mask)
|
||||
{
|
||||
g_scheduler.task_flags |= task_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 原子地取出当前所有待执行任务标志并清零。
|
||||
* @retval 返回当前待执行任务位图。
|
||||
*/
|
||||
uint32_t task_manager_take_pending(void)
|
||||
{
|
||||
uint32_t pending;
|
||||
|
||||
__disable_irq();
|
||||
pending = g_scheduler.task_flags;
|
||||
g_scheduler.task_flags &= ~pending;
|
||||
__enable_irq();
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 推进一次 100us 调度节拍并按周期置位待执行任务。
|
||||
* @note 按 500us / 1ms / 10ms / 100ms / 1s 档次分别置位对应任务组。
|
||||
*/
|
||||
void task_manager_tick_100us(void)
|
||||
{
|
||||
g_scheduler.tick_100us++;
|
||||
|
||||
if((g_scheduler.tick_100us % 5U) == 0U) {
|
||||
task_manager_set(1UL << TASK_ADC_VREF_SAMPLE);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10U) == 0U) {
|
||||
g_scheduler.tick_1ms++;
|
||||
task_manager_set((1UL << TASK_ADC_TEMP_SAMPLE) |
|
||||
(1UL << TASK_ADC_PROCESS));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 100U) == 0U) {
|
||||
g_scheduler.tick_10ms++;
|
||||
task_manager_set((1UL << TASK_CAN_RX_POLL) |
|
||||
(1UL << TASK_CAN_RX_PARSE));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 1000U) == 0U) {
|
||||
g_scheduler.tick_100ms++;
|
||||
task_manager_set((1UL << TASK_CAN_TX_PREPARE) |
|
||||
(1UL << TASK_CAN_TX_SEND) |
|
||||
(1UL << TASK_STATUS_LED));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10000U) == 0U) {
|
||||
g_scheduler.tick_1s++;
|
||||
task_manager_set((1UL << TASK_HEARTBEAT) |
|
||||
(1UL << TASK_DIAGNOSTIC_PRINT));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file task_manager.cpp
|
||||
* @brief 任务标志调度与时基驱动实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "sys/task_manager.h"
|
||||
#include "sys/config.h"
|
||||
|
||||
task_scheduler_t g_scheduler = {0};
|
||||
|
||||
/**
|
||||
* @brief 初始化任务管理器内部状态。
|
||||
*/
|
||||
void task_manager_init(void)
|
||||
{
|
||||
g_scheduler.task_flags = 0U;
|
||||
g_scheduler.tick_100us = 0U;
|
||||
g_scheduler.tick_1ms = 0U;
|
||||
g_scheduler.tick_10ms = 0U;
|
||||
g_scheduler.tick_100ms = 0U;
|
||||
g_scheduler.tick_1s = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置一个或多个待执行任务标志。
|
||||
* @param[in] task_mask 待置位的任务位图掩码。
|
||||
*/
|
||||
void task_manager_set(uint32_t task_mask)
|
||||
{
|
||||
g_scheduler.task_flags |= task_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 原子地取出当前所有待执行任务标志并清零。
|
||||
* @retval 返回当前待执行任务位图。
|
||||
*/
|
||||
uint32_t task_manager_take_pending(void)
|
||||
{
|
||||
uint32_t pending;
|
||||
|
||||
__disable_irq();
|
||||
pending = g_scheduler.task_flags;
|
||||
g_scheduler.task_flags &= ~pending;
|
||||
__enable_irq();
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 推进一次 100us 调度节拍并按周期置位待执行任务。
|
||||
* @note 按 500us / 1ms / 10ms / 100ms / 1s 档次分别置位对应任务组。
|
||||
*/
|
||||
void task_manager_tick_100us(void)
|
||||
{
|
||||
g_scheduler.tick_100us++;
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS) == 0U) {
|
||||
task_manager_set(1UL << TASK_ADC_VREF_SAMPLE);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS) == 0U) {
|
||||
g_scheduler.tick_1ms++;
|
||||
task_manager_set((1UL << TASK_ADC_TEMP_SAMPLE) |
|
||||
(1UL << TASK_ADC_PROCESS));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_CAN_RX_TICKS) == 0U) {
|
||||
g_scheduler.tick_10ms++;
|
||||
task_manager_set((1UL << TASK_CAN_RX_POLL) |
|
||||
(1UL << TASK_CAN_RX_PARSE));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_CAN_TX_TICKS) == 0U) {
|
||||
g_scheduler.tick_100ms++;
|
||||
task_manager_set((1UL << TASK_CAN_TX_PREPARE) |
|
||||
(1UL << TASK_CAN_TX_SEND) |
|
||||
(1UL << TASK_STATUS_LED));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % CONFIG_TASK_PERIOD_HEARTBEAT_TICKS) == 0U) {
|
||||
g_scheduler.tick_1s++;
|
||||
task_manager_set((1UL << TASK_HEARTBEAT) |
|
||||
(1UL << TASK_DIAGNOSTIC_PRINT));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file task_manager.cpp
|
||||
* @brief 任务标志调度与时基驱动实现。
|
||||
*/
|
||||
|
||||
#include "../main.h"
|
||||
#include "task_manager.h"
|
||||
|
||||
task_scheduler_t g_scheduler = {0};
|
||||
|
||||
/**
|
||||
* @brief 初始化任务管理器内部状态。
|
||||
*/
|
||||
void task_manager_init(void)
|
||||
{
|
||||
g_scheduler.task_flags = 0U;
|
||||
g_scheduler.tick_100us = 0U;
|
||||
g_scheduler.tick_1ms = 0U;
|
||||
g_scheduler.tick_10ms = 0U;
|
||||
g_scheduler.tick_100ms = 0U;
|
||||
g_scheduler.tick_1s = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置一个或多个待执行任务标志。
|
||||
* @param[in] task_mask 待置位的任务位图掩码。
|
||||
*/
|
||||
void task_manager_set(uint32_t task_mask)
|
||||
{
|
||||
g_scheduler.task_flags |= task_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 原子地取出当前所有待执行任务标志并清零。
|
||||
* @retval 返回当前待执行任务位图。
|
||||
*/
|
||||
uint32_t task_manager_take_pending(void)
|
||||
{
|
||||
uint32_t pending;
|
||||
|
||||
__disable_irq();
|
||||
pending = g_scheduler.task_flags;
|
||||
g_scheduler.task_flags &= ~pending;
|
||||
__enable_irq();
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 推进一次 100us 调度节拍并按周期置位待执行任务。
|
||||
* @note 按 500us / 1ms / 10ms / 100ms / 1s 档次分别置位对应任务组。
|
||||
*/
|
||||
void task_manager_tick_100us(void)
|
||||
{
|
||||
g_scheduler.tick_100us++;
|
||||
|
||||
if((g_scheduler.tick_100us % 5U) == 0U) {
|
||||
task_manager_set(1UL << TASK_ADC_VREF_SAMPLE);
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10U) == 0U) {
|
||||
g_scheduler.tick_1ms++;
|
||||
task_manager_set((1UL << TASK_ADC_TEMP_SAMPLE) |
|
||||
(1UL << TASK_ADC_PROCESS));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 100U) == 0U) {
|
||||
g_scheduler.tick_10ms++;
|
||||
task_manager_set((1UL << TASK_CAN_RX_POLL) |
|
||||
(1UL << TASK_CAN_RX_PARSE));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 1000U) == 0U) {
|
||||
g_scheduler.tick_100ms++;
|
||||
task_manager_set((1UL << TASK_CAN_TX_PREPARE) |
|
||||
(1UL << TASK_CAN_TX_SEND) |
|
||||
(1UL << TASK_STATUS_LED));
|
||||
}
|
||||
|
||||
if((g_scheduler.tick_100us % 10000U) == 0U) {
|
||||
g_scheduler.tick_1s++;
|
||||
task_manager_set((1UL << TASK_HEARTBEAT) |
|
||||
(1UL << TASK_DIAGNOSTIC_PRINT));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef SYS_TASK_MANAGER_H
|
||||
#define SYS_TASK_MANAGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "main.h"
|
||||
|
||||
/**
|
||||
* @brief 任务调度管理器。
|
||||
* @note 负责维护节拍计数器与待执行任务位图。
|
||||
*/
|
||||
class TaskManager {
|
||||
public:
|
||||
static void init();
|
||||
static void tick100us();
|
||||
static uint32_t takePending();
|
||||
static void set(uint32_t taskMask);
|
||||
static task_scheduler_t &state();
|
||||
};
|
||||
|
||||
#endif /* SYS_TASK_MANAGER_H */
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef SYS_TASK_MANAGER_H
|
||||
#define SYS_TASK_MANAGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void task_manager_init(void);
|
||||
void task_manager_tick_100us(void);
|
||||
uint32_t task_manager_take_pending(void);
|
||||
void task_manager_set(uint32_t task_mask);
|
||||
|
||||
#endif /* SYS_TASK_MANAGER_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file task_manager.h
|
||||
* @brief 任务标志调度与时基驱动接口定义。
|
||||
*/
|
||||
#ifndef SYS_TASK_MANAGER_H
|
||||
#define SYS_TASK_MANAGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief 初始化任务管理器内部状态。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
*/
|
||||
void task_manager_init(void);
|
||||
|
||||
/**
|
||||
* @brief 推进一次 100us 调度节拍并按周期置位待执行任务。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
*/
|
||||
void task_manager_tick_100us(void);
|
||||
|
||||
/**
|
||||
* @brief 原子地取出当前所有待执行任务标志。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval uint32_t 返回当前待执行任务位图,并在内部清除对应标志。
|
||||
*/
|
||||
uint32_t task_manager_take_pending(void);
|
||||
|
||||
/**
|
||||
* @brief 设置一个或多个待执行任务标志。
|
||||
* @param[in] task_mask 待置位的任务位图掩码。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
*/
|
||||
void task_manager_set(uint32_t task_mask);
|
||||
|
||||
#endif /* SYS_TASK_MANAGER_H */
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file task_runner.cpp
|
||||
* @brief 任务执行器实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "device/adc.h"
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "sys/task_manager.h"
|
||||
#include "sys/task_runner.h"
|
||||
|
||||
struct TaskRunner::Runtime {
|
||||
temp_sensor_data_t sample{};
|
||||
uint16_t last_vin_raw;
|
||||
uint16_t last_vref_raw;
|
||||
uint16_t last_temp_raw;
|
||||
uint32_t last_rx_id;
|
||||
uint8_t last_rx_len;
|
||||
uint8_t last_rx_data[64];
|
||||
};
|
||||
|
||||
TaskRunner::Runtime TaskRunner::s_runtime;
|
||||
|
||||
void TaskRunner::taskAdcVrefSample()
|
||||
{
|
||||
s_runtime.last_vin_raw = Adc::readVinRaw();
|
||||
s_runtime.last_vref_raw = Adc::readVrefRaw();
|
||||
}
|
||||
|
||||
void TaskRunner::taskAdcTempSample()
|
||||
{
|
||||
s_runtime.last_temp_raw = Adc::readTempRaw();
|
||||
}
|
||||
|
||||
void TaskRunner::taskAdcProcess()
|
||||
{
|
||||
auto &s = s_runtime.sample;
|
||||
s.vin_raw = s_runtime.last_vin_raw;
|
||||
s.vref_raw = s_runtime.last_vref_raw;
|
||||
s.temp_raw = s_runtime.last_temp_raw;
|
||||
s.vdda = Adc::calculateVdda(s.vref_raw);
|
||||
s.vin_adc_v = Adc::calculateVinAdcVoltage(s.vin_raw, s.vdda);
|
||||
s.temperature = Adc::calculateTemperature(s.temp_raw, s.vdda);
|
||||
}
|
||||
|
||||
void TaskRunner::taskCanRxPoll() { CanFd::poll(); }
|
||||
void TaskRunner::taskCanTxSend() { CanFd::sendPrepared(); }
|
||||
|
||||
void TaskRunner::taskCanRxParse()
|
||||
{
|
||||
if(CanFd::hasRxFrame())
|
||||
CanFd::consumeRxFrame(&s_runtime.last_rx_id, s_runtime.last_rx_data, &s_runtime.last_rx_len);
|
||||
}
|
||||
|
||||
void TaskRunner::taskCanTxPrepare()
|
||||
{
|
||||
CanFd::StatusPayload status;
|
||||
status.temp_raw = s_runtime.sample.temp_raw;
|
||||
status.vref_raw = s_runtime.sample.vref_raw;
|
||||
status.vdda = s_runtime.sample.vdda;
|
||||
status.temperature = s_runtime.sample.temperature;
|
||||
CanFd::prepareStatus(&status);
|
||||
}
|
||||
|
||||
void TaskRunner::taskStatusLed() { /* 预留 */ }
|
||||
void TaskRunner::taskHeartbeat() { /* 预留 */ }
|
||||
|
||||
void TaskRunner::taskDiagnosticPrint()
|
||||
{
|
||||
const auto *diag = CanFd::diag();
|
||||
const auto &s = s_runtime.sample;
|
||||
|
||||
printf("vin_raw=%u, vin_adc=%.3f V, temp_raw=%u, vref_raw=%u, vdda=%.3f V, temp=%.2f C, rx_id=0x%08lX, rx_len=%u, can_tx=%lu, can_rx=%lu, can_err=%lu\r\n",
|
||||
s.vin_raw, s.vin_adc_v, s.temp_raw, s.vref_raw, s.vdda, s.temperature,
|
||||
static_cast<unsigned long>(s_runtime.last_rx_id),
|
||||
static_cast<unsigned int>(s_runtime.last_rx_len),
|
||||
static_cast<unsigned long>(diag->tx_count),
|
||||
static_cast<unsigned long>(diag->rx_count),
|
||||
static_cast<unsigned long>(diag->error_count));
|
||||
}
|
||||
|
||||
void TaskRunner::init()
|
||||
{
|
||||
Adc::collectSample(&s_runtime.sample);
|
||||
s_runtime.last_vin_raw = s_runtime.sample.vin_raw;
|
||||
s_runtime.last_vref_raw = s_runtime.sample.vref_raw;
|
||||
s_runtime.last_temp_raw = s_runtime.sample.temp_raw;
|
||||
}
|
||||
|
||||
void TaskRunner::runPending()
|
||||
{
|
||||
const uint32_t pending = TaskManager::takePending();
|
||||
if(pending == 0U) return;
|
||||
|
||||
if(pending & (1UL << TASK_ADC_VREF_SAMPLE)) taskAdcVrefSample();
|
||||
if(pending & (1UL << TASK_ADC_TEMP_SAMPLE)) taskAdcTempSample();
|
||||
if(pending & (1UL << TASK_ADC_PROCESS)) taskAdcProcess();
|
||||
if(pending & (1UL << TASK_CAN_RX_POLL)) taskCanRxPoll();
|
||||
if(pending & (1UL << TASK_CAN_RX_PARSE)) taskCanRxParse();
|
||||
if(pending & (1UL << TASK_CAN_TX_PREPARE)) taskCanTxPrepare();
|
||||
if(pending & (1UL << TASK_CAN_TX_SEND)) taskCanTxSend();
|
||||
if(pending & (1UL << TASK_STATUS_LED)) taskStatusLed();
|
||||
if(pending & (1UL << TASK_HEARTBEAT)) taskHeartbeat();
|
||||
if(pending & (1UL << TASK_DIAGNOSTIC_PRINT)) taskDiagnosticPrint();
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @file task_runner.cpp
|
||||
* @brief 任务执行器初始化与待执行任务分发实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "device/adc.h"
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "sys/task_manager.h"
|
||||
#include "sys/task_runner.h"
|
||||
|
||||
namespace {
|
||||
/** @brief 应用运行时上下文,保存各任务间共享的最新数据。 */
|
||||
struct AppRuntime {
|
||||
temp_sensor_data_t sample{};
|
||||
uint16_t last_vref_raw = 0U;
|
||||
uint16_t last_temp_raw = 0U;
|
||||
uint32_t last_rx_id = 0U;
|
||||
uint8_t last_rx_len = 0U;
|
||||
uint8_t last_rx_data[64] = {0};
|
||||
};
|
||||
|
||||
AppRuntime g_app{};
|
||||
|
||||
/**
|
||||
* @brief 采样内部参考电压原始值。
|
||||
*/
|
||||
inline void task_adc_vref_sample()
|
||||
{
|
||||
g_app.last_vref_raw = adc_read_vref_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 采样内部温度通道原始值。
|
||||
*/
|
||||
inline void task_adc_temp_sample()
|
||||
{
|
||||
g_app.last_temp_raw = adc_read_temp_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据采样原始值换算 VDDA 与芯片温度。
|
||||
*/
|
||||
inline void task_adc_process()
|
||||
{
|
||||
g_app.sample.vref_raw = g_app.last_vref_raw;
|
||||
g_app.sample.temp_raw = g_app.last_temp_raw;
|
||||
g_app.sample.vdda = adc_calculate_vdda(g_app.sample.vref_raw);
|
||||
g_app.sample.temperature = adc_calculate_temperature(g_app.sample.temp_raw, g_app.sample.vdda);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 轮询 CANFD 接收 FIFO。
|
||||
*/
|
||||
inline void task_can_rx_poll()
|
||||
{
|
||||
canfd_poll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析并消费已接收的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_rx_parse()
|
||||
{
|
||||
if(canfd_has_rx_frame() != 0U) {
|
||||
canfd_consume_rx_frame(&g_app.last_rx_id, g_app.last_rx_data, &g_app.last_rx_len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 准备 CANFD 状态发送帧。
|
||||
*/
|
||||
inline void task_can_tx_prepare()
|
||||
{
|
||||
const canfd_status_payload_t status {
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
};
|
||||
canfd_prepare_status(&status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送已准备好的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_tx_send()
|
||||
{
|
||||
canfd_send_prepared();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 状态灯维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_status_led()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 系统心跳维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_heartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 诊断信息打印任务,输出当前所有运行时数据。
|
||||
*/
|
||||
inline void task_diagnostic_print()
|
||||
{
|
||||
const canfd_diag_t *diag = canfd_get_diag();
|
||||
|
||||
printf("temp_raw=%u, vref_raw=%u, vdda=%.3f V, temp=%.2f C, rx_id=0x%08lX, rx_len=%u, can_tx=%lu, can_rx=%lu, can_err=%lu\r\n",
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
static_cast<unsigned long>(g_app.last_rx_id),
|
||||
static_cast<unsigned int>(g_app.last_rx_len),
|
||||
static_cast<unsigned long>(diag->tx_count),
|
||||
static_cast<unsigned long>(diag->rx_count),
|
||||
static_cast<unsigned long>(diag->error_count));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @brief 初始化任务执行器运行时上下文。
|
||||
* @note 执行一次初始采样,填充运行时数据起点。
|
||||
*/
|
||||
void task_runner_init(void)
|
||||
{
|
||||
adc_collect_sample(&g_app.sample);
|
||||
g_app.last_vref_raw = g_app.sample.vref_raw;
|
||||
g_app.last_temp_raw = g_app.sample.temp_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行当前所有已置位的待处理任务。
|
||||
* @note 若当前没有待执行任务,直接返回。
|
||||
*/
|
||||
void task_runner_run_pending(void)
|
||||
{
|
||||
const uint32_t pending = task_manager_take_pending();
|
||||
if(pending == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((pending & (1UL << TASK_ADC_VREF_SAMPLE)) != 0U) {
|
||||
task_adc_vref_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_TEMP_SAMPLE)) != 0U) {
|
||||
task_adc_temp_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_PROCESS)) != 0U) {
|
||||
task_adc_process();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_POLL)) != 0U) {
|
||||
task_can_rx_poll();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_PARSE)) != 0U) {
|
||||
task_can_rx_parse();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_PREPARE)) != 0U) {
|
||||
task_can_tx_prepare();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_SEND)) != 0U) {
|
||||
task_can_tx_send();
|
||||
}
|
||||
if((pending & (1UL << TASK_STATUS_LED)) != 0U) {
|
||||
task_status_led();
|
||||
}
|
||||
if((pending & (1UL << TASK_HEARTBEAT)) != 0U) {
|
||||
task_heartbeat();
|
||||
}
|
||||
if((pending & (1UL << TASK_DIAGNOSTIC_PRINT)) != 0U) {
|
||||
task_diagnostic_print();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* @file task_runner.cpp
|
||||
* @brief 任务执行器初始化与待执行任务分发实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "device/adc.h"
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "sys/task_manager.h"
|
||||
#include "sys/task_runner.h"
|
||||
|
||||
namespace {
|
||||
/** @brief 应用运行时上下文,保存各任务间共享的最新数据。 */
|
||||
struct AppRuntime {
|
||||
temp_sensor_data_t sample{};
|
||||
uint16_t last_vin_raw = 0U;
|
||||
uint16_t last_vref_raw = 0U;
|
||||
uint16_t last_temp_raw = 0U;
|
||||
uint32_t last_rx_id = 0U;
|
||||
uint8_t last_rx_len = 0U;
|
||||
uint8_t last_rx_data[64] = {0};
|
||||
};
|
||||
|
||||
AppRuntime g_app{};
|
||||
|
||||
/**
|
||||
* @brief 采样内部参考电压原始值。
|
||||
*/
|
||||
inline void task_adc_vref_sample()
|
||||
{
|
||||
g_app.last_vin_raw = adc_read_vin_raw();
|
||||
g_app.last_vref_raw = adc_read_vref_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 采样内部温度通道原始值。
|
||||
*/
|
||||
inline void task_adc_temp_sample()
|
||||
{
|
||||
g_app.last_temp_raw = adc_read_temp_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据采样原始值换算 VDDA 与芯片温度。
|
||||
*/
|
||||
inline void task_adc_process()
|
||||
{
|
||||
g_app.sample.vin_raw = g_app.last_vin_raw;
|
||||
g_app.sample.vref_raw = g_app.last_vref_raw;
|
||||
g_app.sample.temp_raw = g_app.last_temp_raw;
|
||||
g_app.sample.vdda = adc_calculate_vdda(g_app.sample.vref_raw);
|
||||
g_app.sample.vin_adc_v = adc_calculate_vin_adc_voltage(g_app.sample.vin_raw, g_app.sample.vdda);
|
||||
g_app.sample.temperature = adc_calculate_temperature(g_app.sample.temp_raw, g_app.sample.vdda);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 轮询 CANFD 接收 FIFO。
|
||||
*/
|
||||
inline void task_can_rx_poll()
|
||||
{
|
||||
canfd_poll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析并消费已接收的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_rx_parse()
|
||||
{
|
||||
if(canfd_has_rx_frame() != 0U) {
|
||||
canfd_consume_rx_frame(&g_app.last_rx_id, g_app.last_rx_data, &g_app.last_rx_len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 准备 CANFD 状态发送帧。
|
||||
*/
|
||||
inline void task_can_tx_prepare()
|
||||
{
|
||||
const canfd_status_payload_t status {
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
};
|
||||
canfd_prepare_status(&status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送已准备好的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_tx_send()
|
||||
{
|
||||
canfd_send_prepared();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 状态灯维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_status_led()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 系统心跳维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_heartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 诊断信息打印任务,输出当前所有运行时数据。
|
||||
*/
|
||||
inline void task_diagnostic_print()
|
||||
{
|
||||
const canfd_diag_t *diag = canfd_get_diag();
|
||||
|
||||
printf("vin_raw=%u, vin_adc=%.3f V, temp_raw=%u, vref_raw=%u, vdda=%.3f V, temp=%.2f C, rx_id=0x%08lX, rx_len=%u, can_tx=%lu, can_rx=%lu, can_err=%lu\r\n",
|
||||
g_app.sample.vin_raw,
|
||||
g_app.sample.vin_adc_v,
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
static_cast<unsigned long>(g_app.last_rx_id),
|
||||
static_cast<unsigned int>(g_app.last_rx_len),
|
||||
static_cast<unsigned long>(diag->tx_count),
|
||||
static_cast<unsigned long>(diag->rx_count),
|
||||
static_cast<unsigned long>(diag->error_count));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @brief 初始化任务执行器运行时上下文。
|
||||
* @note 执行一次初始采样,填充运行时数据起点。
|
||||
*/
|
||||
void task_runner_init(void)
|
||||
{
|
||||
adc_collect_sample(&g_app.sample);
|
||||
g_app.last_vin_raw = g_app.sample.vin_raw;
|
||||
g_app.last_vref_raw = g_app.sample.vref_raw;
|
||||
g_app.last_temp_raw = g_app.sample.temp_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行当前所有已置位的待处理任务。
|
||||
* @note 若当前没有待执行任务,直接返回。
|
||||
*/
|
||||
void task_runner_run_pending(void)
|
||||
{
|
||||
const uint32_t pending = task_manager_take_pending();
|
||||
if(pending == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((pending & (1UL << TASK_ADC_VREF_SAMPLE)) != 0U) {
|
||||
task_adc_vref_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_TEMP_SAMPLE)) != 0U) {
|
||||
task_adc_temp_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_PROCESS)) != 0U) {
|
||||
task_adc_process();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_POLL)) != 0U) {
|
||||
task_can_rx_poll();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_PARSE)) != 0U) {
|
||||
task_can_rx_parse();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_PREPARE)) != 0U) {
|
||||
task_can_tx_prepare();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_SEND)) != 0U) {
|
||||
task_can_tx_send();
|
||||
}
|
||||
if((pending & (1UL << TASK_STATUS_LED)) != 0U) {
|
||||
task_status_led();
|
||||
}
|
||||
if((pending & (1UL << TASK_HEARTBEAT)) != 0U) {
|
||||
task_heartbeat();
|
||||
}
|
||||
if((pending & (1UL << TASK_DIAGNOSTIC_PRINT)) != 0U) {
|
||||
task_diagnostic_print();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @file task_runner.cpp
|
||||
* @brief 任务执行器初始化与待执行任务分发实现。
|
||||
*/
|
||||
|
||||
#include "../main.h"
|
||||
#include "../device/adc.h"
|
||||
#include "../device/canfd.h"
|
||||
#include "../device/temp_sensor.h"
|
||||
#include "task_manager.h"
|
||||
#include "task_runner.h"
|
||||
|
||||
namespace {
|
||||
/** @brief 应用运行时上下文,保存各任务间共享的最新数据。 */
|
||||
struct AppRuntime {
|
||||
temp_sensor_data_t sample{};
|
||||
uint16_t last_vref_raw = 0U;
|
||||
uint16_t last_temp_raw = 0U;
|
||||
uint32_t last_rx_id = 0U;
|
||||
uint8_t last_rx_len = 0U;
|
||||
uint8_t last_rx_data[64] = {0};
|
||||
};
|
||||
|
||||
AppRuntime g_app{};
|
||||
|
||||
/**
|
||||
* @brief 采样内部参考电压原始值。
|
||||
*/
|
||||
inline void task_adc_vref_sample()
|
||||
{
|
||||
g_app.last_vref_raw = adc_read_vref_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 采样内部温度通道原始值。
|
||||
*/
|
||||
inline void task_adc_temp_sample()
|
||||
{
|
||||
g_app.last_temp_raw = adc_read_temp_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据采样原始值换算 VDDA 与芯片温度。
|
||||
*/
|
||||
inline void task_adc_process()
|
||||
{
|
||||
g_app.sample.vref_raw = g_app.last_vref_raw;
|
||||
g_app.sample.temp_raw = g_app.last_temp_raw;
|
||||
g_app.sample.vdda = adc_calculate_vdda(g_app.sample.vref_raw);
|
||||
g_app.sample.temperature = adc_calculate_temperature(g_app.sample.temp_raw, g_app.sample.vdda);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 轮询 CANFD 接收 FIFO。
|
||||
*/
|
||||
inline void task_can_rx_poll()
|
||||
{
|
||||
canfd_poll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析并消费已接收的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_rx_parse()
|
||||
{
|
||||
if(canfd_has_rx_frame() != 0U) {
|
||||
canfd_consume_rx_frame(&g_app.last_rx_id, g_app.last_rx_data, &g_app.last_rx_len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 准备 CANFD 状态发送帧。
|
||||
*/
|
||||
inline void task_can_tx_prepare()
|
||||
{
|
||||
const canfd_status_payload_t status {
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
};
|
||||
canfd_prepare_status(&status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送已准备好的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_tx_send()
|
||||
{
|
||||
canfd_send_prepared();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 状态灯维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_status_led()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 系统心跳维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_heartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 诊断信息打印任务,输出当前所有运行时数据。
|
||||
*/
|
||||
inline void task_diagnostic_print()
|
||||
{
|
||||
const canfd_diag_t *diag = canfd_get_diag();
|
||||
|
||||
printf("temp_raw=%u, vref_raw=%u, vdda=%.3f V, temp=%.2f C, rx_id=0x%08lX, rx_len=%u, can_tx=%lu, can_rx=%lu, can_err=%lu\r\n",
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
static_cast<unsigned long>(g_app.last_rx_id),
|
||||
static_cast<unsigned int>(g_app.last_rx_len),
|
||||
static_cast<unsigned long>(diag->tx_count),
|
||||
static_cast<unsigned long>(diag->rx_count),
|
||||
static_cast<unsigned long>(diag->error_count));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @brief 初始化任务执行器运行时上下文。
|
||||
* @note 执行一次初始采样,填充运行时数据起点。
|
||||
*/
|
||||
void task_runner_init(void)
|
||||
{
|
||||
adc_collect_sample(&g_app.sample);
|
||||
g_app.last_vref_raw = g_app.sample.vref_raw;
|
||||
g_app.last_temp_raw = g_app.sample.temp_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行当前所有已置位的待处理任务。
|
||||
* @note 若当前没有待执行任务,直接返回。
|
||||
*/
|
||||
void task_runner_run_pending(void)
|
||||
{
|
||||
const uint32_t pending = task_manager_take_pending();
|
||||
if(pending == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((pending & (1UL << TASK_ADC_VREF_SAMPLE)) != 0U) {
|
||||
task_adc_vref_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_TEMP_SAMPLE)) != 0U) {
|
||||
task_adc_temp_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_PROCESS)) != 0U) {
|
||||
task_adc_process();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_POLL)) != 0U) {
|
||||
task_can_rx_poll();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_PARSE)) != 0U) {
|
||||
task_can_rx_parse();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_PREPARE)) != 0U) {
|
||||
task_can_tx_prepare();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_SEND)) != 0U) {
|
||||
task_can_tx_send();
|
||||
}
|
||||
if((pending & (1UL << TASK_STATUS_LED)) != 0U) {
|
||||
task_status_led();
|
||||
}
|
||||
if((pending & (1UL << TASK_HEARTBEAT)) != 0U) {
|
||||
task_heartbeat();
|
||||
}
|
||||
if((pending & (1UL << TASK_DIAGNOSTIC_PRINT)) != 0U) {
|
||||
task_diagnostic_print();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @file task_runner.cpp
|
||||
* @brief 任务执行器初始化与待执行任务分发实现。
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "device/adc.h"
|
||||
#include "device/canfd.h"
|
||||
#include "device/temp_sensor.h"
|
||||
#include "sys/task_manager.h"
|
||||
#include "sys/task_runner.h"
|
||||
|
||||
namespace {
|
||||
/** @brief 应用运行时上下文,保存各任务间共享的最新数据。 */
|
||||
struct AppRuntime {
|
||||
temp_sensor_data_t sample{};
|
||||
uint16_t last_vref_raw = 0U;
|
||||
uint16_t last_temp_raw = 0U;
|
||||
uint32_t last_rx_id = 0U;
|
||||
uint8_t last_rx_len = 0U;
|
||||
uint8_t last_rx_data[64] = {0};
|
||||
};
|
||||
|
||||
AppRuntime g_app{};
|
||||
|
||||
/**
|
||||
* @brief 采样内部参考电压原始值。
|
||||
*/
|
||||
inline void task_adc_vref_sample()
|
||||
{
|
||||
g_app.last_vref_raw = adc_read_vref_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 采样内部温度通道原始值。
|
||||
*/
|
||||
inline void task_adc_temp_sample()
|
||||
{
|
||||
g_app.last_temp_raw = adc_read_temp_raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据采样原始值换算 VDDA 与芯片温度。
|
||||
*/
|
||||
inline void task_adc_process()
|
||||
{
|
||||
g_app.sample.vref_raw = g_app.last_vref_raw;
|
||||
g_app.sample.temp_raw = g_app.last_temp_raw;
|
||||
g_app.sample.vdda = adc_calculate_vdda(g_app.sample.vref_raw);
|
||||
g_app.sample.temperature = adc_calculate_temperature(g_app.sample.temp_raw, g_app.sample.vdda);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 轮询 CANFD 接收 FIFO。
|
||||
*/
|
||||
inline void task_can_rx_poll()
|
||||
{
|
||||
canfd_poll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析并消费已接收的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_rx_parse()
|
||||
{
|
||||
if(canfd_has_rx_frame() != 0U) {
|
||||
canfd_consume_rx_frame(&g_app.last_rx_id, g_app.last_rx_data, &g_app.last_rx_len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 准备 CANFD 状态发送帧。
|
||||
*/
|
||||
inline void task_can_tx_prepare()
|
||||
{
|
||||
const canfd_status_payload_t status {
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
};
|
||||
canfd_prepare_status(&status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送已准备好的 CANFD 帧。
|
||||
*/
|
||||
inline void task_can_tx_send()
|
||||
{
|
||||
canfd_send_prepared();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 状态灯维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_status_led()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 系统心跳维护任务(当前为预留占位)。
|
||||
*/
|
||||
inline void task_heartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 诊断信息打印任务,输出当前所有运行时数据。
|
||||
*/
|
||||
inline void task_diagnostic_print()
|
||||
{
|
||||
const canfd_diag_t *diag = canfd_get_diag();
|
||||
|
||||
printf("temp_raw=%u, vref_raw=%u, vdda=%.3f V, temp=%.2f C, rx_id=0x%08lX, rx_len=%u, can_tx=%lu, can_rx=%lu, can_err=%lu\r\n",
|
||||
g_app.sample.temp_raw,
|
||||
g_app.sample.vref_raw,
|
||||
g_app.sample.vdda,
|
||||
g_app.sample.temperature,
|
||||
static_cast<unsigned long>(g_app.last_rx_id),
|
||||
static_cast<unsigned int>(g_app.last_rx_len),
|
||||
static_cast<unsigned long>(diag->tx_count),
|
||||
static_cast<unsigned long>(diag->rx_count),
|
||||
static_cast<unsigned long>(diag->error_count));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @brief 初始化任务执行器运行时上下文。
|
||||
* @note 执行一次初始采样,填充运行时数据起点。
|
||||
*/
|
||||
void task_runner_init(void)
|
||||
{
|
||||
adc_collect_sample(&g_app.sample);
|
||||
g_app.last_vref_raw = g_app.sample.vref_raw;
|
||||
g_app.last_temp_raw = g_app.sample.temp_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行当前所有已置位的待处理任务。
|
||||
* @note 若当前没有待执行任务,直接返回。
|
||||
*/
|
||||
void task_runner_run_pending(void)
|
||||
{
|
||||
const uint32_t pending = task_manager_take_pending();
|
||||
if(pending == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((pending & (1UL << TASK_ADC_VREF_SAMPLE)) != 0U) {
|
||||
task_adc_vref_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_TEMP_SAMPLE)) != 0U) {
|
||||
task_adc_temp_sample();
|
||||
}
|
||||
if((pending & (1UL << TASK_ADC_PROCESS)) != 0U) {
|
||||
task_adc_process();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_POLL)) != 0U) {
|
||||
task_can_rx_poll();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_RX_PARSE)) != 0U) {
|
||||
task_can_rx_parse();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_PREPARE)) != 0U) {
|
||||
task_can_tx_prepare();
|
||||
}
|
||||
if((pending & (1UL << TASK_CAN_TX_SEND)) != 0U) {
|
||||
task_can_tx_send();
|
||||
}
|
||||
if((pending & (1UL << TASK_STATUS_LED)) != 0U) {
|
||||
task_status_led();
|
||||
}
|
||||
if((pending & (1UL << TASK_HEARTBEAT)) != 0U) {
|
||||
task_heartbeat();
|
||||
}
|
||||
if((pending & (1UL << TASK_DIAGNOSTIC_PRINT)) != 0U) {
|
||||
task_diagnostic_print();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef SYS_TASK_RUNNER_H
|
||||
#define SYS_TASK_RUNNER_H
|
||||
|
||||
/**
|
||||
* @brief 任务执行器。
|
||||
* @note 负责消费 TaskManager 置位的任务,并驱动各模块完成实际工作。
|
||||
*/
|
||||
class TaskRunner {
|
||||
public:
|
||||
static void init();
|
||||
static void runPending();
|
||||
|
||||
private:
|
||||
struct Runtime;
|
||||
static Runtime s_runtime;
|
||||
|
||||
static void taskAdcVrefSample();
|
||||
static void taskAdcTempSample();
|
||||
static void taskAdcProcess();
|
||||
static void taskCanRxPoll();
|
||||
static void taskCanRxParse();
|
||||
static void taskCanTxPrepare();
|
||||
static void taskCanTxSend();
|
||||
static void taskStatusLed();
|
||||
static void taskHeartbeat();
|
||||
static void taskDiagnosticPrint();
|
||||
};
|
||||
|
||||
#endif /* SYS_TASK_RUNNER_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @file task_runner.h
|
||||
* @brief 任务执行器初始化与待执行任务分发接口定义。
|
||||
*/
|
||||
#ifndef SYS_TASK_RUNNER_H
|
||||
#define SYS_TASK_RUNNER_H
|
||||
|
||||
/**
|
||||
* @brief 初始化任务执行器运行时上下文。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
*/
|
||||
void task_runner_init(void);
|
||||
|
||||
/**
|
||||
* @brief 执行当前所有已置位的待处理任务。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
* @note 若当前没有待执行任务,函数直接返回。
|
||||
*/
|
||||
void task_runner_run_pending(void);
|
||||
|
||||
#endif /* SYS_TASK_RUNNER_H */
|
||||
Reference in New Issue
Block a user