15.210控制台故障分析(解决问题的思路)
对于串口的输出,210按照前面的操作是下面的乱码。
-
第一想到的很可能是波特率的问题,这是串口乱码的一般情况。排除这一点的是前面的putc函数是可以实现的。验证:
如上面,先把主函数里的printf信息给注释掉。加上putc函数。重新编译和加头:
开发板先格式化
再下载:
下载成功之后,却换到NandFlash启动,看看串口有没有输出:
可以看到终端上面有信息的正常输出,说明了putc是可以工作的,也就是波特率没有错。
上面就确保了波特率没有问题,接下来想到的是串口打印函数printf有问题。在printf函数里我们就实现了两个功能:1)格式化输入的信息。2)输出格式化后的信息。
一般想到的是,很可能是在1)格式化输入的信息的时候出错了,导致输出的是乱码。也有可能2)输出格式化后的信息有错。
之所以说输出信息的地方出错的可能性很小,这是因为前面的putc已经正常工作了。接下来就是排除这种情况。
主函数,直接调用printf:
做了上面的修改之后重新编译,烧写到开发板,设置从NandFlash启动:
可以看到仍然是乱码。上面转化已经被注释掉了,可还是乱码。说明在输出的时候就已经有问题了。
解析来就是注释掉for循环,直接输出一个变量:
重新编译,烧写到开发板,NandFlash启动:
当改为变量之后,干脆就没输出了。
说明了输出一个变量都有问题,接下来测试一下输出一个字符:
重新编译,烧写到开发板,NandFlash启动:
换成字符之后又没问题了。
从上面的结果知道,问题出在变量上面。由于上面的变量是已经初始化的,存在于数据段,接下来就是检查数据段的位置和内容是否正确。
数据段的位置是在代码段之后的,打开lds文件即可确定:
可以看到是没有问题的。
接下来是确认数据段的内容里有没有tmp变量。
打开dump,搜索tmp变量:
可以看到,tmp是在elf文件里,也是在数据段的。但是存不存在与gboot.bin文件中呢!?
上面可以看到,定义的内容已经编译进入了.bin文件。
就是数据段的内容也是正确的。
问题是,210里的uboot是需要加上一个头信息的:gboot-210.bin,打开gboot-210.bin之后:
发现加了头信息之后的uboot.bin里的内容变了好多,根本就没有我们定义的信息。
查看两个文件的大小:
上面可以到,gboot-210.bin比gboot.bin小了很多,但是,按道理,由于gboot-210.bin比gboot.bin多了一个头信息,应该是要大一点才对,反而小了。
可以得出的结论了,就是没加头信息的uboot.bin是正常的,加了头信息后,反而不正常,且是数据段的内容减少了。所以问题就出在加头程序了。
打开加头程序后,可以看到:
可以看到,上面BUFSIZE和IMG_SIZE的大小都是16k,然后是不是定义的BUFSIZE和IMG_SIZE太小,然后把后面的内容忽略了。所以改16k设置为32k。再把那些调试信息删掉。重新编译,烧写,NandFlash启动:
现在问题好像有点更严重了,啥信息都没有,原来是有乱码输出的。开发板还一直在叫。
为什么单单改了一下长度:
开发板会在一直叫呢?
我们来回顾一下前面学过的东西:
如上图,在210的uboot启动的过程中,首先是先运行IROM里的BL0里的程序。BL0程序会把BL1里的程序往SRAM里复制。BL1的最大值是16k。复制进来之后,BL0会做相应的操作:
其中的一个操作是:
是去检查Checksum。
具体的过程是这样的:在BL0去把BL1里的16k程序复制到SRAM里的时候,回去统计BL1里1的个数。然后在我们的BL1里,4字节的头:
可以看到也有CheckSum,就是BL1里1的个数。当上面的两者不一致的时候,BL0就认为传递过来的映象有问题,就会产生叫声。
问题是出在:
在加头程序里,有一个for循环,就是统计加头文件里1的个数的。本来BL1的最大值是16k的,这里的IMG_SING已经被赋值为32k,所以统一1的个数不只是BL0里的1,也有BL2里的1,导致与BL0统计的1的个数不一样,所以会啸叫。这里把它改回16k
改了之后重新编译,重新加头信息:
重新下载,设置NandFlash启动:
可以看到控制台已经正常输出了。问题终于解决了。
上面就是一个解决嵌入式异常的流程,要善于用排除法,排除干扰因素等。