添加了AES128加密算法实现和电机OTA中继相关文件,包括: - ./sys/aes128.h 和 ./sys/aes128.cpp - AES128加密算法头文件和实现 - ./sys/motor_ota_relay.h 和 ./sys/motor_ota_relay.cpp - 电机OTA中继功能 - 更新了项目配置文件包含这些新模块
106 lines
2.8 KiB
C++
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
|