RISC-V MCU编译过程分析
RISC-V MCU编译过程分析
1、前言
使用MounRiver Studio(MRS)这款集成开发环境(IDE)对RISC-V MCU进行嵌入式开发时,工程师不用关注RISC-V MCU 繁杂的底层编译过程,只需用C语言编写相应的工程代码,点击build编译按钮,即可生成hex或bin目标文件,下载后即可运行。
本文将分析点击bulid按键后,.c文件是如何一步一步变为可执行的.hex或.bin文件。
2、编译过程
而将.C文件转变为最终的.hex或.bin目标文件,需要经过预处理、编译、汇编、链接这四个步骤。
建议关闭多线程编译,让整个编译过程按顺序执行。(切记及时打开,以提升编译速度)
可以通过取消MRS的简洁输出模式,Project -> Concise Build Output Mode,观察整个编译过程。
MRS默认是不保存编译过程中的.i和.s等临时文件,为了更好的分析编译的过程,可配置保存这些文件,操作如下:
2.1 预处理(Pre-Processing)
主要包括宏定义(#define),文件包含(#include),条件编译(#ifdef)三部分。
预处理期间将检查包含预处理指令的语句和宏定义,并对其进行响应和替换,并删除程序中的注释和多余空白字符,最后会生成 .i 文件。
2.2 编译(Compiling)
编译器会将预处理完的 .i 文件进行一些列的语法分析,并优化后生成对应的汇编代码,生成 .s 文件。
RISC-V MCU的工程采用GCC编译,官方工具链地址:https://github.com/riscv/riscv-gnu-toolchain。
当然,各厂家会根据自家的内核设计,修改对应的工具链以支持其特色功能,如沁恒微电子的RISC-V MCU所特有的HPE硬件压栈和VTF免表中断技术,需要在中断服务函数增加指令 __attribute__((interrupt("WCH-Interrupt-fast")))
,然后在编译时会识别并省略软件压栈的过程。
2.3 汇编(Assembling)
通过汇编器将编译器生成的 .s 汇编程序汇编为机器语言或指令,也就是可以机器可以执行的二进制程序,生成 .o 文件。
2.4 链接(Linking)
根据“*.ld”链接文件将多个目标文件(.o)和库文件(.a)输入文件链接成一个可执行输出文件(.elf)。涉及到对空间和地址的分配以及符号解析与重定位。
3、elf、hex、bin文件说明
使用MRS编译时,最终生成的可执行文件为elf、hex或bin文件,这些文件之间的联系如下:
3.1 elf文件
ELF(Executable and Linkable Format),可执行与可链接格式。
elf是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
ELF文件记录的信息更多、更复杂。主要包含以下内容:
- ELF头(ELF header) - 描述文件的主要特性:类型,CPU架构,入口地址,现有部分的大小和偏移等等;
- 程序头表(Program header table) - 列举了所有有效的段(segments)和他们的属性。 程序头表需要加载器将文件中的节加载到虚拟内存段中;
- 节头表(Section header table) - 包含对节(sections)的描述。
3.2 hex文件
HEX格式文件由Intel制定的一种十六进制标准文件格式,一种ASCII文本文件。文件的每一行都包含了 一个HEX记录。这些记录是由一些代表机器语言代码和常量的16进制数据组成的。Intel HEX文件常用来传输要存储在ROM 或者 EPROM中的程序和数据。大部分的EPROM编程器和FLASH能使用Intel HEX文件。
格式如下:
行开始 | 数据长度 | 地址 | 数据类型 | 数据 | 校验 |
---|---|---|---|---|---|
: | BB | AAAA | TT | D……D | CC |
1字节 | 2字节 | 1字节 | n字节 | 1字节 |
- :冒号,代表行开始
- BB代表Bytes,数据长度
- AAAA代码Address,表示数据这行数据的存储地址
- TT代表Type,数据类型(标识)
- 00:数据标识
- 01:文件结束标识
- 02:扩展段地址
- 03:开始段地址
- 04:线性地址
- 05:线性开始地址
- D……D代表Data,有效数据
- CC代表CheckSum,校验和
3.3 bin文件
bin是binary的缩写,即二进制文件,全是0或1的文件,最底层的可执行的机器码。只包含程序数据。bin文件的大小直接反应所占flash内存的大小。
3.4 转换关系
因为bin、hex都是只是记录数据的,但elf类型不仅记录数据还有程序描述,所以elf文件通过gcc中的objcopy可转换成hex或bin文件,hex文件也可转换成bin文件,但反之不可。
3.5 总结
bin文件最小最简单,但是安全性差,功能性差,hex包含头尾和检验,就有很好的安全性,但是文件比bin大,功能没有elf强大;elf功能多,但是文件最大。
在使用工程编译结果是,最好有bin或者hex同时具有elf文件,elf用于仿真和调试,但输出的到工厂的文件可以使用hex和bin。
posted on 2021-09-01 20:54 Wahahahehehe 阅读(2248) 评论(3) 编辑 收藏 举报