feat(motor_state): 支持多通道电机状态管理并添加推送周期动态调节功能

- 实现 node×channel 双键槽位管理,支持同一节点号在不同CAN通道独立缓存
- 扩展电机状态表容量从9个槽位到27个槽位(9节点×3通道)
- 添加SPI命令子命令0xFE用于动态设置0xC5推送周期(50-5000ms)
- 增加运行时可调推送周期功能,默认250ms,支持50ms-5s范围调节
- 更新CAN通道配置,启用CH1和CH2通道支持
- 版本号更新至1.5.4
This commit is contained in:
cbb
2026-07-30 02:11:49 +08:00
parent 46ef19d882
commit e06f5eb9a9
8 changed files with 107 additions and 34 deletions
+15 -4
View File
@@ -40,11 +40,12 @@ void onCanFrame(uint8_t channel, uint32_t id, const uint8_t *data, uint8_t len)
}
const uint8_t node = static_cast<uint8_t>((id >> 16) & 0x0FU);
if (node < 1U || node > kMotorMaxNodes) {
if (node < 1U || node > kMotorMaxNodes || channel >= kMotorChannels) {
return;
}
MotorSlot &slot = s_motorTable.slots[node - 1U];
/* node×channel 双键槽位:同节点号在不同通道各自独立缓存,互不覆盖 */
MotorSlot &slot = s_motorTable.slots[(node - 1U) * kMotorChannels + channel];
slot.node_id = node;
slot.channel = channel;
@@ -66,7 +67,7 @@ void checkOffline()
const uint32_t now = g_app_uptime_sec;
uint8_t active = 0U;
for (uint8_t i = 0U; i < kMotorMaxNodes; ++i) {
for (uint8_t i = 0U; i < kMotorSlotCount; ++i) {
MotorSlot &slot = s_motorTable.slots[i];
if (slot.node_id == 0U) {
continue; /* 空槽 */
@@ -115,7 +116,7 @@ uint16_t buildPayload(uint8_t page, uint8_t *buf, uint16_t maxLen)
for (uint8_t i = 0U; i < kMotorEntriesPerPage; ++i) {
const uint8_t slotIdx = static_cast<uint8_t>(startIdx + i);
if (slotIdx >= kMotorMaxNodes) {
if (slotIdx >= kMotorSlotCount) {
break;
}
@@ -145,4 +146,14 @@ uint16_t buildPayload(uint8_t page, uint8_t *buf, uint16_t maxLen)
return offset;
}
uint16_t setPushPeriodMs(uint16_t ms)
{
if (ms < kMotorPeriodMinMs) { ms = kMotorPeriodMinMs; }
if (ms > kMotorPeriodMaxMs) { ms = kMotorPeriodMaxMs; }
/* ms→tick:100us/tick,每 ms 10 tick。写 volatile uint16_t 在 Cortex-M 上为原子,
* tick100us(ISR) 读该值无擕裂风险。 */
g_scheduler.motor_state_period_ticks = static_cast<uint16_t>(ms * kMotorTicksPerMs);
return ms;
}
} // namespace MotorState