/** * @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(s_runtime.last_rx_id), static_cast(s_runtime.last_rx_len), static_cast(diag->tx_count), static_cast(diag->rx_count), static_cast(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(); }