Skip to content

feat(CmBacktrace): enhance reliability, configurability, and testability#22

Open
wdfk-prog wants to merge 1 commit intoarmink-rtt-pkgs:masterfrom
wdfk-prog:reliability
Open

feat(CmBacktrace): enhance reliability, configurability, and testability#22
wdfk-prog wants to merge 1 commit intoarmink-rtt-pkgs:masterfrom
wdfk-prog:reliability

Conversation

@wdfk-prog
Copy link
Copy Markdown
Contributor

@wdfk-prog wdfk-prog commented Oct 30, 2025

代码审核 (Code Review)

这是一次对 CmBacktrace 组件非常有价值的、多方面的改进。它同时提升了组件的可靠性、可配置性和可测试性,是-一次质量非常高的提交。

整体评价:
代码逻辑清晰,改动精确且必要。开发者显然深刻理解在嵌入式故障处理中的痛点,并提供了优雅且完整的解决方案。强烈建议合入。

优点 (Pros):

  1. 核心可靠性增强 (Enhanced Core Reliability):

    • 切换到紧急日志: 将 ulog_flush() 替换为 ulog_emergency_flush() 是本次提交最关键的改进。它解决了在 HardFault 等中断上下文中调用标准日志函数可能导致系统死锁或二次故障的根本问题。
    • 注册紧急后端: 与上一条相辅相成,将 cmb_flash_log 后端正确地标记为 is_emergency_backend = RT_TRUE,确保了紧急日志刷新机制能够找到并使用这个安全的后端。这两项改动使得 CmBacktrace 在最危急的时刻能够真正发挥作用。
  2. 大幅提升易用性和可测试性 (Improved Usability and Testability):

    • 新增 cmb_test MSH宏:。
    • 条件编译: 将测试代码包裹在 PKG_CMBACKTRACE_ENABLE_TEST 宏中,确保了它不会被编译进最终的发布版本,避免了不必要的代码空间占用。
  3. 提升可配置性 (Improved Configurability):

    • cmb_port.c 中,将 cm_backtrace_init 函数的硬编码版本号字符串替换为宏定义 (CMBACKTRACE_FIRMWARE_NAME, etc.)。这是一个良好的实践,使得固件版本信息可以通过 Kconfig 或其他配置方式轻松管理,而无需直接修改代码。
  4. 修正初始化时机 (Corrected Initialization Order):

    • INIT_APP_EXPORT 替换为 INIT_FS_EXPORT 是一个非常专业的改动。它保证了 Flash 日志后端在文件系统初始化完毕后、但在普通应用启动前进行注册,确保了日志系统能在更早的启动阶段生效。
  5. 增强兼容性 (Enhanced Compatibility):

    • cmb_flash_log.c 中,根据 RT_VER_NUM 来包含不同的头文件,处理了 RT-Thread 不同版本间文件系统接口的差异,体现了良好的代码维护性和前瞻性。

建议 (Suggestions):

  • 无。这次提交考虑得非常周全,逻辑严谨,是高质量代码的典范。

验证如下

[2025/10/30 16:48:24 108] msh /flash/log>cmb
[2025/10/30 16:48:24 109] cmb_test
[2025/10/30 16:48:24 705] msh /flash/log>cmb_test
[2025/10/30 16:48:24 707] Please input 'cmb_test <DIVBYZERO|UNALIGNED|ASSERT>' 
[2025/10/30 16:48:29 462] msh /flash/log>cmb_test UNALIGNED
[2025/10/30 16:48:29 464] addr:0x00 value:0x20002A28
[2025/10/30 16:48:29 612] addr:0x04 value:0x08000229
[2025/10/30 16:48:29 612] thread             pri  status      sp     stack size max used left tick   error  tcb addr   usage
[2025/10/30 16:48:29 612] ------------------ ---  ------- ---------- ----------  ------  ---------- ------- ---------- -----
[2025/10/30 16:48:29 613] motorControlTask4    4  suspend 0x000001bc 0x00000800    36%   0x00000002 EINTRPT 0x200139cc   0%
[2025/10/30 16:48:29 613] motorControlTask3    4  suspend 0x000001bc 0x00000800    36%   0x00000001 EINTRPT 0x200130ec   0%
[2025/10/30 16:48:29 613] motorControlTask2    4  suspend 0x000001bc 0x00000800    36%   0x00000002 EINTRPT 0x2001280c   0%
[2025/10/30 16:48:29 613] motorControlTask1    4  suspend 0x000001bc 0x00000800    35%   0x00000002 EINTRPT 0x20011f2c   0%
[2025/10/30 16:48:29 613] canTxTask            3  suspend 0x0000011c 0x00000400    79%   0x00000003 EINTRPT 0x2001186c   0%
[2025/10/30 16:48:29 613] moduleControlTask    4  suspend 0x000000cc 0x00000400    25%   0x00000001 EINTRPT 0x20011014   0%
[2025/10/30 16:48:29 613] seppukuTask          4  suspend 0x000000cc 0x00000400    25%   0x00000005 EINTRPT 0x20010b34   0%
[2025/10/30 16:48:29 613] canRxTask            2  suspend 0x000000dc 0x00002000    02%   0x00000005 EINTRPT 0x2000d584   0%
[2025/10/30 16:48:29 613] tshell              20  running 0x0000015c 0x00001000    51%   0x00000008 OK      0x2000b630   0%
[2025/10/30 16:48:29 613] ulog_async          30  suspend 0x000000bc 0x00001000    45%   0x0000000d EINTRPT 0x2000a140   1%
[2025/10/30 16:48:29 613] tidle0              31  ready   0x0000005c 0x00000100    78%   0x00000015 OK      0x20003d54  97%
[2025/10/30 16:48:29 613] timer                4  suspend 0x000000ac 0x00000200    33%   0x00000009 EINTRPT 0x20004140   0%
[2025/10/30 16:48:29 613] 01-01 00:00:00 cmb:  
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb: Firmware name: 5axis, hardware version: 1.0, software version: 1.0
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb: Fault on interrupt or bare metal(no OS) environment
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb: ===== Thread stack information =====
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb:   addr: 20003cf4    data: 2000415c
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb:   addr: 20003cf8    data: 00000000
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb:   addr: 20003cfc    data: 08027db9
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb:   addr: 20003d00    data: 08020270
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb:   addr: 20003d04    data: 01000200
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb:   addr: 20003d08    data: 080554fb
[2025/10/30 16:48:29 803] 01-01 00:00:00 cmb: ====================================
[2025/10/30 16:48:29 804] 01-01 00:00:00 cmb: =================== Registers information ====================
[2025/10/30 16:48:29 804] 01-01 00:00:00 cmb:   R0 : 2000c5d4  R1 : 2000c5f8  R2 : 2000c618  R3 : 080202c3
[2025/10/30 16:48:29 804] 01-01 00:00:00 cmb:   R12: fffffffd  LR : 00000000  PC : 10000000  PSR: f0000000
[2025/10/30 16:48:29 804] 01-01 00:00:00 cmb: ==============================================================
[2025/10/30 16:48:29 804] 01-01 00:00:00 cmb: Usage fault is caused by indicates that an unaligned access fault has taken place
[2025/10/30 16:48:29 804] 01-01 00:00:00 cmb: Show more call stack info by run: addr2line -e 5axis.elf -afpiC 10000000 08027db8 080554fa 
[2025/10/30 16:48:29 805] 01-01 00:00:00 cmb: Current system tick: 20784


[2025/10/30 16:53:44 892] msh />
[2025/10/30 16:53:47 096] msh />cd l
[2025/10/30 16:53:48 053] msh />cd f
[2025/10/30 16:53:48 436] msh />cd flash/l
[2025/10/30 16:53:48 740] msh />cd flash/log/
[2025/10/30 16:53:50 591] msh /flash/log>ls
[2025/10/30 16:53:50 608] Directory /flash/log:
[2025/10/30 16:53:50 655] cmb.log              2917                     
[2025/10/30 16:53:50 720] flash_sys.log        16518                    
[2025/10/30 16:53:52 466] msh /flash/log>cat c
[2025/10/30 16:53:52 818] msh /flash/log>cat cmb.log
[2025/10/30 16:53:53 128] 01-01 00:00:00 cmb:  
[2025/10/30 16:53:53 128] ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ01-01 00:00:00 cmb:  
[2025/10/30 16:53:53 129] ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ01-01 00:00:00 cmb:  
[2025/10/30 16:53:53 129] ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ01-01 00:00:00 cmb:  
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Firmware name: 5axis, hardware version: 1.0, software version: 1.0
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Fault on interrupt or bare metal(no OS) environment
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: ===== Thread stack information =====
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   addr: 20003cf4    data: 2000415c
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   addr: 20003cf8    data: 00000000
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   addr: 20003cfc    data: 08027db9
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   addr: 20003d00    data: 08020270
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   addr: 20003d04    data: 01000200
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   addr: 20003d08    data: 080554e7
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: ====================================
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: =================== Registers information ====================
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   R0 : 2000c5d4  R1 : 2000c5f8  R2 : 2000c618  R3 : 080202c3
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:   R12: fffffffd  LR : 00000000  PC : 10000000  PSR: f0000000
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: ==============================================================
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Usage fault is caused by indicates that an unaligned access fault has taken place
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Show more call stack info by run: addr2line -e 5axis.elf -afpiC 10000000 08027db8 080554e6 
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Current system tick: 11837
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb:  
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Firmware name: 5axis, hardware version: 1.0, software version: 1.0
[2025/10/30 16:53:53 129] 01-01 00:00:00 cmb: Fault on interrupt or bare metal(no OS) environment
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: ===== Thread stack information =====
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   addr: 20003cf4    data: 2000415c
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   addr: 20003cf8    data: 00000000
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   addr: 20003cfc    data: 08027db9
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   addr: 20003d00    data: 08020270
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   addr: 20003d04    data: 01000200
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   addr: 20003d08    data: 080554fb
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: ====================================
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: =================== Registers information ====================
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   R0 : 2000c5d4  R1 : 2000c5f8  R2 : 2000c618  R3 : 080202c3
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb:   R12: fffffffd  LR : 00000000  PC : 10000000  PSR: f0000000
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: ==============================================================
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: Usage fault is caused by indicates that an unaligned access fault has taken place
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: Show more call stack info by run: addr2line -e 5axis.elf -afpiC 10000000 08027db8 080554fa 
[2025/10/30 16:53:53 130] 01-01 00:00:00 cmb: Current system tick: 20784

@milo-9
Copy link
Copy Markdown

milo-9 commented Nov 4, 2025

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

@wdfk-prog
Copy link
Copy Markdown
Contributor Author

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

  1. cmb组件在什么顺序下初始化不影响;在最后阶段初始化也可以.毕竟初始化都没有完成就出异常了多半也不需要cmb了
  2. cmb有文件备份的一个功能,如果开启这个功能的话,是对接到fal组件的.fal组件的初始话是自行调用的.一般来说fal层还可以对接一个文件系统,那么在文件系统阶段执行cmb初始化会保险一点.防止fal没有初始化就启动

@milo-9
Copy link
Copy Markdown

milo-9 commented Nov 5, 2025

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

  1. cmb组件在什么顺序下初始化不影响;在最后阶段初始化也可以.毕竟初始化都没有完成就出异常了多半也不需要cmb了
  2. cmb有文件备份的一个功能,如果开启这个功能的话,是对接到fal组件的.fal组件的初始话是自行调用的.一般来说fal层还可以对接一个文件系统,那么在文件系统阶段执行cmb初始化会保险一点.防止fal没有初始化就启动

因为你的pr描述里说这个执行在INIT_APP_EXPORT前,我纠正你而已。
不过后面的文件备份功能,目前来讲几乎是不可用的,断言中或者hardfault中断中,调用那些文件系统会涉及到调用很多系统内核API,很多API对执行上下文是有要求的,而断言和hardfault中断的上下文很难满足这些要求。

@wdfk-prog
Copy link
Copy Markdown
Contributor Author

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

  1. cmb组件在什么顺序下初始化不影响;在最后阶段初始化也可以.毕竟初始化都没有完成就出异常了多半也不需要cmb了
  2. cmb有文件备份的一个功能,如果开启这个功能的话,是对接到fal组件的.fal组件的初始话是自行调用的.一般来说fal层还可以对接一个文件系统,那么在文件系统阶段执行cmb初始化会保险一点.防止fal没有初始化就启动

因为你的pr描述里说这个执行在INIT_APP_EXPORT前,我纠正你而已。 不过后面的文件备份功能,目前来讲几乎是不可用的,断言中或者hardfault中断中,调用那些文件系统会涉及到调用很多系统内核API,很多API对执行上下文是有要求的,而断言和hardfault中断的上下文很难满足这些要求。

  • 是的,文件系统不满足可用需求.
  • cmb目前是直接调用fal的接口,不走文件系统.
  • 所以我对SPI FLASH的驱动以及STM32 的 spi驱动进行了中断上下文的适配

@milo-9
Copy link
Copy Markdown

milo-9 commented Nov 5, 2025

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

  1. cmb组件在什么顺序下初始化不影响;在最后阶段初始化也可以.毕竟初始化都没有完成就出异常了多半也不需要cmb了
  2. cmb有文件备份的一个功能,如果开启这个功能的话,是对接到fal组件的.fal组件的初始话是自行调用的.一般来说fal层还可以对接一个文件系统,那么在文件系统阶段执行cmb初始化会保险一点.防止fal没有初始化就启动

因为你的pr描述里说这个执行在INIT_APP_EXPORT前,我纠正你而已。 不过后面的文件备份功能,目前来讲几乎是不可用的,断言中或者hardfault中断中,调用那些文件系统会涉及到调用很多系统内核API,很多API对执行上下文是有要求的,而断言和hardfault中断的上下文很难满足这些要求。

  • 是的,文件系统不满足可用需求.
  • cmb目前是直接调用fal的接口,不走文件系统.
  • 所以我对SPI FLASH的驱动以及STM32 的 spi驱动进行了中断上下文的适配

哪怕是走fal,也对驱动实现是有要求的,fal目前来讲像调用sfud或者直接读写片内flash,驱动实现一般都会加上互斥锁,获取锁的上下文要求也是不满足的。除非实现一个特定的fal驱动,或者配置特定区域不获取锁,保证只有cmb会读写,而且内部实现还得谨慎调用内核API。这个功能的通用性就大打折扣了,既然没有通用性,就干脆自己实现这个功能好了,没必要再用这个框架的这个功能了。所以我的结论是,保存日志这个功能,目前来讲是鸡肋。

@armink
Copy link
Copy Markdown
Member

armink commented Nov 5, 2025

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

  1. cmb组件在什么顺序下初始化不影响;在最后阶段初始化也可以.毕竟初始化都没有完成就出异常了多半也不需要cmb了
  2. cmb有文件备份的一个功能,如果开启这个功能的话,是对接到fal组件的.fal组件的初始话是自行调用的.一般来说fal层还可以对接一个文件系统,那么在文件系统阶段执行cmb初始化会保险一点.防止fal没有初始化就启动

因为你的pr描述里说这个执行在INIT_APP_EXPORT前,我纠正你而已。 不过后面的文件备份功能,目前来讲几乎是不可用的,断言中或者hardfault中断中,调用那些文件系统会涉及到调用很多系统内核API,很多API对执行上下文是有要求的,而断言和hardfault中断的上下文很难满足这些要求。

  • 是的,文件系统不满足可用需求.
  • cmb目前是直接调用fal的接口,不走文件系统.
  • 所以我对SPI FLASH的驱动以及STM32 的 spi驱动进行了中断上下文的适配

哪怕是走fal,也对驱动实现是有要求的,fal目前来讲像调用sfud或者直接读写片内flash,驱动实现一般都会加上互斥锁,获取锁的上下文要求也是不满足的。除非实现一个特定的fal驱动,或者配置特定区域不获取锁,保证只有cmb会读写,而且内部实现还得谨慎调用内核API。这个功能的通用性就大打折扣了,既然没有通用性,就干脆自己实现这个功能好了,没必要再用这个框架的这个功能了。所以我的结论是,保存日志这个功能,目前来讲是鸡肋。

赞同的,真的要可靠的保存日志最好直接对接到最底层驱动,不要依赖太多中间件

@wdfk-prog
Copy link
Copy Markdown
Contributor Author

INIT_FS_EXPORT是在INIT_APP_EXPORT后面执行的

  1. cmb组件在什么顺序下初始化不影响;在最后阶段初始化也可以.毕竟初始化都没有完成就出异常了多半也不需要cmb了
  2. cmb有文件备份的一个功能,如果开启这个功能的话,是对接到fal组件的.fal组件的初始话是自行调用的.一般来说fal层还可以对接一个文件系统,那么在文件系统阶段执行cmb初始化会保险一点.防止fal没有初始化就启动

因为你的pr描述里说这个执行在INIT_APP_EXPORT前,我纠正你而已。 不过后面的文件备份功能,目前来讲几乎是不可用的,断言中或者hardfault中断中,调用那些文件系统会涉及到调用很多系统内核API,很多API对执行上下文是有要求的,而断言和hardfault中断的上下文很难满足这些要求。

  • 是的,文件系统不满足可用需求.
  • cmb目前是直接调用fal的接口,不走文件系统.
  • 所以我对SPI FLASH的驱动以及STM32 的 spi驱动进行了中断上下文的适配

哪怕是走fal,也对驱动实现是有要求的,fal目前来讲像调用sfud或者直接读写片内flash,驱动实现一般都会加上互斥锁,获取锁的上下文要求也是不满足的。除非实现一个特定的fal驱动,或者配置特定区域不获取锁,保证只有cmb会读写,而且内部实现还得谨慎调用内核API。这个功能的通用性就大打折扣了,既然没有通用性,就干脆自己实现这个功能好了,没必要再用这个框架的这个功能了。所以我的结论是,保存日志这个功能,目前来讲是鸡肋。

赞同的,真的要可靠的保存日志最好直接对接到最底层驱动,不要依赖太多中间件

  • 有fal层做中转减少了很多负担.
  • 直接对接最底层驱动感觉对于用户来说还是很难搞的.
  • 能够对接fal->rtt的驱动框架的话,会轻松很多.
  • 只能说目前的驱动框架与bsp驱动并没有对中断上下文进行太多适配

@Rbb666
Copy link
Copy Markdown

Rbb666 commented Nov 7, 2025

  • 对SPI FLASH的驱动以及STM32 的 spi驱动

我有个思路,可以把异常信息保存到ram里面,然后下一次复位的时候可以dump出来,mcoredump 软件包就是这么做的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants