wahahahehehe

Tips:

1. 博客内容主要为博主的学习笔记,引用已表明出处,如有侵犯请联系我删除;

2. 如有错误请指出,万分感谢;

3. 博主邮箱:yukai_tao@163.com。

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文件。
image

2、编译过程

而将.C文件转变为最终的.hex或.bin目标文件,需要经过预处理编译汇编链接这四个步骤。

image

建议关闭多线程编译,让整个编译过程按顺序执行。(切记及时打开,以提升编译速度)

image

可以通过取消MRS的简洁输出模式,Project -> Concise Build Output Mode,观察整个编译过程。

image

MRS默认是不保存编译过程中的.i.s等临时文件,为了更好的分析编译的过程,可配置保存这些文件,操作如下:

image

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)的描述。

image

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编辑  收藏  举报

导航