粗浅的小结而已,可能是错误的。
1. 编译器方法
主要解决语法错误。
可以准确解决逻辑错误,如查看变量/函数的方法,但是,缺点:效率低,需要中止程序的运行。
2. printf 函数输出信息法
主要解决逻辑错误;用于手工测试。
程序逻辑是程序员安排的结果,逻辑错误不属于语法错误,而使用编译器方法来解决这类错误,在有些场景里,效率是低下的,不如 printf 高效。比如:一个开关到底是关?还是开?才是正确的逻辑呢?这是人为规定的结果。printf还具备灵活性,可以输出程序员想要的其他信息。
串口在调试中的最通用的:通过串口通信,串口将信息输出到上位机,这在嵌入式调试中,是高效的。
缺点:必须采用合理的程序结构,保证在串口输出期间,既要输出需要的信息,又要不会干扰到程序的正常运行。这种程序需求,在有些时钟要求不被打断的应用中,是困难的;此时可能需要采用专门的测试软件。
一种解决 printf 输出速度慢问题的方法:有些程序段的运行,是有时间要求的,不能被长时间打断。可以预设一些变量,用于保存测试的结果,然后,再 printf 输出。解决 printf 输出速度慢的问题。
https://www.bilibili.com/video/BV1bv4y1R7dp?p=43
// 注意:修改日期:2020年的新版,还增加了如 OS选择,arm 编译器 V6选择等等的功能。
// 修改日期:2015/9/7
//V1.0修改说明
//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
//#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//使用 Keil 微库,则直接改下如下,即可。
//重定义fputc函数
int fputc(int ch, FILE *f)
{// SR&0X40:为该款 MCU 串口寄存器的发送完成标志位
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
重定向到通用串口,但其他接口的显示设备,也是可以的。
- 串口一般连接电脑里的上位机。这可能是最普遍的。
- 嵌入式设备大多有自己的显示屏,这些显示屏有不同的接口通信方式。比如:IIC、SPI、LCD TFT等等。这时 printf 可以直接重定向到这些显示设备上。
说明:
1. 与“测试软件法”相比,简单、方便;各有各的好处,各有各的不足,比如:“测试软件法”的初期需要耗费大量的工时,但后期就会快捷了。
2. ARM的 printf 函数与其他 MCU的,是不同的。ARM的 printf 函数默认采用了半主机模式,当不不使用 ARM的专门、或兼容调试器时,需要注意关闭“半主机模式”。
关联参考:
ARM半主机模式介绍,及 printf (**) https://blog.csdn.net/ken2232/article/details/135324666
串口通信:printf 重定向 (****) https://blog.csdn.net/ken2232/article/details/135347248
3. 测试软件法
主要解决逻辑错误;用于自动化测试。
还可以解决数据错误,运行时错误等等的几乎全部的软件错误?
黑盒、白盒测试。
有免费开源的;如:gtest,cpptest。
有收费的;如:。
说明:采用测试软件法的工作量,有些可能会接近、甚至超过正常软件开发的工作量。
因此,未必什么样的项目都需要采用这种测试方法。比如:一些迭代快的产品,以其使用测试软件法,还不如直接使用人工进行测试、来得简便和快捷。
4. 直接人工测试法
主要解决软件的逻辑错误,硬件问题,以及其他等等的问题;这种测试方法,一般会贯穿于软件开发中的各个阶段,以及成品和售后阶段。
可以先记录下、或者立即修改在测试中发现的问题代码,硬件问题等等。
根据软件需求书,直接人工测试。
x. 小结
没有包治百病的药:没有一种调试工具,可以适用于所有的调试场景。
或者说,不同的调试工具,有其最佳的适用场景。假如当前场景没有适合的调试工具,可能就需要创造了。
调试工具的选择,与具体的场景需求有关。有时,需要同时采用几种不同的调试工具,来满足不同场景之下的调试需要。