玩转S19文件

本文首发于微信公众号“嵌入式软件实战派”。

这是《玩转Hex文件》的姊妹篇。
如果你还不了解S19或者SREC文件格式,请戳《SREC、Hex、Bin等烧录文件格式完全解读》

本文与其说是《玩转S19文件》,还不如说是《玩转S19、Hex、Bin文件》,因为接下来讲的神器是可以玩转S19、Hex、Bin的。下面是基于Python的BinCopy库来讲解的。

写数据

方法有很多:

add(data, overwrite=False)
add_binary(data, address=0, overwrite=False)
add_binary_file(filename, address=0, overwrite=False)
add_file(filename, overwrite=False)
add_ihex(records, overwrite=False)
add_ihex_file(filename, overwrite=False)
add_srec(records, overwrite=False)
add_srec_file(filename, overwrite=False)
add_ti_txt(lines, overwrite=False)
add_ti_txt_file(filename, overwrite=False)

使用也很简单,可以自行查找其使用手册来看看,以下挑几个来讲解下。

import bincopy
bf=bincopy.BinFile()
bf.add_binary("embedded_sw".encode(),0x00)

那么得到的内容是

00000000  65 6d 62 65 64 64 65 64  5f 73 77                 |embedded_sw     |

假设,我有另一个bin文件is_great.bin,我想加载到这个bf里面来,可以这样:

bf.add_binary_file("is_great.bin",0x10)

可得到像这样的结果:

00000000  65 6d 62 65 64 64 65 64  5f 73 77                 |embedded_sw     |
00000010  69 73 20 67 72 65 61 74  21                       |is great!       |

同样的道理,
对于intel hex内容可以用方法add_ihex(records, overwrite=False)
对于intel hex文件内容可以用方法add_ihex_file(filename, overwrite=False)
对于SREC(S19)内容可以用方法add_srec(records, overwrite=False)
对于SREC(S19)文件可以用方法add_srec_file(filename, overwrite=False)
……

读数据

读的方法有很多:

as_array(minimum_address=None, padding=None, separator=’, ')
as_binary()
as_ihex(number_of_data_bytes=32, address_length_bits=32)
as_srec(number_of_data_bytes=32, address_length_bits=32)
as_ti_txt()

就针对上面的例子,我试下这些方法

bf.as_array()
0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0x69, 0x73, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x21

把padding参数加上

bf.as_array(padding=b'x\ff')
0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x77, 0x78, 0x0c, 0x66, 0x78, 0x0c, 0x66, 0x78, 0x0c, 0x66, 0x78, 0x0c, 0x66, 0x78, 0x0c, 0x66, 0x69, 0x73, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, 0x21

从上面这个padding参数得出的结果可以看出,如果不用padding(即padding=None)的话,得出的结果是不管空白地方的,这个要注意。

bf.as_ihex()
:0B000000656D6265646465645F737782
:09001000697320677265617421B7
:00000001FF
bf.as_srec()
S31000000000656D6265646465645F73777C
S30E00000010697320677265617421B1
S5030002FA
bf.as_ti_txt()
@0000
65 6D 62 65 64 64 65 64 5F 73 77
@0010
69 73 20 67 72 65 61 74 21
q

格式转换

从上面的读数据的例子,很容易得到想要的格式内容,那么将这些格式内容保存成文档,不就是相当于格式转换了吗!

下面以ihex格式为例,其他格式类同:

with open("embedded_sw_ihex.hex", 'w') as f:
    for l in s19.as_ihex():
        f.write(l)

但这里要注意,写入的文档最后面会多一个空行,看看这个空行是否会影响你项目上用到的解析软件。当然,你可以用rstrip()删掉最后面的空行(换行符),像这样:

with open("embedded_sw_ihex.hex", 'w') as f:
    for l in s19.as_ihex().rstrip():
        f.write(l)

文件裁剪

对于一个文件,我只想其中的一部分,怎么办?可以试试以下两个方法:

crop(minimum_address, maximum_address)
exclude(minimum_address, maximum_address)

解释一下,这个crop就是保留minimum_address ~ maximum_address之间的内容;而exclude就是保留minimum_address ~ maximum_address之间的内容砍掉不要。

下面来实验下这个

bf.crop(0x00, 0x09)
bf.as_hexdump()
00000000  65 6d 62 65 64 64 65 64  5f                       |embedded_       |

数一下这个内容字节数,只有9个字节,其实是不包含最大地址maximum_address的内容的,那么这个maximum_address是什么意思呢?

我们看看官方文档的说明:

crop(minimum_address, maximum_address)
Keep given range and discard the rest.
minimum_address is the first word address to keep (including).
maximum_address is the last word address to keep (excluding).

maximum_address的内容是excluding的。也就是说crop后保留的内容是minimum_addressmaximum_address-1的内容,即[minimum_address, maximun_address)或者[minimum_address, maximun_address-1]。这个跟IntelHex库的.maxaddr()是不一样的。

同样地,接着上面的例子:

bf.exclude(0x03, 0x07)
bf.as_hexdump()
00000000  65 6d 62             64  5f                       |emb    d_       |

其他

查看文件信息,可以用info()方法

bf.info()
Data ranges:

    0x00000000 - 0x00000003 (3 bytes)
    0x00000007 - 0x00000009 (2 bytes)

segments可以查看里面的每个数据段内容

for seg in bf.segments: print(seg)
Segment(address=0, data=bytearray(b'emb'))
Segment(address=7, data=bytearray(b'd_'))

所有的segment又可以切割成很小的chunks(size=32, alignment=1)

for chunk in bf.segments.chunks(1): print(chunk)
Chunk(address=0, data=bytearray(b'e'))
Chunk(address=1, data=bytearray(b'm'))
Chunk(address=2, data=bytearray(b'b'))
Chunk(address=7, data=bytearray(b'd'))
Chunk(address=8, data=bytearray(b'_'))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值