我正在使用 avr-gcc 来生成 elf 文件以及稍后
avr-objcopy -O ihex -R .eeprom main.elf main.hex
创建用于编程的十六进制文件。如何从生成的十六进制文件中提取所有字符串?我试过了
avr-objdump -j .sec1 -D -m avr5 main.hex
但是这并没有显示任何字符串。
背景:.hex 文件存储在没有 .elf 的单独介质上,我想在使用 avrdude 编程之前检查版本字符串
假设日期是像“Sep 10 2020”这样的字符串,您可以通过将数据字节解释为字符流,选择该流中的可打印字符串(由 NUL 字节分隔)并将它们与您选择的日期格式。下面是 awk 可执行脚本,如果使用 -vout=date 选项调用,则执行此操作,否则执行其他有用的操作
#!/bin/awk -f
# dump Intel hex format https://en.wikipedia.org/wiki/Intel_HEX
# several output formats are possible
# normal is the default hexdump style
# date attempts to extract a single date encoded in the binary
# string/ascii display nonempty strings of printable/ascii characters
# size returns the total number of DAT bytes (code)
BEGIN {
types[0]="DAT" # Data
types[1]="EOF" # End Of File
types[2]="ESA" # Extended Segment Address
types[3]="SSA" # Start Segment Address
types[4]="ELA" # Extended Linear Address
types[5]="SLA" # Start Linear Address
if(!length(out))
out="normal"; # output format (string,ascii,normal,date,size)
if(!length(dateform))
dateform="(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]+ [0-9]+"
maxbytes=255 # avoid long strings
pcnt=nl=0;
size=0;
}
{
sub(/^.*:/,""); # remove the start code byte(s) of the record
sub(/\r$/,""); # remove the CR at the end (if terminated by CR+LF)
patsplit($0,s,"[[:xdigit:]]{2}");
bytes=s[1]; # byte count
if(length(s)-5 != strtonum("0x" bytes))
printf("BYTE COUNT ERROR %i for record " NR " with %s %s bytes and full length of %i bytes\n",
length(s)-5,strtonum("0x" bytes),type,length(s)) > "/dev/stderr";
address=s[2] s[3]; # memory location
type=types[strtonum("0x" s[4])]; # meaning of the data field
csum=s[length(s)]; # checksum byte at the end
c=0; # check record validity
for (i = 1; i <= length(s); i++) {
# printf("%02x+%s=", c,s[i]);
c+=strtonum("0x" s[i]);
c=and(c,0xFF);
}
if(c)
printf("CHECKSUM ERROR %02x for record " NR " with %s %s bytes and checksum %s\n",
c,strtonum("0x" bytes),type,csum) > "/dev/stderr";
sub(/^[[:xdigit:]]{8}/,""); # remove byte count, address, and type bytes
sub(/[[:xdigit:]]{2}$/,""); # remove the checksum endbyte
if(length(s)-5 != length($0)/2)
printf("LENGTH ERROR %i for record " NR " with %s %s bytes and full length of %i bytes\n",
length(s)-5,strtonum("0x" bytes),type,length($0)) > "/dev/stderr";
switch (out) {
case "date":
if(NR==1) d="";
for (i = 5; i < length(s); i++) {
if(length(p)>=maxbytes) p=""; # truncate long strings
p=sprintf("%c",strtonum("0x" s[i]));
if(p~/[\x00-\x7F]/ && p~/[[:print:]]/) d=d p;
if(p=="\0") {
# /(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]+ [0-9]+/
if(length(d) && match(d,dateform)) {
printf("%s\n",d);
exit; # assuming there's only one date ...
}
d="";
}
}
break;
case "ascii":
for (i = 5; i < length(s); i++) {
p=sprintf("%c",strtonum("0x" s[i]));
if(p~/[\x00-\x7F]/ && p~/[[:print:]]/) {printf("%s",p); pcnt++};
if(p=="\0") {
if(pcnt) printf("\n"); nl++; pcnt=0;
}
}
break;
case "string":
for (i = 5; i < length(s); i++) {
p=sprintf("%c",strtonum("0x" s[i]));
if(p~/[[:print:]]/) {printf("%s",p); pcnt++};
if(p=="\0") {
if(pcnt) printf("\n"); nl++; pcnt=0;
}
}
break;
case "normal":
default:
printf("%s %s %s %s %s ", address, bytes, type, $0, csum);
for (i = 5; i < length(s); i++) {
p=sprintf("%c",strtonum("0x" s[i]));
printf("%s",p~/[[:print:]]/?p:".");
}
printf("\n");
case "size":
if(type==types[0]) size+=bytes;
}
}
END{
switch (out) {
case "size":
printf("%i\n",size);
break;
case "normal":
printf("%i data bytes\n",size);
default:
}
}