在初学者眼里,调试手段很多,自己平常使用调试手段的具有局限性、单一性,碰到复杂的问题还是很难解决。比如看watch窗口、memory窗口、打断点这些基本的调试手段。
就比如新接手中的一个项目,总是会出现串口通信错误,我也知道这是两次数据发送混乱了,但就是很难解决,为什么?因为通信是时时刻刻发生的,而你却不知道会在哪一刻发生错误。即使你一直处于在线调试状态,按照一般的调试手段,你也只能通过 Watch、Memory 之类的调试手段获得一些发生通信错误的那一刻的数据,但是之前的数据却早已淹没在时间长河里,你不知道在发生通信错误之前发生了什么,而往往通信错误之前的历史数据才是重中之重。
如何记录调试过程中的历史数据??
在keil里面:
ITM 调试,硬件不支持就不能使用
ini文件可不用硬件支持也可以使用
ini文件相当于一个额外的.c 文件,可以实现如单片机程序的绝大多数事情,比如读取 IO,读取寄存器,读取内存,操作寄存器,写入内存等等,更多详细的内容可参看官方的在线帮助文档。
当然你也可以直接像打开 txt 文件一样打开这个文件。
而你会发现,和写 C 程序一样,可定义变量、函数,你也可以使用 // 来进行必要的注释,当然 /**/ 也是可以的。本文以调用函数为例。
FUNC int add(int a, int b)
{
printf("hello world!!!\n");;
return (a+b);
}
FUNC void MyRegs(void)
{
printf ("---------- MyRegs() ----------\n");
printf (" R4 R8 R9 R10 R11 R12\n");
printf (" %04X %04X %04X %04X %04X %04X\n",
R4, R8, R9, R10, R11, R12);
printf ("------------------------------\n");
}
FUNC void TEST_PRINTF(void)
{
printf("test printf!!!\n");;
}
将.ini 文件添加到初始化文件中,KEIL 进入调试模式的时候,会自动加载这个文件,并执行里面的内容,假设我们保存为test.ini
在进入调试模式下,程序在没运行下或者停止(打断点停止),可编辑ini文件,可编辑文件的话,就有红色框框下面这个选项
ini文件编辑后,编译
通过command串口输入命令,调用ini文件里面的函数,程序运行时调用,按ENTER键结束调用输入
也可以定义按钮,调用ini文件里面的函数,程序运行时调用
在command窗口输入创建按钮命令,可创建按钮
分别输入两个命令,创建两个按钮,对应的两个命令
DEFINE BUTTON "MyRegs","MyRegs()" /*调用调试函数*/
DEFINE BUTTON "TEST_PRINTF","TEST_PRINTF()" /*调用调试函数*/
按下按钮可以可在运行过程中,任意调用运行函数;
比如一直按下
command窗口一直输出调用函数运行输出的结果
删除按钮MyRegs在command输入
KILL BUTTON 1 /* Kill Toolbox Button number 1 */
删除按钮TEST_PRINTF在command输入
KILL BUTTON 2 /* Kill Toolbox Button number 2 */