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:
cbb
2026-07-27 01:49:18 +08:00
parent edebde4a02
commit 46ef19d882
9 changed files with 130 additions and 88 deletions
+32 -32
View File
@@ -209,7 +209,7 @@ void CanFd::initGpio()
gpio_afio_port_config(AFIO_PE1_CAN2_CFG, ENABLE);
#endif
printf("[CAN-GPIO] AFIO_PCF0=0x%08lX CAN0=PA11/PA12 CAN1=PB12/PB13\r\n",
CAN_LOGI("[CAN-GPIO] AFIO_PCF0=0x%08lX CAN0=PA11/PA12 CAN1=PB12/PB13\r\n",
static_cast<unsigned long>(AFIO_PCF0));
for(size_t i = 0; i < kChannelCount; ++i) {
@@ -322,7 +322,7 @@ bool CanFd::initFdMode(uint32_t canPeriph)
/** @brief 打印 SYS/APB1 时钟与目标波特率。 */
void CanFd::printClockInfo()
{
printf("[CAN-CLOCK] SYS=%luHz APB1=%luHz nominal=1Mbps data=2Mbps\r\n",
CAN_LOGI("[CAN-CLOCK] SYS=%luHz APB1=%luHz nominal=1Mbps data=2Mbps\r\n",
static_cast<unsigned long>(SystemCoreClock),
static_cast<unsigned long>(rcu_clock_freq_get(CK_APB1)));
}
@@ -360,7 +360,7 @@ void CanFd::initChannelHardware(uint8_t i)
if ((CAN_STAT(ch.canPeriph) & CAN_STAT_IWS) == 0U) break;
}
printf("[CAN-WARN] CH%u init failed (nom=%u fd=%u STAT=0x%08lX), retry %u/5\r\n",
LOG_ERR("[CAN-WARN] CH%u init failed (nom=%u fd=%u STAT=0x%08lX), retry %u/5\r\n",
static_cast<unsigned>(i),
nominalOk ? 1U : 0U, fdOk ? 1U : 0U,
static_cast<unsigned long>(CAN_STAT(ch.canPeriph)),
@@ -388,7 +388,7 @@ void CanFd::initChannelHardware(uint8_t i)
for (volatile uint32_t d = 0; d < 200000U; ++d) {
if ((CAN_STAT(ch.canPeriph) & CAN_STAT_IWS) == 0U) break;
}
printf("[CAN-WARN] CH%u needed extra SWRST to exit init mode (STAT=0x%08lX)\r\n",
LOG_ERR("[CAN-WARN] CH%u needed extra SWRST to exit init mode (STAT=0x%08lX)\r\n",
static_cast<unsigned>(i),
static_cast<unsigned long>(CAN_STAT(ch.canPeriph)));
}
@@ -398,7 +398,7 @@ void CanFd::initChannelHardware(uint8_t i)
const uint8_t rxLevelAfter = (gpio_input_bit_get(ch.rxPort, ch.rxPin) != RESET) ? 1U : 0U;
const uint32_t tecAfterExit = (errAfterExit >> 16) & 0xFFU;
const uint32_t recAfterExit = (errAfterExit >> 24) & 0xFFU;
printf("[CAN-DIAG] CH%u init_nom=%u init_fd=%u exit_ok=%u wait=%lu rx_before=%u rx_after=%u stb=%u STAT=0x%08lX ERR=0x%08lX TEC=%lu REC=%lu\r\n",
CAN_LOGI("[CAN-DIAG] CH%u init_nom=%u init_fd=%u exit_ok=%u wait=%lu rx_before=%u rx_after=%u stb=%u STAT=0x%08lX ERR=0x%08lX TEC=%lu REC=%lu\r\n",
static_cast<unsigned>(i),
nominalOk ? 1U : 0U,
fdOk ? 1U : 0U,
@@ -438,7 +438,7 @@ void CanFd::configureAllFilters()
if (!kChannelEnabled[i]) continue;
configureRxFilter(kChannels[i].canPeriph, kChannels[i].filterNumber, s_mode);
}
printf("[CAN] filters configured post-init: HBC1F=%lu FW=0x%08lX\r\n",
CAN_LOGI("[CAN] filters configured post-init: HBC1F=%lu FW=0x%08lX\r\n",
static_cast<unsigned long>((CAN_FCTL(CAN0) >> 8) & 0x3FU),
static_cast<unsigned long>(CAN_FW(CAN0)));
}
@@ -448,14 +448,14 @@ void CanFd::configureAllFilters()
void CanFd::printInitResult()
{
/* ===== 初始化结果汇总 ===== */
printf("=== CAN INIT RESULT ===\r\n");
CAN_LOGI("=== CAN INIT RESULT ===\r\n");
for (size_t i = 0; i < kChannelCount; ++i) {
const auto &ch = kChannels[i];
uint32_t stat = CAN_STAT(ch.canPeriph);
uint32_t bt = CAN_BT(ch.canPeriph);
uint32_t dbt = CAN_DBT(ch.canPeriph);
bool ok = (stat & CAN_STAT_IWS) == 0U;
printf("CH%u: %s BT=0x%08lX DBT=0x%08lX\r\n",
CAN_LOGI("CH%u: %s BT=0x%08lX DBT=0x%08lX\r\n",
static_cast<unsigned>(i),
ok ? "OK" : "FAIL(init_mode)",
static_cast<unsigned long>(bt),
@@ -466,7 +466,7 @@ void CanFd::printInitResult()
uint32_t fw = CAN_FW(CAN0);
uint32_t fw2 = CAN_FW(CAN2);
uint32_t hbc = (CAN_FCTL(CAN0) >> 8) & 0x3FU;
printf("FILTER: HBC1F=%lu CAN01_FW=0x%08lX(b0=%lu b2=%lu b14=%lu) CAN2_FW=0x%08lX(b2=%lu)\r\n",
CAN_LOGI("FILTER: HBC1F=%lu CAN01_FW=0x%08lX(b0=%lu b2=%lu b14=%lu) CAN2_FW=0x%08lX(b2=%lu)\r\n",
static_cast<unsigned long>(hbc),
static_cast<unsigned long>(fw),
static_cast<unsigned long>((fw >> 0) & 1U),
@@ -481,13 +481,13 @@ void CanFd::printInitResult()
void CanFd::printErrorState()
{
/* ===== 初始化后错误计数器快照(不发帧,避免启动时累积 TEC)===== */
printf("=== CAN INIT ERR STATE ===\r\n");
LOG_ERR("=== CAN INIT ERR STATE ===\r\n");
for (size_t i = 0; i < kChannelCount; ++i) {
const auto &ch = kChannels[i];
uint32_t err = CAN_ERR(ch.canPeriph);
uint32_t tec = (err >> 16) & 0xFFU;
uint32_t rec = (err >> 24) & 0xFFU;
printf("CH%u: ERR=0x%08lX TEC=%lu REC=%lu boff=%u epv=%u ew=%u\r\n",
LOG_ERR("CH%u: ERR=0x%08lX TEC=%lu REC=%lu boff=%u epv=%u ew=%u\r\n",
static_cast<unsigned>(i),
static_cast<unsigned long>(err),
static_cast<unsigned long>(tec),
@@ -504,10 +504,10 @@ void CanFd::printErrorState()
void CanFd::runSelfTest()
{
/* ===== Self-test (NORMAL mode, 发到物理总线测 ACK) ===== */
printf("=== CAN SELF-TEST (normal mode) ===\r\n");
CAN_LOGI("=== CAN SELF-TEST (normal mode) ===\r\n");
for (size_t i = 0; i < kChannelCount; ++i) {
if (!kChannelEnabled[i]) {
printf("CH%u: SKIP(disabled)\r\n", static_cast<unsigned>(i));
CAN_LOGI("CH%u: SKIP(disabled)\r\n", static_cast<unsigned>(i));
continue;
}
const uint8_t ch = static_cast<uint8_t>(i);
@@ -519,14 +519,14 @@ void CanFd::runSelfTest()
const CanSelfTestResult fd = runSelfTestFrame(ch, 0x1FFFFF10U | i, data64, 64, true, false);
#if (CONFIG_CAN_FD_BRS_ENABLE != 0)
const CanSelfTestResult brs = runSelfTestFrame(ch, 0x1FFFFF20U | i, data64, 64, true, true);
printf("CH%u: classic=%s(fd=0) fd_nobrs=%s(fd=1) fd_brs=%s(brs=1) TEC=%lu\r\n",
CAN_LOGI("CH%u: classic=%s(fd=0) fd_nobrs=%s(fd=1) fd_brs=%s(brs=1) TEC=%lu\r\n",
static_cast<unsigned>(i),
c.tec == 0 ? "ACK" : "NO_ACK",
fd.tec == 0 ? "ACK" : "NO_ACK",
brs.tec == 0 ? "ACK" : "NO_ACK",
static_cast<unsigned long>(brs.tec > fd.tec ? brs.tec : fd.tec));
#else
printf("CH%u: classic=%s fd_nobrs=%s TEC=%lu\r\n",
CAN_LOGI("CH%u: classic=%s fd_nobrs=%s TEC=%lu\r\n",
static_cast<unsigned>(i),
c.tec == 0 ? "ACK" : "NO_ACK",
fd.tec == 0 ? "ACK" : "NO_ACK",
@@ -542,17 +542,17 @@ void CanFd::runSelfTest()
void CanFd::runLoopbackTest()
{
/* ===== Loopback 回环测试 (内部 TX→RX,不走物理总线) ===== */
printf("=== CAN LOOPBACK (internal) ===\r\n");
CAN_LOGI("=== CAN LOOPBACK (internal) ===\r\n");
for (size_t i = 0; i < kChannelCount; ++i) {
const auto &ch = kChannels[i];
if (!kChannelEnabled[i]) {
printf("CH%u: SKIP(disabled)\r\n", static_cast<unsigned>(i));
CAN_LOGI("CH%u: SKIP(disabled)\r\n", static_cast<unsigned>(i));
continue;
}
if (CAN_STAT(ch.canPeriph) & CAN_STAT_IWS) {
printf("CH%u: SKIP(stuck_init)\r\n", static_cast<unsigned>(i));
CAN_LOGI("CH%u: SKIP(stuck_init)\r\n", static_cast<unsigned>(i));
continue;
}
@@ -577,7 +577,7 @@ void CanFd::runLoopbackTest()
}
if (!lbkmOk) {
printf("CH%u: SKIP(lbk_fail API:%d/%d/%d reg:LCMOD=0)\r\n",
CAN_LOGI("CH%u: SKIP(lbk_fail API:%d/%d/%d reg:LCMOD=0)\r\n",
static_cast<unsigned>(i), r1, r2, r3);
/* 恢复 normal */
CAN_CTL(ch.canPeriph) |= CAN_CTL_IWMOD;
@@ -646,7 +646,7 @@ void CanFd::runLoopbackTest()
bool brsOk = (s_channelStats[i].rx_count - rxB3) > 0U;
uint32_t tecLb = (CAN_ERR(ch.canPeriph) >> 16) & 0xFFU;
printf("CH%u: classic=%s fd=%s fd_brs=%s TEC=%lu\r\n",
CAN_LOGI("CH%u: classic=%s fd=%s fd_brs=%s TEC=%lu\r\n",
static_cast<unsigned>(i),
cOk ? "PASS" : "FAIL",
fdOk ? "PASS" : "FAIL",
@@ -670,7 +670,7 @@ void CanFd::runLoopbackTest()
uint32_t tecAfterLb = (errAfterLb >> 16) & 0xFFU;
uint32_t recAfterLb = (errAfterLb >> 24) & 0xFFU;
uint32_t statAfterLb = CAN_STAT(ch.canPeriph);
printf("CH%u: post-lb TEC=%lu REC=%lu STAT=0x%08lX BT=0x%08lX CTL=0x%08lX\r\n",
CAN_LOGI("CH%u: post-lb TEC=%lu REC=%lu STAT=0x%08lX BT=0x%08lX CTL=0x%08lX\r\n",
static_cast<unsigned>(i),
static_cast<unsigned long>(tecAfterLb),
static_cast<unsigned long>(recAfterLb),
@@ -678,7 +678,7 @@ void CanFd::runLoopbackTest()
static_cast<unsigned long>(CAN_BT(ch.canPeriph)),
static_cast<unsigned long>(CAN_CTL(ch.canPeriph)));
}
printf("========================\r\n");
CAN_LOGI("========================\r\n");
}
#endif /* CONFIG_CAN_STARTUP_LOOPBACK_TEST_ENABLE */
@@ -687,7 +687,7 @@ void CanFd::runLoopbackTest()
void CanFd::dumpRegisters()
{
/* ===== 初始化后全寄存器快照:诊断 CAN0/CAN1 不收帧 ===== */
printf("=== POST-INIT FULL REG DUMP ===\r\n");
CAN_LOGI("=== POST-INIT FULL REG DUMP ===\r\n");
for (size_t i = 0; i < kChannelCount; ++i) {
const auto &ch = kChannels[i];
uint32_t ctl = CAN_CTL(ch.canPeriph);
@@ -701,7 +701,7 @@ void CanFd::dumpRegisters()
uint32_t rfl0 = CAN_RFIFO0(ch.canPeriph) & 0x3U; /* RFL0 bits 1:0 */
bool normalMode = ((stat & CAN_STAT_IWS) == 0U) && ((bt & (3U << 30)) == 0U);
printf("CH%u: %s CTL=0x%08lX STAT=0x%08lX BT=0x%08lX DBT=0x%08lX\r\n"
CAN_LOGI("CH%u: %s CTL=0x%08lX STAT=0x%08lX BT=0x%08lX DBT=0x%08lX\r\n"
" ERR=0x%08lX INTEN=0x%08lX FCTL=0x%08lX FW=0x%08lX RFL0=%lu\r\n",
static_cast<unsigned>(i),
normalMode ? "NORMAL" : "!!!NOT_NORMAL!!!",
@@ -716,7 +716,7 @@ void CanFd::dumpRegisters()
static_cast<unsigned long>(rfl0));
/* 逐位解析关键标志 */
printf(" IWMOD=%u SLPWMOD=%u ARD=%u ABOR=%u | IWS=%u SLPWS=%u | LCMOD=%u SCMOD=%u\r\n",
CAN_LOGI(" IWMOD=%u SLPWMOD=%u ARD=%u ABOR=%u | IWS=%u SLPWS=%u | LCMOD=%u SCMOD=%u\r\n",
(ctl & CAN_CTL_IWMOD) ? 1U : 0U,
(ctl & CAN_CTL_SLPWMOD) ? 1U : 0U, /* bit1: sleep mode request */
(ctl & CAN_CTL_ARD) ? 1U : 0U, /* bit4: auto retrans disable */
@@ -726,7 +726,7 @@ void CanFd::dumpRegisters()
(bt & (1U << 30)) ? 1U : 0U, /* LCMOD */
(bt & (1U << 31)) ? 1U : 0U); /* SCMOD */
}
printf("===============================\r\n");
CAN_LOGI("===============================\r\n");
}
#endif /* CONFIG_CAN_STARTUP_DIAG_VERBOSE */
@@ -942,7 +942,7 @@ CanFd::CanTxResult CanFd::transmitFrame(uint8_t channelIndex, uint32_t ext_id,
/* 诊断:捕获任何通过 transmitFrame 发 0x100 DLC=16 的帧(排查幽灵帧来源) */
if (ext_id == 0x00000100U && dlc == 16U) {
printf("[CAN-DIAG] TX 0x100 DLC=16 via transmitFrame ch=%u\r\n",
CAN_LOGI("[CAN-DIAG] TX 0x100 DLC=16 via transmitFrame ch=%u\r\n",
(unsigned)channelIndex);
}
@@ -1015,7 +1015,7 @@ CanFd::CanTxResult CanFd::transmitFrame(uint8_t channelIndex, uint32_t ext_id,
static uint32_t s_lastMailboxLogSeq[kChannelCount] = {0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU};
if (s_lastMailboxLogSeq[channelIndex] != s_feedbackSeq) {
const uint32_t errAfter = CAN_ERR(canPeriph);
printf("[CAN-TX-REJECT] CH%u MAILBOX ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu TSTAT=0x%08lX\r\n",
LOG_ERR("[CAN-TX-REJECT] CH%u MAILBOX ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu TSTAT=0x%08lX\r\n",
static_cast<unsigned>(channelIndex),
static_cast<unsigned long>(errAfter),
static_cast<unsigned long>((errAfter >> 4U) & 0x07U),
@@ -1061,7 +1061,7 @@ void CanFd::setChannelAutoRetrans(uint8_t channelIndex, bool enable)
for (volatile uint32_t t = 0U; t < 200000U; ++t) {
if ((CAN_STAT(canPeriph) & CAN_STAT_IWS) == 0U) break;
}
printf("[CAN] CH%u set auto_retrans=%u -> ARD=%u\r\n",
CAN_LOGI("[CAN] CH%u set auto_retrans=%u -> ARD=%u\r\n",
(unsigned)channelIndex, (unsigned)enable,
(CAN_CTL(canPeriph) & CAN_CTL_ARD) ? 1U : 0U);
}
@@ -1369,7 +1369,7 @@ void CanFd::refreshFeedbackSnapshot()
* 仅当 TEC/REC 或告警位非零时输出 [CAN-HW-ERR];全量 seq 心跳见 CONFIG_UART_DIAG_LEVEL。 */
if (s_feedbackSeq % 5U == 0U) {
#if (CONFIG_UART_DIAG_LEVEL != 0)
printf("[CAN-FB] refresh seq=%lu rx0=%lu rx1=%lu rx2=%lu\r\n",
CAN_LOGI("[CAN-FB] refresh seq=%lu rx0=%lu rx1=%lu rx2=%lu\r\n",
(unsigned long)s_feedbackSeq,
(unsigned long)s_channelStats[0].rx_count,
(unsigned long)s_channelStats[1].rx_count,
@@ -1380,7 +1380,7 @@ void CanFd::refreshFeedbackSnapshot()
&& (hw_err[i] & (CAN_ERR_WERR | CAN_ERR_PERR | CAN_ERR_BOERR)) == 0U) {
continue;
}
printf("[CAN-HW-ERR] CH%u ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu TSTAT=0x%08lX\r\n",
LOG_ERR("[CAN-HW-ERR] CH%u ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu TSTAT=0x%08lX\r\n",
static_cast<unsigned>(i),
static_cast<unsigned long>(hw_err[i]),
static_cast<unsigned long>((hw_err[i] >> 4U) & 0x07U),
@@ -1418,7 +1418,7 @@ void CanFd::refreshFeedbackSnapshot()
else if (cur & (1U << 3)) stateStr = "BUS_OFF";
else if (cur & (1U << 2)) stateStr = "ERR_PASSIVE";
else if (cur & (1U << 4)) stateStr = "ERR_WARN";
printf("[CAN-BUS] CH%u: %s -> %s ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu seq=%lu\r\n",
LOG_ERR("[CAN-BUS] CH%u: %s -> %s ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu seq=%lu\r\n",
static_cast<unsigned>(i),
(s_prevBusState[i] == 0xFF) ? "?" :
(s_prevBusState[i] & (1U << 3)) ? "BUS_OFF" :