Files
ESP32_COMM/main/transport/canfd_bridge.cpp
T
小龙虾 6ef97307c3 feat(http): 添加CPU使用率监控功能
添加了详细的CPU使用率统计功能,包括:
- 实现FreeRTOS运行时统计采样机制
- 添加CPU任务占用率计算和快照功能
- 在/system/status接口中增加CPU状态JSON数据
- 支持实时监控各任务的运行时间和占用百分比

更新了前端界面以显示CPU使用情况:
- 添加CPU使用率进度条和百分比显示
- 显示空闲时间、采样窗口和任务数量
- 展示前8个最耗时任务的详细统计信息

同时优化了CAN FD桥接实现,重构为SPI协议帧传输方式,
并改进了前端CAN页面布局,将CAN表单迁移到独立页面。
2026-06-25 01:42:31 +08:00

83 lines
2.5 KiB
C++

/*
* canfd_bridge.cpp - CANFD 3通道通信桥接实现(M4: 从 SpiMaster 提取)
*/
#include <string.h>
#include "canfd_bridge.h"
#include "spi_master.h"
namespace {
constexpr uint8_t kSpiCanFrameType = 0xC0U;
static int sendCanFrameOverSpi(can_channel_t channel, uint32_t ext_id,
const uint8_t *data, uint8_t dlc,
uint8_t *recv_buf, uint8_t recv_max,
uint32_t timeout_ms)
{
uint8_t tx_buf[72];
size_t tx_len = 0;
tx_buf[tx_len++] = static_cast<uint8_t>(channel & CAN_CHANNEL_MASK);
tx_buf[tx_len++] = static_cast<uint8_t>((ext_id >> 24) & 0xFFU);
tx_buf[tx_len++] = static_cast<uint8_t>((ext_id >> 16) & 0xFFU);
tx_buf[tx_len++] = static_cast<uint8_t>((ext_id >> 8) & 0xFFU);
tx_buf[tx_len++] = static_cast<uint8_t>(ext_id & 0xFFU);
if (dlc > 0U) {
memcpy(&tx_buf[tx_len], data, dlc);
tx_len += dlc;
}
uint8_t resp_type = 0U;
size_t resp_len = 0U;
esp_err_t ret = SpiMaster::instance().otaTransfer(
kSpiCanFrameType,
tx_buf,
tx_len,
&resp_type,
recv_buf,
recv_max,
&resp_len,
timeout_ms);
if (ret != ESP_OK || resp_type != SPI_OTA_RSP_ACK) {
return -1;
}
if (recv_buf == nullptr || recv_max == 0U) {
return static_cast<int>(resp_len);
}
const size_t copied_len = (resp_len < recv_max) ? resp_len : recv_max;
return static_cast<int>(copied_len);
}
} // namespace
/**
* @brief 发送一帧 CANFD 数据,可选等待并读取响应。
* 通过 SPI 协议帧发送给 GD32 APP,并读取 ACK/ERROR 响应。
*/
int canFdSend(can_channel_t channel, uint32_t ext_id,
const uint8_t *data, uint8_t dlc,
uint8_t *recv_buf, uint8_t recv_max,
uint32_t timeout_ms)
{
if (channel >= CAN_CHANNEL_MAX || dlc > CAN_MAX_DLC || !data) {
return -1;
}
return sendCanFrameOverSpi(channel, ext_id, data, dlc, recv_buf, recv_max, timeout_ms);
}
/**
* @brief 发送一帧无需上层消费响应的 CANFD 数据。
* GD32 APP 仍会返回 ACK/ERROR,这里主动读走响应,避免残留到下一笔 SPI 事务。
*/
int canFdSendNoReply(can_channel_t channel, uint32_t ext_id,
const uint8_t *data, uint8_t dlc)
{
if (channel >= CAN_CHANNEL_MAX || dlc > CAN_MAX_DLC || !data) {
return -1;
}
return (sendCanFrameOverSpi(channel, ext_id, data, dlc, nullptr, 0U, 1000U) >= 0) ? 0 : -1;
}