在对嵌入式程序进行调测的时候,经常会有“IAR变量观察窗口怎么使用,IAR变量值显示异常怎么判断”这种疑问被大家碰到;其实这个窗口不仅仅是把数值摆出来这么简单,它的背后还牵扯到编译器的优化、调试文件的有无、变量自己起作用的范围、内存的具体地址、数据的不同类型解释,甚至连DMA和中断去改动数据都会对它产生影响;有时候数据确实被程序更改了,有时候却只是软件窗口显示得不准确,所以在找问题的时候,首先得把“显示出问题”和“运行出问题”给区分开才行。
一、IAR里面的变量观察窗口应该怎么去用
在IAR这个软件里面,大家比较常用的去观察变量的办法,主要就是利用Watch、Locals、Live Watch还有Memory这几个不同的窗口;因为不同的窗口针对的场景是不一样的,所以大家不能把所有的变量都只塞到一个Watch窗口里面去盯着看。
1、利用Watch窗口去对指定的变量进行查看
当把调试模式进去了之后,通过点击菜单栏里面的【View】→【Watch】,就可以把变量观察窗口给打开了;在里面的空行里,把变量的名字、数组里面的元素、结构体里面的成员或者一些简单的计算式子输进去,当前的数值就能被看到了;像那些全局变量、代表状态的标志位、数数用的计数器,还有通信的状态这些,都比较适合被放到Watch窗口里去进行长时间的盯着看。
2、利用Locals窗口去对局部变量进行查看
在对函数里面的内部逻辑进行调试的时候,【View】→【Locals】这个窗口可以被打开;当前函数范围里的那些局部变量都会自动在这个窗口里显示出来,大家不需要自己去一个一个地手动添加进去;在进行单步执行程序的时候,参数是怎么传的、临时变量是怎么算的,还有分支条件有没有对,Locals窗口都能帮着去进行查看和判断。
3、利用Live Watch去盯着运行过程里的变化
如果大家想要看到正在运行着的计数器、采样出来的数值,或者是状态机里面的变量,这时候Live Watch就可以被用上了;它比较适合用来观察那些即使程序不眼看着停下来,自己也会一直变个不停的变量,比如定时器的计数、通信时候的接收标志,还有ADC采样的结果之类的。
二、IAR变量值显示异常怎么判断
当发现变量的数值看起来不太对劲的时候,大家千万不能只盯着窗口里面的数字去发呆;这时候真正需要去搞清楚的是:这个变量是不是被编译优化给影响到了,或者是数据类型被自己给看错了,再或者是被别的什么代码给偷偷改掉了,甚至有可能是目标板子上烧录的根本就不是现在手里的这一套程序。
1、首先要去检查优化的等级还有调试信息
通过点击【Project】→【Options】→【C/C++Compiler】,当前设置的优化等级就可以被看到了;在写代码调试的阶段,Debug配置是建议被大家选用的,而且优化的等级也得尽量给调得低一些;因为要是把优化开得太高了,编译器就会自作主张地把变量直接塞进寄存器里、把没用到的变量给删掉、把几句语句给拼到一起,或者把代码执行的先后顺序给换了;这么一来的话,虽然源程序里的变量还在,但是调试窗口却不一定能把准确的数值给显示出来了。
2、去看看变量现在是不是还待在有效的作用域里面
那些局部变量、临时变量,还有写在特定代码块内部的变量,各自都是有自己的起作用范围的;比方说某个变量只是在if语句的大括号里面被定义了一下,那么等程序跑出了这个大括号之后,大家再去盯着它看可就不怎么靠谱了;函数的参数也是一回事,在被编译器优化了之后,它可能早就没待在以前的那个栈位置上了。
3、把数据的类型还有显示的格式去对一下
有时候看到的变量值不对,可能只是因为显示的格式被弄错了;比方说寄存器的数值比较适合用十六进制去瞅,状态的标志比较适合用二进制的位去瞅,而通信的缓冲区就比较适合当成字节数组去瞅;像结构体、联合体、指针、枚举还有位域这些复杂的类型,都特别容易因为理解和解释的方法不一样,从而被大家给看错。
三、变量观察仍然异常需要摸排哪些方面
如果发现变量的数值一直在那瞎跳、明明代码里没有给它赋过值它自己却变了,或者是程序停在断点的时候,数值和心里的预期一点都不一样,这时候运行时候的各种因素就得继续去查了;在嵌入式程序里面,变量可不一定单单只是被现在的这个函数给改动的。
1、去查查变量是不是被中断或者DMA给改过了
有很多代表状态的变量、接收用的缓存区、数数用的计数器还有标志位,经常会在中断服务函数、DMA的回调函数或者外设的驱动程序里面被偷偷修改掉;主循环里面虽然看着没有写赋值的代码,但这可不代表变量没有在别的地方被写入过数据;这时候可以把整个工程翻个底朝天,去搜一搜这个变量的名字,把注意力集中放在那些赋值的语句、传指针的参数、回调函数还有中断服务程序上面。
2、去排查一下数组有没有越界,内存有没有被覆盖掉
变量的数值要是莫名其妙地变了,这里面非常常见的一个原因就是数组写过界了、指针指错了地方、栈溢出了,或者是DMA的目标地址被不小心配置错了;比方说接收的缓冲区要是写得超出了范围,可能就会把挨在它旁边的全局变量给硬生生盖掉了;又或者是RTOS的任务栈给得太小了,这也会导致里面的局部变量显示出来一堆乱七八糟的随机数。
3、去确认一下目标板子里跑的到底是不是最新的程序
有时候源程序虽然已经被改过了,但是程序其实并没有真正重新下载进去,或者是下载失败了导致目标板子上还在跑着以前的旧版本,这种情况也会导致看到的变量显示和手里的代码逻辑完全对不上号;所以在费劲排查之前,最好是去点一下【Rebuild All】重新全部编译一遍,然后把程序再规规矩矩地下载一次。
总结
IAR变量观察窗口可以通过【Watch】查看指定变量,通过【Locals】查看当前函数局部变量,通过【Live Watch】观察运行中变化的变量,通过【Memory】核对原始内存内容。遇到IAR变量值显示异常时,不要马上判断代码逻辑错了,要先检查优化等级、调试信息、变量作用域、显示格式、数据类型和目标程序版本。如果变量确实被改写,再继续排查中断、DMA、数组越界、指针错误和栈溢出。把显示问题和真实运行问题分开看,变量调试会清楚很多。