前节,实现了redboot引导运行flash中的hello程序,但该程序是通过串口把srec格式的hello程序下载到内存,再烧写到flash中的。如换作bin格式程序,则会出现问题,不能成功引导运行。
为何呢?这就是本节所要介绍的内容:实现redboot引导运行bin格式的应用程序。
为何要实现redboot引导运行bin格式的程序
一方面,根据前面章节所述方法编译出hello程序后,发现srec格式程序文件比bin格式的要大很多,这是因为srec格式程序文件是一种数据文本文件,附带了很多额外的数据,而bin格式程序文件纯粹是二进制数据,是可以直接执行的指令数据。因此通过串口等方式下载到内存时,srec格式程序需要较大的内存。相反,bin格式程序需要相对较少的内存。
另一方面,我公司所实现的,redboot引导的正是bin格式程序。所以引导bin格式程序运行肯定可行。
bin格式程序引起的问题
通过串口把bin格式程序下载到内存中的命令是:
-r:表示原始数据之意,即raw单词的头个字母。不像srec格式带有加载地址等信息,load bin程序到内存必须要用这个选项。后面也必须带着-b选项,指明要load到内存的哪个位置。
load到内存后,用go或go 0x68008000或0x68008019等不可启动hello程序,并出现如下图所示的情况:
这问题查了好久,发现load到内存中的数据与编译生成的bin文件数据在某些字节数据上不一致。redboot有cksum指令,Ubuntu下也有cksum指令,它们都是POSIX的,使用相同算法,因此可用这个命令来验证数据一致性,还可通过redboot的dump指令,把内存中的数据打印出来。
为什么会出现数据不一致,我归结为redboot的load指令对二进制数据的接收处理有问题或者不支持二进制数据的下载。
压缩bin格式程序文件
为把bin格式程序load到内存并使数据一致性,对bin格式程序文件进行了压缩(使用windows下的7-zip工具按gz压缩格式压缩,取名为hello.bin.gz)。经验证,load到内存后,数据保持一致。
redboot添加解压缩功能
在ecos图形配置工具中,选择:Build->Packages…,进入Package管理界面,在左边窗口中选择Zlib compress/decompress包,点击中间的“Add”按钮,把它添加到右边界面中,如下图所示:
回到redboot配置界面,找到:CYGBLD_BUILD_REDBOOT_WITH_ZLIB配置项,对其进行配置,如下图所示(最后一项默认不打√,选择打√,redboot命令中则会有gunzip解压缩指令可用):
重新编译并烧写到stm32内部flash中。启动后可以看到redboot中有gunzip解压缩指令。而且fis load指令多了一个可用的选项:“-d”,表示读取指定flash分区的数据到内存并进行解压缩。
烧写压缩后的bin程序到flash
先通过load -r -b 0x68008000 -m xmodem 指令把hello.bin.gz下载到内存。
这时如果通过下面这条指令把内存中的hello.bin.gz数据烧写到flash中时会出现问题:
出现的问题是:Can’t program region at 0x08045000: Data verify failed after operation,如下图所示:
原因不明,但可换下面这条指令烧写进去:
如下图所示:
注:使用上面这条指令时,需事先创建好了hello分区,否则启动时会因为找不到分区而不能正常引导。
fis load的解压缩问题
fis load的解压缩似乎不是很可靠,不稳定。有时需要尝试多次才能解压缩成功,如下图所示:
会出现:decompression error: incorrect data check,原因待查证。
更新启动脚本
需要更新下原先创建的启动脚本:主要是把fis load hello,改为:fis load -d hello,其它可不用改,如下图所示(修改时,fconfig命令中,带“-i”表示重新创建启动脚本,也可直接输入fconfig进行修改):
复位或者重上电,则可以引导运行flash的hello程序了。
问题总结
总结上面,还存在2个问题需待查证和解决:
- 不能使用fis create指令把内存中压缩后的bin格式程序烧写到指定分区中;
- fis load的解压缩功能不是很稳定,有时候可以,有时候会失败;
推荐阅读相关文章:
- stm32移植ecos #12,redboot引导启动flash中的应用程序映像文件(上)
- stm32移植ecos #21,触摸屏tsc2046驱动移植
- stm32移植ecos系列文章归档
- stm32移植ecos #11,使用自己的模板(Template)
- stm32移植ecos #10,移植ecos并成功运行helloworld程序,烧写到内部flash直接运行helloworld程序
- stm32移植ecos #9,移植ecos并成功运行helloworld程序,使用redboot引导运行内存中的helloworld程序
- stm32移植ecos #8,移植ecos并成功运行helloworld程序,编译链接生成helloworld程序
- stm32移植ecos #7,移植ecos并成功运行helloworld程序,配置编译生成静态链接库文件