需求背景
IAR导出和载入内存支持 motorola
格式和 intel-extended
格式:
其中 motorola
格式以16进制表示,在输出文件中可以直接看到内存地址信息,并且文本长度比 intel-extended
格式更短。
所以我这里以 motorola
格式为基础,用Python开发hex和bin文件之间的转换程序。
解析文件
打开一个IAR工程,从 0x0C8A4FE4
地址处开始截取一段内存,保存为 motorola.hex
。
得到的内容为:
S0030000FC
S3150C8A4FE401800011FBFFFFFEFFFFBFFF0002008159
S3150C8A4FF416210010BBFFFFFFFFFFBEFFC90000216D
S3150C8A500410000000FEFFFFFFFF7FFBFF000000007D
S3150C8A501440000000FFFFFFFBFDFF7FFE48100010D7
S3150C8A502410088210FFFBFFF9FFFFFFFD84000001C5
S3060C8A5034944B
S70500000000FA
参考motorola-s19格式标准:
整理一下按空格隔开,分为 命令
、长度
、地址
、数据
、校验位
这几个部分:
S0 03 0000 FC
S3 15 0C8A4FE4 01800011FBFFFFFEFFFFBFFF00020081 59
S3 15 0C8A4FF4 16210010BBFFFFFFFFFFBEFFC9000021 6D
S3 15 0C8A5004 10000000FEFFFFFFFF7FFBFF00000000 7D
S3 15 0C8A5014 40000000FFFFFFFBFDFF7FFE48100010 D7
S3 15 0C8A5024 10088210FFFBFFF9FFFFFFFD84000001 C5
S3 06 0C8A5034 94 4B
S7 05 00000000 FA
其中 校验位
必须要计算正确,不然是传不上去的,我已经试过了。
转换程序
由于快速开发的需求日益增多,我决定广泛使用自己开发的 lsx
库作为编程基础,而不仅仅再只使用内建库。
该库大小仅为24KB,不额外依赖第三方库,支持多种平台、支持3.4以上的Python版本,非常方便携带。
安装 lsx
库的方法:
pip install lsx -U
最后的程序、和测试例子:
import lsx
import struct
import binascii
def hex2bin(path):
assert '.hex' == lsx.ext(path), lsx.ext(path)
text = lsx.read(path)
lines = text.splitlines()
lines = [line[12:-2] for line in lines[1:-1]]
data = binascii.a2b_hex(''.join(lines))
lsx.write(lsx.p12(path, '.bin'), data)
def bin2hex(path, addr=0):
assert '.bin' == lsx.ext(path), lsx.ext(path)
lines = ['S0030000FC']
data = lsx.readb(path)
for block in lsx.split(data, 16):
block = struct.pack('>i', addr) + block
block = struct.pack('>b', len(block) + 1) + block
block = block + bytes([0xFF - (sum(block) & 0xFF)])
line = 'S3' + binascii.b2a_hex(block).upper().decode()
lines.append(line)
addr += 16
lines.append('S70500000000FA')
lsx.write(lsx.p12(path, '.out.hex'), lines)
if __name__ == '__main__':
hex2bin('motorola.hex')
bin2hex('motorola.bin', 0x0C8A5000)