feat(build): 优化构建配置并引入日志分级系统
- 将优化级别从balanced调整为size,减少Flash占用 - 添加hardfault.cpp文件以增强故障诊断能力 - 关闭RTTI和异常处理以移除libcppabi运行时(节省约2.5KB Flash) - 添加链接器参数输出未引用段与总量报告用于Flash尺寸分析 refactor(logging): 统一日志输出并实现编译时日志分级 - 将printf调用替换为模块化的日志宏(ECAT_LOGI、CAN_LOGI等) - 实现CONFIG_*_LOG_ENABLE编译开关控制各模块INFO级日志 - 错误和关键事件使用LOG_ERR恒定保留,其他日志可编译时裁剪 - 保持原有日志内容不变,但支持链接器自动回收未使用的格式字符串
This commit is contained in:
@@ -195,7 +195,7 @@ static void keyedCrc32(const uint8_t *key, const uint8_t *data, uint8_t *output)
|
||||
static bool canSend(uint32_t id, const uint8_t *data, uint8_t dlc, bool periodic = false) {
|
||||
/* 诊断:kTransfer 期间只应发 0x101,若出现 0x100 则为幽灵帧 */
|
||||
if (s_state == State::kTransfer && id == kOtaReqId) {
|
||||
printf("[MOTOR-OTA] BUG! canSend(0x100) in kTransfer! dlc=%u\r\n", (unsigned)dlc);
|
||||
LOG_ERR("[MOTOR-OTA] BUG! canSend(0x100) in kTransfer! dlc=%u\r\n", (unsigned)dlc);
|
||||
}
|
||||
const CanFd::CanTxResult r = CanFd::transmitFrame(s_channel, id, data, dlc, periodic);
|
||||
return (r == CanFd::CanTxResult::kOk);
|
||||
@@ -321,7 +321,7 @@ static void sendNonce() {
|
||||
|
||||
/* 统一重发当前步骤的帧(超时重发 + kHandshakeReq 首发) */
|
||||
static void sendCurrentStep(uint32_t now_ms) {
|
||||
printf("[MOTOR-OTA] TX %s try=%u t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] TX %s try=%u t=%lu\r\n",
|
||||
stepName(s_state), (unsigned)s_retry_count, (unsigned long)now_ms);
|
||||
switch (s_state) {
|
||||
case State::kHandshakeReq: {
|
||||
@@ -413,14 +413,14 @@ static void sendCurrentPacket() {
|
||||
/* 末包 padding 日志在 TX 前打印(sendNextPacket 设 s_last_pad_valid)。
|
||||
* 用最短格式 + 一次性打印(打印后置 0xFFFF 防重发重复打印)。 */
|
||||
if (s_last_pad_valid != 0xFFFFU) {
|
||||
printf("[MOTOR-OTA] PAD v=%u p=%u\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] PAD v=%u p=%u\r\n",
|
||||
(unsigned)s_last_pad_valid,
|
||||
(unsigned)(kPacketPayload - s_last_pad_valid));
|
||||
s_last_pad_valid = 0xFFFFU;
|
||||
}
|
||||
/* 逐包 TX 日志在 5ms 节奏下会拖主循环;仅末包/每 64 包打一行。 */
|
||||
if (is_last || ((pkt_num & 0x3FU) == 0U)) {
|
||||
printf("[MOTOR-OTA] TX pkt=%lu/%u%s t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] TX pkt=%lu/%u%s t=%lu\r\n",
|
||||
(unsigned long)pkt_num, (unsigned)s_total_packets,
|
||||
is_last ? " LAST" : "", (unsigned long)SysTickTimer::getMs());
|
||||
}
|
||||
@@ -445,7 +445,7 @@ static void sendNextPacket() {
|
||||
static uint32_t s_last_tail_ms = 0;
|
||||
const uint32_t now = SysTickTimer::getMs();
|
||||
if (now - s_last_tail_ms >= 200U) {
|
||||
printf("[MOTOR-OTA] 末包欠载,等尾字节 pkt=%u used=%u need=%u fed=%lu t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] tail-wait pkt=%u used=%u need=%u fed=%lu t=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)used,
|
||||
(unsigned)last_valid, (unsigned long)s_fw_fed,
|
||||
(unsigned long)now);
|
||||
@@ -466,7 +466,7 @@ static void sendNextPacket() {
|
||||
static uint32_t s_last_empty_ms = 0;
|
||||
const uint32_t now = SysTickTimer::getMs();
|
||||
if (now - s_last_empty_ms >= 200U) {
|
||||
printf("[MOTOR-OTA] 缓冲空,等ESP32喂 pkt=%u used=%u fed=%lu/%lu t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] buf-empty wait-feed pkt=%u used=%u fed=%lu/%lu t=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)used,
|
||||
(unsigned long)s_fw_fed, (unsigned long)s_fw_size,
|
||||
(unsigned long)now);
|
||||
@@ -533,7 +533,7 @@ static void processTransferAck(const uint8_t *data, uint8_t len) {
|
||||
s_crc_resend_pending = true;
|
||||
return;
|
||||
}
|
||||
printf("[MOTOR-OTA] CRC 重试耗尽 pkt=%u/%u dup=%lu crc=%lu\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] CRC retry exhausted pkt=%u/%u dup=%lu crc=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)s_total_packets,
|
||||
(unsigned long)s_dup_ack_count, (unsigned long)s_crc_err_count);
|
||||
setError(0x23); /* CRC 重试耗尽 */
|
||||
@@ -543,7 +543,7 @@ static void processTransferAck(const uint8_t *data, uint8_t len) {
|
||||
/* INVALID_HANDSHAKE(0x05):电机 BOOT 已退回 IDLE。按用户要求不再做
|
||||
* 「发 CANCEL + 从包 0 重握手」的自动重试(会白扔进度、坏总线下反复失败),
|
||||
* 直接中止,由上位机决定是否整体重刷。 */
|
||||
printf("[MOTOR-OTA] HANDSHAKE 错误(0x05),中止(不重握手) pkt=%u/%u\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] HANDSHAKE err(0x05) abort pkt=%u/%u\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)s_total_packets);
|
||||
setError(0x05);
|
||||
return;
|
||||
@@ -579,7 +579,7 @@ if (next_pkt == 0xFFFFFFFFU) {
|
||||
s_packets_acked = s_total_packets;
|
||||
s_last_acked_pkt = s_total_packets;
|
||||
s_pkt_pending = false;
|
||||
printf("[MOTOR-OTA] FINISHED pkt=%u/%u dup=%lu crc=%lu resend=%lu fast=%lu t=%lu\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] FINISHED pkt=%u/%u dup=%lu crc=%lu resend=%lu fast=%lu t=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)s_total_packets,
|
||||
(unsigned long)s_dup_ack_count, (unsigned long)s_crc_err_count,
|
||||
(unsigned long)s_ack_resend_total, (unsigned long)s_fast_resend_total,
|
||||
@@ -624,7 +624,7 @@ if (next_pkt == 0xFFFFFFFFU) {
|
||||
* 与 0xD1 喂数抢总线,加重缓冲欠载(CANlog 可见周期性 ~500ms 空洞)。
|
||||
* 进度由 ESP32 feedTask 按已喂字节估算;终态再 push。 */
|
||||
if ((s_packets_acked & 0x1F) == 0) {
|
||||
printf("[MOTOR-OTA] 进度 pkt=%u/%u dup=%lu crc=%lu resend=%lu fast=%lu t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] progress pkt=%u/%u dup=%lu crc=%lu resend=%lu fast=%lu t=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)s_total_packets,
|
||||
(unsigned long)s_dup_ack_count, (unsigned long)s_crc_err_count,
|
||||
(unsigned long)s_ack_resend_total, (unsigned long)s_fast_resend_total,
|
||||
@@ -662,7 +662,7 @@ void onTxTick() {
|
||||
s_retry_count++;
|
||||
s_fast_resend_total++;
|
||||
const uint32_t err = CanFd::readChannelErrorReg(s_channel);
|
||||
printf("[MOTOR-OTA] TX错快重发 pkt=%u retry=%u tec=%lu rec=%lu errn=%lu\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] TX-err fast-resend pkt=%u retry=%u tec=%lu rec=%lu errn=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)s_retry_count,
|
||||
(unsigned long)((err >> 16) & 0xFFU),
|
||||
(unsigned long)((err >> 24) & 0xFFU),
|
||||
@@ -678,7 +678,7 @@ void onTxTick() {
|
||||
/* 事件时刻 CAN_ERR 快照:钉死丢帧时总线状态(TEC 涨=数据帧发丢,
|
||||
* REC 高=接收方向损坏),摆脱 1Hz [CAN-BUS] 采样混叠。仅日志,不做发送门控。 */
|
||||
const uint32_t err = CanFd::readChannelErrorReg(s_channel);
|
||||
printf("[MOTOR-OTA] ACK 超时重发 pkt=%u retry=%u tec=%lu rec=%lu errn=%lu\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] ACK timeout resend pkt=%u retry=%u tec=%lu rec=%lu errn=%lu\r\n",
|
||||
(unsigned)s_packets_acked, (unsigned)s_retry_count,
|
||||
(unsigned long)((err >> 16) & 0xFFU),
|
||||
(unsigned long)((err >> 24) & 0xFFU),
|
||||
@@ -723,7 +723,7 @@ if (s_pkt_pending) return; /* 当前包待确认,不发新包
|
||||
if (!is_last && !all_fed && used < water) {
|
||||
static uint32_t s_last_water_ms = 0;
|
||||
if (now - s_last_water_ms >= 200U) {
|
||||
printf("[MOTOR-OTA] 等SPI水位 used=%u need=%u fed=%lu pkt=%u\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] wait-SPI-level used=%u need=%u fed=%lu pkt=%u\r\n",
|
||||
(unsigned)used, (unsigned)water,
|
||||
(unsigned long)s_fw_fed, (unsigned)s_packets_acked);
|
||||
s_last_water_ms = now;
|
||||
@@ -749,12 +749,12 @@ void process() {
|
||||
* 再开始握手就不会被干扰。 */
|
||||
if (s_state == State::kPreCancel) {
|
||||
if (s_boot_heartbeat_seen && stateTimedOut(kBootSettleMs)) {
|
||||
printf("[MOTOR-OTA] 0x103 心跳确认 + %ums 残帧窗口已过,开始握手\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] 0x103 ok, residue-win %ums passed, handshake\r\n",
|
||||
(unsigned)kBootSettleMs);
|
||||
enterState(State::kHandshakeReq);
|
||||
pushStatus();
|
||||
} else if (stateTimedOut(kHandshakeTimeoutMs)) {
|
||||
printf("[MOTOR-OTA] 等待 0x103 超时,电机未进入 BOOT\r\n");
|
||||
LOG_ERR("[MOTOR-OTA] wait 0x103 timeout, motor not in BOOT\r\n");
|
||||
setError(0x02); /* 0x02 = 电机未进入 BOOT */
|
||||
}
|
||||
return;
|
||||
@@ -785,7 +785,7 @@ void process() {
|
||||
if (rnow - s_last_rxerr_ms >= 200U) { rx_do_log = true; s_last_rxerr_ms = rnow; }
|
||||
}
|
||||
if (rx_do_log) {
|
||||
printf("[MOTOR-OTA] RX %s pkt=%u/%u len=%u b0=%02X b1=%02X t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] RX %s pkt=%u/%u len=%u b0=%02X b1=%02X t=%lu\r\n",
|
||||
stepName(s_state), (unsigned)s_packets_acked, (unsigned)s_total_packets,
|
||||
(unsigned)ack_len,
|
||||
(ack_len > 0) ? ack_data[0] : 0xFFU, (ack_len > 1) ? ack_data[1] : 0xFFU,
|
||||
@@ -800,7 +800,7 @@ void process() {
|
||||
enterState(State::kHandshakeNonce);
|
||||
canSend(kOtaReqId, s_nonce, 16);
|
||||
s_last_send_ms = SysTickTimer::getMs();
|
||||
printf("[MOTOR-OTA] TX HANDSHAKE_NONCE(0x100:16B) [ACK-driven] t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] TX HANDSHAKE_NONCE(0x100:16B) [ACK-driven] t=%lu\r\n",
|
||||
(unsigned long)s_last_send_ms);
|
||||
}
|
||||
/* 不匹配的 ACK 靠掉 —— 忽略,等超时重发 REQ */
|
||||
@@ -809,13 +809,13 @@ void process() {
|
||||
case State::kHandshakeNonce:
|
||||
if (ack_len < 36) {
|
||||
/* 短帧(0x05/干扰) —— 忽略,等真正 48B 或超时重发 */
|
||||
printf("[MOTOR-OTA] NONCE ACK 忽略短帧 len=%u b0=0x%02X\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] NONCE ACK ignore short frame len=%u b0=0x%02X\r\n",
|
||||
(unsigned)ack_len, (ack_len > 0) ? ack_data[0] : 0xFFU);
|
||||
break;
|
||||
}
|
||||
if (memcmp(ack_data + 12, s_nonce + 8, 8) != 0) {
|
||||
/* nonce echo 不匹配 —— 电机收到了错误的帧当 nonce */
|
||||
printf("[MOTOR-OTA] NONCE ACK echo mismatch, ignore\r\n");
|
||||
LOG_ERR("[MOTOR-OTA] NONCE ACK echo mismatch, ignore\r\n");
|
||||
break;
|
||||
}
|
||||
/* ✔ nonce 响应正确 —— 派生 K_session,立即发 confirm */
|
||||
@@ -834,7 +834,7 @@ void process() {
|
||||
aes128_encrypt_block(&s_aes_ctx, plain, confirm);
|
||||
canSend(kOtaReqId, confirm, 16);
|
||||
s_last_send_ms = SysTickTimer::getMs();
|
||||
printf("[MOTOR-OTA] TX HANDSHAKE_CONFIRM(0x100:16B) [ACK-driven] t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] TX HANDSHAKE_CONFIRM(0x100:16B) [ACK-driven] t=%lu\r\n",
|
||||
(unsigned long)s_last_send_ms);
|
||||
}
|
||||
break;
|
||||
@@ -850,7 +850,7 @@ void process() {
|
||||
size_le[3] = static_cast<uint8_t>((s_fw_size >> 24) & 0xFF);
|
||||
canSend(kOtaDataId, size_le, 4);
|
||||
s_last_send_ms = SysTickTimer::getMs();
|
||||
printf("[MOTOR-OTA] TX ERASE(0x101:fw_size) [ACK-driven] t=%lu\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] TX ERASE(0x101:fw_size) [ACK-driven] t=%lu\r\n",
|
||||
(unsigned long)s_last_send_ms);
|
||||
}
|
||||
/* 非 [BA C0] —— 忽略(可能是 0x03/0x05 干扰帧) */
|
||||
@@ -867,7 +867,7 @@ void process() {
|
||||
* 过时的 0x100 帧 → catch-all → [05] 杀死 OTA。强制 abort 降低风险。 */
|
||||
CanFd::abortPendingTx(s_channel);
|
||||
s_last_send_ms = SysTickTimer::getMs();
|
||||
printf("[MOTOR-OTA] ERASE ACK 收到,等 %ums 再发首包\r\n",
|
||||
OTA_LOGI("[MOTOR-OTA] ERASE ACK ok, wait %ums then first pkt\r\n",
|
||||
(unsigned)kEraseWaitMs);
|
||||
}
|
||||
/* 非 [BA C0 ...] —— 忽略,等超时重发 fw_size */
|
||||
@@ -906,7 +906,7 @@ void process() {
|
||||
} else if ((now_ms - s_last_send_ms) >= kStepTimeoutMs) {
|
||||
/* 超时重发 */
|
||||
if (s_retry_count >= kMaxResends) {
|
||||
printf("[MOTOR-OTA] %s 未收到应答(已发送 %u 次无响应),中止刷写\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] %s no-ACK after %u tries, abort\r\n",
|
||||
stepName(s_state), (unsigned)(kMaxResends + 1U));
|
||||
setError(static_cast<uint8_t>(0x30U + static_cast<uint8_t>(s_state)));
|
||||
pushStatus();
|
||||
@@ -989,7 +989,7 @@ s_channel = can_channel;
|
||||
|
||||
/* 不在 SPI 中断里同步发握手帧(电机跳 BOOT 期间 CAN 可能短暂断开)。
|
||||
* 先进 kPreCancel 等待电机 0x103 心跳确认已进 BOOT,再由 process() 异步推进到握手。 */
|
||||
printf("[MOTOR-OTA] START ch=%u fw=%lu total=%u\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] START ch=%u fw=%lu total=%u\r\n",
|
||||
(unsigned)can_channel, (unsigned long)fw_size, (unsigned)s_total_packets);
|
||||
s_boot_heartbeat_seen = false;
|
||||
enterState(State::kPreCancel);
|
||||
@@ -1040,7 +1040,7 @@ bool feedData(const uint8_t *data, uint16_t len) {
|
||||
static uint32_t s_last_gap_ms = 0;
|
||||
const uint32_t now = SysTickTimer::getMs();
|
||||
if (now - s_last_gap_ms >= 200U) {
|
||||
printf("[MOTOR-OTA] feed 缺口 off=%lu fed=%lu len=%u\r\n",
|
||||
LOG_ERR("[MOTOR-OTA] feed gap off=%lu fed=%lu len=%u\r\n",
|
||||
(unsigned long)offset, (unsigned long)s_fw_fed,
|
||||
(unsigned)chunk_len);
|
||||
s_last_gap_ms = now;
|
||||
@@ -1061,7 +1061,7 @@ bool feedData(const uint8_t *data, uint16_t len) {
|
||||
|
||||
void cancel() {
|
||||
if (s_state == State::kIdle) return;
|
||||
printf("[MOTOR-OTA] CANCEL received in state %s\r\n", stepName(s_state));
|
||||
LOG_ERR("[MOTOR-OTA] CANCEL received in state %s\r\n", stepName(s_state));
|
||||
/* ★ kFinished/kError 时电机已跳转 APP 或已中止,绝不能再发 CAN 取消帧!
|
||||
* kOtaCancelId=0x00000000 与电机 APP 的 CANFD_BOOT_ID(base_id=0x0000) 冲突,
|
||||
* 电机 APP 收到会当作 BOOT 命令 → enter_silent_mode 10s,APP 看似卡死。
|
||||
|
||||
Reference in New Issue
Block a user