目录
本文主要介绍hex6x工具的使用和实现“.out”文件转“.hex”,参考文档为:
hex6x工具的使用
C6000 Compiler提供了一个“.out”文件转“.hex”文件的工具“hex6x.exe”,在编译器的安装目录下。我的是:
C:\ti\ccs620\ccsv6\tools\compiler\c6000_7.4.18\bin
我把这个路径添加到了PATH环境变量,方便调用hex6x.exe这个工具。
使用这个工具也需要一个命令文件,用于存放一些配置选项,这个和之前的链接脚本类似,后缀名也是“.cmd”,一不小心就容易和链接cmd文件搞混。所以这个文件不能放在工程目录下,不然会被编译器当作链接脚本文件拿去用,导致编译出错。我就把这个命令文件放在和“.out”文件同一目录,命名为“hexutil.cmd”。
在命令行中调用hex6x.exe工具,即可生成“工程名.hex”文件
hex6x.exe .\hexutil.cmd
我的需要固化的工程名是Blink,就是一个闪灯的简单的程序,所以输出文件是Blink.out,hexutil.cmd的具体内容为:
Blink.out
--ascii
--image
--fill=0xFFFFFFFF
--boot
--bootorg=0xB0000400
--bootsection .boot_load 0xB0000000
--map=hex.map
--memwidth=8
--order=L
--outfile=Blink.hex
ROMS
{
FLASH: org = 0xB0000000, len = 0x10000, romwidth = 8
}
这个工具的用法在SPRU186W的第11章有非常详细的介绍。它有很多选项,还有ROMS命令和SECTION命令,功能挺强大的。
image选项
“- -image”选项要配合ROMS命令使用,就是它直接给出一整块存储器中每个字节的值。因为有时候不同的section之间是不连续的,这种不连续的section对于某些只支持连续地址写入的存储器来说可能就不是很友好。
所以配合“–fill”选项,可以在一些不连续的section之间填充常值,得到一整块存储器的数据,便于后续写入。
这里对于我来说其实我所谓,不用“–image”选项也可以,因为我的boot table是一整块的,然后EMIF逐个字节向Flash写入。其实不用也有好处,就是可以少写入一些冗余的数据;但是在逐字节写入的过程中可能会在写了一块区域之后跳转到新的地址继续写,控制起来比较麻烦,而如果是image的话就无脑地址自增就好了,各有利弊吧。
存储器宽度
memwidth和romwidth选项也是一定要设置的。memwidth相当于是存储器数据总线的宽度,romwidth就是具体的每个ROM的宽度,因为有时候可能会有多个存储器共享地址总线,然后数据总线位宽扩展。这里如果有多个存储器,就会生成多个hex文件。C6455只支持8bit位宽的存储器用于启动,所以这里这两个选项都设置为8。
Boot Table
有三个boot table相关的选项,“–boot”、“–bootsection”和“–bootorg”,在11.10.3中有详细的介绍,建议仔细阅读。
“–boot”选项是将所有的section都转化为boot table,但是我们的启动代码不能转化成boot table,它是需要一开始就执行的,所以需要用“–bootsection”选项把它排除在外,用“–bootorg”选项指定boot table的起始地址。
其它选项
“–map”选项可以输出一个“.map”文件,相当于是一个最后的结果报告,便于用户核对配置的结果。
“–order=L”指定以小端模式输出;
“–ascii”选项指定输出文件格式为ASCII-Hex;
hex文件转C源码
先简单介绍一下往Flash固化程序的机制,就是我们通过仿真器先把待烧录的程序以数据的形式放到L2上,然后将这部分数据写入Flash就实现了程序的固化。因此我们需要将以上生成的Hex文件再转成C语言常量的形式,便于将它用到后续的烧录程序中。
我是用python脚本做了一下转换,代码如下:
import math
cnt = 0
# output file name
fp_dst = open('code.h', 'w')
# input file name
fp_src = open('Blink.hex', 'r')
fp_dst.write('#include <tistdtypes.h>\n')
fp_dst.write('#pragma DATA_SECTION(code, ".data");\n')
fp_dst.write('const Uint8 code[] = {\n ')
fp_src.readline()
fp_src.readline()
line = fp_src.readline()
fp_dst.write('0x' + line[0:2])
cnt = cnt + 1
for i in range(23):
fp_dst.write(', 0x' + line[(i + 1) * 3:(i + 2) * 3 - 1])
cnt = cnt + 1
fp_dst.write('\n ')
line = fp_src.readline()
while len(line) > 2:
for i in range(math.floor(len(line)/3)):
fp_dst.write(', 0x' + line[i * 3:(i + 1) * 3 - 1])
cnt = cnt + 1
fp_dst.write('\n ')
line = fp_src.readline()
fp_dst.write('};\n')
print('total count', cnt)
fp_dst.close
fp_src.close
我把这个python脚本就放在和hex文件相同的路径下,运行后就能够生成一个“code.h”文件,里面有一个名为code的Uint8类型的数组,数组维度也会在脚本运行完之后打印输出。这个“code.h”文件就可以直接用到后续的烧录中。