Files
DCU_APP/GD32E508_DCU_APP/sys/task_runner.cpp.bak_fixinclude
T

179 lines
4.3 KiB
Plaintext
Raw Normal View History

/**
* @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();
}
}