0%
调试技巧
- 上电后(或初始化完成后)点亮一枚LED可判断上述过程是否有误(复位或初始化代码问题排查),运行main函数的死循环时让LED闪烁可以判断系统此时运行状况(有效判断操作执行是否异常)
- 完成前期模块测试后先使用模拟器检查软件运行是否正确,后再烧写上机调试
- 通过对某个GPIO引脚产生逻辑电平作为调试信号,辅之以示波器可以调试某些对时序性较高的过程代码
- Keil的调试技巧(内存读写断点,条件/次数断点,运行时在断点用Command输出字符)
优化提示
- 在本机仿真或用某些调试器时可能有Profiler工具查看执行时间与调用次数,方便确定优化目标
- 在开发阶段务必将编译器优化关掉,因为某些编译器优化会使代码执行结果异常(必要时使用volatile变量)
- 使用查询表(函数指针的数列)代替switch,化判断为寻址
- 使用全局变量来传入参数(但程序模块化下降),特别是浮点数等较大的数据类型;使用register修饰变量可针对频繁读取的变量优化
- 使用内联函数优化某些微小的函数,降低堆栈传参带来的额外开销
- 适配堆栈大小,使程序在正常运行的情况下不浪费内存(但注意堆栈溢出会带来致命的后果)
做法:在函数内定义变量如int a[n];并赋一个特殊值,调整n的大小直到程序完整运行的时候崩溃(崩溃后应该进行跟踪),以此估算所需堆栈大小
减小堆栈大小:避免递归算法,减小局部变量的大小,内存对齐问题 - 避免浮点运算或用硬件指令代替;手动写汇编
可靠性改进
- main初始化部分:禁用所有中断,(禁用所有外设或其时钟,可将其所有配置清除)禁用所有外设或其时钟(防止未配置完成的外设出现误动作),部分情况需要禁用所有中断并立即复位
使用HAL_NVIC_DisableIRQ,__set_FAULTMASK(1)
,__disable_irq()
(CPSID)禁用中断
将APB时钟关闭,或关闭单个外设时钟,或清除外设使能位(参考HAL_DeInit) - 检查复位情况(看门狗复位/软件复位,上电复位/欠压复位),确定保持复位前的哪些变量以及哪些外设需要初始化
- 若为看门狗复位,尝试提取保存错误信息
- 初始化外设,尽量恢复原来的状态流程运行
- 接管错误中断:关闭所有中断,然后等待(循环,BKPT)或直接复位