【发布时间】:2017-05-16 20:30:29
【问题描述】:
主要目的是将十六进制编码的字符串或仅十六进制数据写入主 bin 文件,无论是否为十六进制转储。
使用 windows powershell 或 cmd,我们正在尝试创建一个 bin 文件,以便使用开源 srecord 执行脚本(如 srec_cat.exe)将其与主文件连接起来。
我们已经设法在 powershell 中以十六进制转储了一些东西,比如字符串左右:
“hello_world”将是:
PS C:\Users\user> echo hello_world | format-hex > output.bin
那个“bin”文件的内容是:
Ruta:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 68 65 6C 6C 6F 5F 77 6F 72 6C 64 hello_world
但是,上面的输出是字符串格式的,需要将其转储为 bin 类型文件。这是因为 srecord 的 srec_cat 工具需要以这种方式将数据写入(连接)到主 bin 文件的某个内存区域,这些内存区域将被闪存到设备中。
所需的输出类似于:
00000000: 68 65 6C 6C 6F 5F 77 6F 72 6C 64 00 00 00 00 00 #hello_world
再次,作为二进制类型文件。
非常感谢您的时间和关注!
第一次编辑:
因此,我们正在使用 Atmel Studio 制作一个适用于 SAMD21 设备的程序。通过 JTAG 与 SAM ICE 一起用于闪存和调试。编译的结果,因此为调试而挂载的最终可执行文件是 *.bin 文件。编码可能是UTF-8。
我正在尝试做的是将 ID、密钥等数据添加到最终固件 *.bin 文件的特定内存方向中,以便刷新。
利用 srec 工具,完成如下操作:
第一次转化:
srec_cat data_input_file.bin -o data_input_file.srec
第二次转换:
srec_cat main_file.bin -binary -o main_file.srec
特定内存区域的concat,这个命令是通用的(没有地址目标):
srec_cat data_input_file.srec main_file.srec -o final_firmware.bin
我不知道如何使用十六进制编码字符串创建这种二进制文件,从零地址开始,直到保存数据所需的空间。
借助 srec 工具,我们能够将这些数据放入所需的方向。
二次编辑
将使用的原始字节来源有两个。
第一个是 Atmel Studio 编译的 *.bin 结果,旨在闪存到我们正在使用的硬件设备中。
文件的内容,例如,Main_File_1.bin:
00000000: 30 30 30 30 09 66 66 20 66 65 20 36 38 20 30 30 #0000.ff fe 68 00
00000010: 20 36 35 20 30 30 20 36 63 20 30 30 20 20 36 63 # 65 00 6c 00 6c
00000020: 20 30 30 20 36 66 20 30 30 20 35 66 20 30 30 20 # 00 6f 00 5f 00
00000030: 37 37 20 30 30 20 20 20 2E 2E 68 2E 65 2E 6C 2E #77 00 ..h.e.l.
00000040: 6C 2E 6F 2E 5F 2E 77 2E 0D 0A 30 30 31 30 09 36 #l.o._.w...0010.6
00000050: 66 20 30 30 20 37 32 20 30 30 20 36 63 20 30 30 #f 00 72 00 6c 00
00000060: 20 36 34 20 30 30 20 20 30 64 20 30 30 20 30 61 # 64 00 0d 00 0a
00000070: 20 30 30 20 20 20 20 20 20 20 20 20 20 20 20 20 # 00
00000080: 20 20 6F 2E 72 2E 6C 2E 64 2E 2E 2E 2E 2E 0D 0A # o.r.l.d......
同样,十六进制转储方式不是强制性的,十六进制转储用于视觉参考,我知道它可以是 Main_File_1.bin:
X" ¡@ @ @ @ @ @ @ @ @ @ e) @ @ @ @ a/ q/ / ‘/ ¡/ ±/ @ @ @ @ @ @ @ @ @ @ @ @ @ µL#x +ÑK +ÐH à ¿##p½Ø ,h µK +ÐHI à ¿Hh +ÐK + ИG½ÀF ,h Ü ,h µ K˜GLú!‰ GK`ú!‰ GK`"K`½ÀFU> E à à0µKhJ %€!Ià ,ÐT`•`hBüÐ8öÒ0½ à àµKh + ИG½ÀFô pµ‚° #J`¬%ep£p%p& !N°G% !°G' !°GK !Ya@"ZaYaZaKhBÐ
KhšÔ K˜G"Kp¿ó_b¶ °p½ô å* €D Aà à 8µ (ÐM ¨G< ,úÑ8½ÀFM µL #£a K˜G@#£a½€D A µ„°K`¬
K˜G$#“ #c`##r#ãr !K˜GH! "K˜G !K˜G°½ÀFô Y* m* y õ( %) µ (Ð !K˜Gà !K˜G½ÀF%) E) 0µ‘°.L##p #cp£p©"Jp‹p
p )K˜G#xÙ " )ÑZ Ò&H!@!˜@aªp #S`“`tSt‘tÑtu$!ST “
“€#[Ó`K“b#[BÓbKcKScK“aHIK˜G (ÑM,h K˜G#@#ƒ@K`*hÓi +üÑ"h#C#`K˜G K˜G àú @²°0½¨ å* D A €–˜ ¬
上面的内容描述只是示例信息,不是实际的字节不能写入,只是理论上下文。
就像任何设备一样,主要目标是在每个硬件设备中写入 ID、频率、数据等。
我想到了本地 windows 机器中的一组 JSON 文件,它将读取内容,以便将其写入当前连接的设备,并准备好被刷写(此时不使用保险丝)。
那么,就像Data_File_1.json:
{
'device_1_data' : {
'device_uuid' : {
'low_uuid' : '0x00000001',
'high_uuid' : '0xABCD000A'
},
'key_1' : ['0x2E', '0x34', '0x72', '0x0A', '0x45', '0x57', '0x41', '0x17', '0x07', '0x52', '0xCA', '0x4C', '0x0D', '0x7B', '0x41', '0x57'],
'module_data' : "0x387A3830",
'frequency_0' : '390200000',
'frequency_1' : '392100000',
'generator_syncword' : '0xCF'
}
}
该项目读取特定的内存地址以启动和运行,设置 ID 和工作所需的信息。因此,利用 JSON 文件保存的信息,需要将数据写入二进制文件,以便将其转换为 SREC,因此可以将其写入主二进制文件中 srecord 指定的内存地址工具。
所以它被配置为按原样读取信息。您可以注意到 JSON 包含十六进制数据,但 JSON 将数据保存为文本,因此需要将十六进制字符串视为十六进制,而整数需要转换为十六进制才能按预期适当写入已申请。
所以,就像Data_To_Be_Written_1.bin:
00000000: 01 00 CD AB 0A 00 00 00 2E 34 72 0A 45 57 41 17 #..Í«.....4r.EWA.
00000010: 07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17 #.RÊL.{AW08z8ÀúA.
00000020: A0 F8 5E 17 #ø^.
上面的数据是从 JSON 文件中获取的,所以,它是预期的,所以我们可以使用 SRecord 工具,以便将该数据写入包含项目的主二进制文件的内存地址,这将使硬件模块工作。
第三次修改(解决方案和总结):
非常感谢大家!
@AnsgarWiechers 的回答确实表明了获得预期的 *.bin 所需的条件。
如果我们以Data_File_1.json为例:
{
'device_1_data' : {
'device_uuid' : {
'low_uuid' : '0x00000001',
'high_uuid' : '0xABCD000A'
},
'key_1' : ['0x2E', '0x34', '0x72', '0x0A', '0x45', '0x57', '0x41', '0x17', '0x07', '0x52', '0xCA', '0x4C', '0x0D', '0x7B', '0x41', '0x57'],
'module_data' : "0x387A3830",
'frequency_0' : '390200000',
'frequency_1' : '392100000',
'generator_syncword' : '0xCF'
}
}
接下来我们可以在powershell中进行如下操作:
# JSON processing.
$json = Get-Content 'C:\<path to json file>\device_data.json' -Raw | ConvertFrom-Json
现在我们已经让 json 对象工作了,我们继续开始获取数据。
首先,获取 UUID。并声明要用于连接第一个字节值的字节数组。
注意这里,如果你知道这里的解决方法或最佳编程实践,那将是很棒的,我从这个开始,所以,我通过阅读和编码来得出以下内容-去。
# Process the whole UUID from the two JSON fields.
[int64] $device_uuid = [int64] ($json.device_1_data.device_uuid.low_uuid + (($json.device_1_data.device_uuid.high_uuid).split('x')[1]))
$device_uuid_byte_array = [BitConverter]::GetBytes($device_uuid)
# Final Byte array for first target address.
[byte[]] $final_byte_array = $device_uuid_byte_array
在上面,我利用了带有 int 值的 BitConverter 函数。首先用高低地址做一个String concat,可以注意到连接的顺序,因为powershell处理的字节序,所以,为了得到下面的字节顺序01 00 CD AB 0A 00 00 00,powershell需要类似"0x00000001ABCD0001" 的字符串,不喜欢 0xABCD00100000001。
然后它将值转换为整数,其结果是7177306113。并利用该功能:
[BitConverter]::getBytes(7177306113)
我们可以得到它的字节值数组。所以它可以被连接起来,或者在这种情况下,是字节数组的起始值,它将位于二进制文件的内容中。
接下来是 JSON 的键字符串字节数组的串联。
# Now process the key byte array from JSON.
[int[]] $key_1_value = [int[]] $json.device_1_data.key_1
[byte[]] $key_1_byte_array = [byte[]][int[]]$key_1_value
$final_byte_array += $key_1_byte_array
现在,可以继续使用module_data JSON 字段。
[int64] $module_data = [int64] $json.device_1_data.module_data
$module_data_byte_array = [BitConverter]::GetBytes($module_data)
$final_byte_array += $module_data_byte_array
然后是频率:
[int] $frequency_0 = [int] $json.device_1_data.frequency_0
[byte[]]$frequency_0_byte_array = [BitConverter]::getBytes($frequency_0)
$final_byte_array += $frequency_0_byte_array
[int] $frequency_1 = [int] $json.device_1_data.frequency_1
[byte[]] $frequency_1_byte_array = [BitConverter]::getBytes($frequency_1)
$final_byte_array += $frequency_1_byte_array
最后是同步词:
[int] $generator_syncword = [int] $json.device_1_data.generator_syncword
$syncword_byte_array = [BitConverter]::GetBytes($generator_syncword)
$final_byte_array += $syncword_byte_array
一旦我们在字节数组中获取并连接了所有内容,我们就可以执行管道操作来了解我们正在获取的内容。
这将是 powershell 的初步输出:
PS C:\Users\user> $final_byte_array | format-hex
Ruta:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 01 00 CD AB 01 00 00 00 2E 34 72 0A 45 57 41 17 ..Í«.....4r.EWA.
00000010 07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17 .RÊL.{AW08z8ÀúA.
00000020 A0 F8 5E 17 CF 00 00 00 ø^.Ï...
现在我们可以将该字节数组发送到扩展名为 *.bin 的文件中,但由于数据是以字节为单位写入的,因此使用 SRecord 工具的进一步步骤不会有任何问题。
# File storage
[IO.File]::WriteAllBytes('C:\<path desired to save>\input_file.bin', $final_byte_array)
一旦我们有了文件,我们就可以使用 srec_cat.exe,为了说明的目的,假设我们在 srec_cat.exe 所在的某个目录位置使用 CMD,如以及我们刚刚创建的input_file.bin。
>srec_cat input_file.bin -binary -o srec_input_file.srec
如果我们打开文件srec_input_file.srec,它将显示如下内容:
S0220000687474703A2F2F737265636F72642E736F75726365666F7267652E6E65742F1D
S12300000100CDAB010000002E34720A455741170752CA4C0D7B415730387A38C0FA4117D5
S10B0020A0F85E17CF000000F8
S5030002FA
然后,我们可以使用 hex-dump 再次对其进行转换,以查看我们是否获得了与之前在 powershell 输出中看到的相同的字节值:
>srec_cat srec_input_file.srec -o hex_input_file.bin -hex-dump
如果我们打开hex_input_file.bin,我们可以看到:
00000000: 01 00 CD AB 01 00 00 00 2E 34 72 0A 45 57 41 17 #..M+.....4r.EWA.
00000010: 07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17 #.RJL.{AW08z8@zA.
00000020: A0 F8 5E 17 CF 00 00 00 # x^.O...
我们可以使用这个文件来连接它的偏移量,假设我们打算从位置0x1A010写入它,我们这样做:
>srec_cat srec_input_file.srec -offset 0x1A010 -o srec_input_file_offset.srec
我们得到类似的东西:
S0220000687474703A2F2F737265636F72642E736F75726365666F7267652E6E65742F1D
S22401A0100100CDAB010000002E34720A455741170752CA4C0D7B415730387A38C0FA411723
S20C01A030A0F85E17CF00000046
S5030002FA
然后我们通过以下方式对其进行审核:
>srec_cat srec_input_file_offset.srec -o hex_input_file_offset.bin -hex-dump
然后打开看看:
0001A010: 01 00 CD AB 01 00 00 00 2E 34 72 0A 45 57 41 17 #..M+.....4r.EWA.
0001A020: 07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17 #.RJL.{AW08z8@zA.
0001A030: A0 F8 5E 17 CF 00 00 00 # x^.O...
之后,我们用0xFF 填充srec_input_file_offset.srec 的空字节:
>srec_cat.exe srec_input_file_offset.srec -fill 0xFF 0x0001A030 0x0001A040 -output final_srec_input_file.srec
最后,只将final_srec_input_file.srec 附加到主 bin 文件的 srec 中。
假设我们没有转换main_file.bin:
>srec_cat main_file.bin -binary -o main_file.srec
然后我们把所有东西放在一起:
>srec_cat main_file.srec srec_input_file_offset.srec -o final_file.bin -binary
就是这样。再次感谢一切。非常欢迎反馈和建议。
亲切的问候。
【问题讨论】:
-
你认为什么是“二进制文件”?请退后一步,描述您要解决的实际问题,而不是您认为的解决方案。你需要这个做什么?
-
我需要它来将一些密钥、ID 和一些数据写入最终的 *.bin 文件,该文件旨在闪存到硬件设备中。我将二进制类型文件视为 srecord 工具可以使用的 *.bin 文件。
-
只是文本还是不可打印的字符?哪种编码?数据结构如何?
-
您需要了解设备的内存布局。就像为 intel cpu 烧写 spi flash rom 一样,您需要知道闪存映射。例如,可能 4kbytes 映射到 0xfffffff0。所以你写到那个偏移量。这只是内存映射。我也认为 windows .bin 与该格式无关。想想一个例子是固件的.spi。 github.com/espressif/esptool/wiki/Firmware-Image-Format 然后有图像以闪存程序员期望的无序方式格式化数据。
-
除非您指定“二进制”输入文件应该具有的格式/结构,否则任何人都不太可能为您提供帮助。
标签: powershell cmd hex bin