Files
cbb 079c6442d4 feat(sys): 添加AES加密和电机OTA中继功能模块
添加了AES128加密算法实现和电机OTA中继相关文件,包括:
- ./sys/aes128.h 和 ./sys/aes128.cpp - AES128加密算法头文件和实现
- ./sys/motor_ota_relay.h 和 ./sys/motor_ota_relay.cpp - 电机OTA中继功能
- 更新了项目配置文件包含这些新模块
2026-07-26 20:39:59 +08:00

106 lines
2.8 KiB
C++

/**
* @file motor_version.cpp
* @brief 多电机版本缓存实现 — CAN 版本应答帧(0x00FF)识别、缓存、0xC6 序列化。
*
* 所有函数仅在主循环上下文调用(taskCanRxParse / pushStep),无 ISR 竞态。
* 与 motor_state.cpp 不同:版本是事件驱动(收到应答才缓存+推送),无周期任务、
* 无离线判定;pushStep 在 app_spi_cmd_motor_version.cpp(含 SPI 依赖)。
*/
#include "device/motor_version.h"
#include "device/spi/app_spi_command_defs.h"
#include <cstring>
/* ── 全局版本表实例 ── */
static MotorVersionTable s_verTable = {};
namespace MotorVersion {
MotorVersionTable &table()
{
return s_verTable;
}
void onCanFrame(uint8_t channel, uint32_t id, const uint8_t *data, uint8_t len)
{
(void)channel;
/* 掩码匹配版本应答 ID: 0x000N00FF */
if ((id & kMotorVersionIdMask) != kMotorVersionIdMatch) {
return;
}
const uint8_t node = static_cast<uint8_t>((id >> 16) & 0x0FU);
if (node < 1U || node > kMotorVersionMaxNodes) {
return;
}
if (data == nullptr || len < 1U) {
return;
}
MotorVersionSlot &slot = s_verTable.slots[node - 1U];
slot.node_id = node;
slot.seq = ++s_verTable.global_seq;
/* 拷贝原始 payload(不足补 0,超长截断) */
const uint8_t n = (len <= kMotorVersionDlc) ? len : kMotorVersionDlc;
std::memcpy(slot.version, data, n);
if (n < kMotorVersionDlc) {
std::memset(&slot.version[n], 0, kMotorVersionDlc - n);
}
slot.dirty = 1U; /* 标记待推送 */
}
bool hasPending()
{
for (uint8_t i = 0U; i < kMotorVersionMaxNodes; ++i) {
if (s_verTable.slots[i].dirty != 0U) {
return true;
}
}
return false;
}
uint16_t buildPayload(uint8_t *buf, uint16_t maxLen)
{
if (buf == nullptr || maxLen < kMotorVersionHeaderLen) {
return 0U;
}
/* Header (2B): count 稍后回填, rsvd=0 */
buf[0] = 0U;
buf[1] = 0U;
uint16_t offset = kMotorVersionHeaderLen;
uint8_t count = 0U;
for (uint8_t i = 0U; i < kMotorVersionMaxNodes; ++i) {
MotorVersionSlot &slot = s_verTable.slots[i];
if (slot.dirty == 0U) {
continue;
}
/* 检查剩余空间;装不下则保留 dirty 待下轮(不丢) */
if (offset + kMotorVersionEntrySize > maxLen) {
break;
}
buf[offset + 0U] = slot.node_id;
writeU32Le(&buf[offset + 1U], slot.seq);
std::memcpy(&buf[offset + 5U], slot.version, kMotorVersionDlc);
offset += kMotorVersionEntrySize;
count++;
slot.dirty = 0U; /* 已打包进本次推送 */
}
if (count == 0U) {
return 0U;
}
buf[0] = count;
return offset;
}
} // namespace MotorVersion