RH850 F1L text段代码与S19文件解析

  • Post author:
  • Post category:其他


前言

我们知道写的代码中,函数、变量名在编译过后都是以地址的形式存在内存中,变量名、函数地址是具体内存地址的一个名字罢了,想个问题

  • 工程编译完成,最后烧写到mcu中都是以S19的文件格式,变量名–>map文件–>hex–>S19之间的映射关系是什么样子的?

本笔记纯理论学习,待实战检验。

环境

编译器: ghs

硬件平台:RH850

以实际工程RH850 flash驱动为例子进行讲解

目的

学习S19文件如何把代码组织起来,烧到MCU中的过程。

map文件

工程中所有变量或函数的定义都能在map文件中找到对应的物理地址。cpu执行指令时就是在这些地址上。

flash库生成的代码都在特定的段内,其中的代码都是以如下声明,将代码放入特定的段中:

#pragma ghs section text=".R_EEL_Text"

其中R_EEL_TEXT段在ld文件中有定义

.R_FDL_Text                 : > .
.R_FDL_Const                : > .
.R_EEL_Text                 : > .
.R_EEL_Const                : > .

有了这2个定义后,编译出来的代码通过MAP文件查看代码所在的物理地址:

   50   .R_FDL_Text          0009ac78  00001dce         7630   0063078
   51   .R_FDL_Const         0009ca46  00000013           19   0064e46
   52   .R_EEL_Text          0009ca5a  0000439a        17306   0064e5a
   53   .R_EEL_Const         000a0df4  00000019           25   00691f4

附加知识:

FDL是针对data flash操作的函数库。

EEL是针对eeprom操作的函数库,EEL也是基于FDL实现的。

FCL是针对code flash操作的函数库,主要用于bootloader中给系统升级

以上三个库瑞萨官方都有提供。

0x0009ac78为R_FDL_Text段的其实地址,大小为7630字节。

继续查看其实地址存放的内容:

 2863  .R_FDL_Text      0009ac78+00001a _R_FDL_Init
 2864  .R_FDL_Text      0009ac92+0000f2 _R_FDL_InitVariables
 2865  .R_FDL_Text      0009ad84+00012c _R_FDL_Execute

其实地址存放的为R_FDL_Init.

现在已经知道编译出来的代码最后存放rom中的物理地址。

那如何从hex文件或者S19文件里找出这些文件内容

S19文件

基本格式:

5个部分具体内容如下:

记录类型         记录长度         存储地址         代码/数据         校验和

记录类型:2个字符(即1个字节),用来描述记录的类型。

一共有8种类型:

S0:S格式文件的第一个记录,表示文件名(含路径),存储地址部分没有使用,以0000置位。此记录表示记录的开始,无需下载到MCU。

S1: 地址为2字节(4个字符)的记录。

S2: 地址为3字节的记录。

S3: 地址为4字节的记录。

网上有很多资料。

实际项目中截图:

S3 21   0009AC18   9F999FAB9F00BD9FCF9FE19FF39F05AF17AF29AF3BAF004DAF5FAF71   5D
S3 21   0009AC34   AF83AF95AFA7AFB9AFCBAF00DDAFEFAF01BF13BF25BF37BF49BF5BBF   E0
S3 21   0009AC50   7D015CB08CEBDEFE9073B07F474D54002020206DB0FD145CB2067F09   B8
S3 21   0009AC6C   00E8660F0900E680F86096BC8207210063E7010003E080FF10000A08   CE
S3 21   0009AC88   015023E7010042063F008207217063E7010003E006C83A06100E0A00   40
S3 21   0009ACA4   00DAF5051A30003A80FF9C1041D241DA1B06ACFF89FD2B06600E0A00   D9
S3 21   0009ACC0   6B070100000AE0C9E24D2B06100E0A006BCF01002C06340E0A006C07   8F
S3 21   0009ACDC   01002D06380E0A006D0701002E06580E0A004E0700002F06590E0A00   B5
S3 21   0009ACF8   4F07000030065A0E0A00500700003106540E0A007107000032063C0E   3F
S3 21   0009AD14   0A00520700003306100E0A0033F701007198E099C21D2B06100E0A00   6B

实际没有空格,这里为了好区分

每个格式为

类型 余下字节数(2字符一个字节) 地址 数据 校验和

S3类型 后面有33个字节。

FDL的物理地址为 0x0009ac78, 那地址空间内容应该包含在这句中:

S3 21   0009AC6C   00E8660F0900E680F86096BC8207210063E7010003E080FF10000A08 

0x0009ac78 – 0x0009ac6c = c (12) 所以9AC6C地址移动12个字节就,也就是0x0009AC78对应的内容:

8207210063E7010003E080FF10000A08

这些才是具体代码对应的二进制文内容,换言之,拿到这些就可以拿到读写删除flash了。

可以通过GHS调试工具查验上述地址上存的内容是否与这一致。

0x0009ac78地址的8个字节:

00 21 07 82 00 01 e7 63,

小端模式(高字节放在高地址)正好与上面对应,8207210063

所以从S19中,9ac78后截取7630个字节就是所有FDL 函数库的二进制文件。

这样可以单独升级使用。

在最终生成S19文件之间有个中间文件HEX,通过对应的HEX文件也可以拿到。

校验和

s19中每一样的最后2个字符(一个字节)为校验和,在发送的过程中,对端接收后可以通过校验和确保数据有没有问题

14451 S3 21   0009AC34   AF83AF95AFA7AFB9AFCBAF00DDAFEFAF01BF13BF25BF37BF49BF5BBF   E0
14452 S3 21   0009AC50   7D015CB08CEBDEFE9073B07F474D54002020206DB0FD145CB2067F09   B8
14453 S3 21   0009AC6C   00E8660F0900E680F86096BC8207210063E7010003E080FF10000A08   CE
14454 S3 21   0009AC88   015023E7010042063F008207217063E7010003E006C83A06100E0A00   40
14455 S3 21   0009ACA4   00DAF5051A30003A80FF9C1041D241DA1B06ACFF89FD2B06600E0A00   D9
14456 S3 21   0009ACC0   6B070100000AE0C9E24D2B06100E0A006BCF01002C06340E0A006C07   8F
14457 S3 21   0009ACDC   01002D06380E0A006D0701002E06580E0A004E0700002F06590E0A00   B5
14458 S3 21   0009ACF8   4F07000030065A0E0A00500700003106540E0A007107000032063C0E   3F
14459 S3 21   0009AD14   0A00520700003306100E0A0033F701007198E099C21D2B06100E0A00   6B

hecksum(校验和):2个字符。这些字符当被配对并换算成16进制数据的时候形成了一个最低有效字符节,该字符节用来表达作为补充数据,地址和数据库的字符对所代表的(字节的)补码的byte总和。即计数值、地址场和数据场的若干字符以两个字符为一对,将它们相加求和,和的溢 出部分不计,只保留最低两位字符NN,checksum =0xFF-0xNN。(引用网络)

校验和: 2个字符(即1字节),校验数据,计算方法:

校验和 = 0Xff – (记录长度 + 存储地址 + 代码/数据)

第一行为例:

校验和0xE0 = 0xFF – (21+00+09+AC+34+AF+83+AF+95+AF+A7+AF+B9+AF+CB+AF+00+DD+AF+EF+AF+01+BF+13+BF+25+BF+37+BF+49+BF+5B+BF)

校验和0x6B = 0xFF – (21+00+09+AD+14+0A+00+52+07+00+00+33+06+10+0E+0A+00+33+F7+01+00+71+98+E0+99+C2+1D+2B+06+10+0E+0A+00)



版权声明:本文为oqqGuMu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。