当前位置: 首页 > news >正文

【AS32X601驱动系列教程】MCU启动详解

在嵌入式开发领域,掌握MCU(微控制单元)的启动流程是工程师们迈向深入开发的关键一步。本文将带您深入了解MCU启动的奥秘,从编译过程到启动文件,再到链接脚本和系统时钟配置,全方位解析MCU启动流程。

在实际编程开发之前,我们首先对芯片的启动流程进行一下介绍,对于绝大多数嵌入式工程师而言,在MCU开发过程中,通常只需要完成C语言代码功能,即可利用集成开发环境编译出来芯片的可执行文件,但在此过程中,编译器进行了一系列编译操作来保证MCU可以支持C程序的运行,因此,实际的完整工程代码中,总共包含了三类文件:汇编文件、C程序代码以及链接脚本。

首先,需要明确概念,程序的编译整体包含预处理、编译、汇编、链接四个步骤。经过这四个过程之后,编译器产生MCU可识别的可执行文件,在编译的过程中,上述所提供的汇编指令代码文件同样被编译,同时依照链接脚本所提供的规则,穿插到 C 语言功能代码之间,如图所示:

在此过程中,芯片厂商会提供基础的链接文件和启动文件,以便集成开发工程管理。一般来说,芯片的启动文件需要使用汇编指令编程,用于完成上电到用户程序之前的启动操作。链接脚本则需要根据不同的编译工具链解析要求进行编写。

启动文件介绍

以AS32x601启动文件为例进行具体流程介绍,为了便于理解,将启动流程划分为三个阶段:第一阶段为系统启动必备阶段,此阶段主要完成指针初始化操作,配置全局指针GP以及栈指针SP;第二阶段为数据搬移阶段,此过程主要完成两部分操作,搬移data段数据到 RAM,清空 bss 数据段;第三阶段与平台相关,主要完成的中断配置,系统时钟初始化等,此阶段需要根据不同MCU设计自行完成,属于非必需过程。

代码详解

随便打开一个demo的IAR工程,找到如下文件双击打开:

该文件即为AS32x601的启动文件,全部由汇编指令编写,为方便讲解,截取其中有效代码如下:

定义地址段

首先,第18行开始,利用SECTION `.init`:CODE指令定义.init段,声明以下内容均包含在init段中,接下来定义全局标签_start,声明此全局标签后,链接文件中即可分配.init段地址来指定_start为处理器上电执行的第一个操作,经过以上两个步骤,即可保证此部分内容先于所有指令,从而完成上电配置。

配置全局指针GP

第40行,通过la命令,将__iar_static_base$$GPREL写入寄存器gp。

其中,__iar_static_base$$GPREL是由IAR提供的全局指针初始值,编译器会合理分配。此处需要注意,通常情况下,gp 指针定义在 data 区,有时候为了优化代码密度,可以根据实际情况修改 gp 指针的位置,如工程中定义了大量的初始化为 0 或未初始化的全局数组作为缓冲区,可以将gp指针的位置定义到bss段。

配置栈指针SP

第41行,通过la命令,将CSTACK$$Limit写入寄存器sp。

其中,_sp 是由链接脚本提供的栈指针位置,开发者应根据数据存储器大小和程序调用层次合理分配,栈指针必须保持 4 字节对齐,否则会发生加载/存储对齐错误。

加载data段

第44-54行,将data段从程序存储器搬运至数据存储器,作为可读可写的变量。

第44-46行,向寄存器a0、a1、a2加载必要数据,地址由链接脚本生成:

第47行,如果a1大于等于a2,表示没有需要搬运的数据,跳过以下循环,执行下面的工作。

第48-53 行,是一个循环结构。读出a0 指向的地址,数据写入t0 暂存。t0的数据写入 a1 指向的地址。a0+4,指向下一存储单元,因为 32bit 是4 字节。a1+4,指向下一存储单元,因为 32bit是4 字节。如果 a1 小于 a2,表示未搬运完,跳转至 49 行,进入下一次循环。如果a1等于a2,表示已经搬完了最后一个数据,退出循环,执行下面的工作。

需要说明的是,程序正常运行,还需要链接脚本的配合,对于启动文件来说,链接脚本除定义上电入口函数外,还对数据搬移过程产生影响,对于自定义的启动地址_start,则需要在链接文件中定义initialize manually,才可以在启动文件中实现数据的搬运。

清空bss段

第57-68 行,工作与data段有点类似,但是只需要清空指定位置的数据。

第57-58 行,向寄存器a0、a1加载必要数据,地址由链接脚本生成:

第59行,如果a0大于等于a1,表示没有需要清0的空间,跳过以下循环,执行下面的工作。

第61-63 行,是一个循环结构。清空a0指向的地址a0+4,指向 下一存储单元,因为32bit是4字节。如果a0小于a1,表示清0未 结束,跳转至32行,进入下一次循环。如果a0等于a1,表示已经清 0 了最后一个存储单元,退出循环,执行下面的工作。

中断初始化

从64行开始,启动文件进入流程第三阶段,配置中断,该过程主要操作RISC-V内核的中断寄存器。

mstatus:Machine Status Register,RISC-V架构中的一个重要控制和状态寄存器,管理和反映机器模式下的状态和控制信息。

mstatus.MIE:Machine Interrupt Enable,机器模式全局中断使能位

mstatus.MPIE:Machine Previous Interrupt Enable,机器模式先前中断使能位

mstatus.MPP:Machine Previous Privilege,机器模式之前的特权级别

mstatus.SPP:Supervisor Previous Privilege,超级模式之前的特权级别

第66-68行,设置mstatus寄存器,开启CPU全局中断;

MEIE:M模式外部中断使能位

SEIE:S模式外部中断使能位

MTIE:M模式timer中断使能位

STIE:S模式timer中断使能位

MSIE:M模式软中断使能位

SSIE:S模式软中断使能位

第71-73行,配置MIE寄存器,开启外部中断;

Direct模式:所有的中断和异常使用同一个中断入口地址,一般都会设置为这种模式。

Vectored模式:所有异常使用同一个入口地址,但是不同的中断使用不同的入口地址。

第76-77行,使用Direct模式,设置中断向量表入口地址TrapEntry,再由as32x601_trapentry.S找到PLIC_TrapHandler。

链接配置文件说明

AS32x601芯片提供了最大2MB的P-Flash和512kb的D-flash及512kb的SRAM。链接配置文件(.icf)作用等同于GCC工具链下的链接文件(.ld),用来描述系统内存分区,定义内存大小,分配数据段存储位置,设置堆栈等,以本芯片为例,编写如下:

第10行,保留符号__iar_cstart_init_gp,该符号在启动代码cstartup.s定义,保留符号意味着即使它未被直接引用,也不会被链接器优化掉。

第12行,定义总体内存空间,包含数据存储区,程序存储区,最大为4G,可直接设置为最大,不影响实际效果;

第14-15行,定义RAM、ROM区间地址以及大小;

第17行,手动初始化.data段。这意味着.data段的内容需要在程序启动时从其他位置(如ROM)复制到RAM中;

第18行,不对以.noinit结尾的段进行初始化。这些段的内容在程序启动时保持不变;

第20-21行,定义堆栈大小以及对齐方式,此处CSTACK_SIZE和HEAP_SIZE代表此处大小由iar软件获取,也可直接进行固定设置,单位为字节;

第23-29行,定义了RW_DATA、RW_DATA_INIT、RW_BSS和RW_DATA_ALL,可供启动文件调用;

第30行,将只读的初始化代码段.init放置在ROM_region32的起始位置。这个段包含启动代码,负责初始化程序的运行环境;

第30行,将只读段(包括代码和常量数据)以及RW_DATA_INIT块放置在ROM_region32中。这意味着初始化数据将与代码一起存储在ROM中。

第31行,将RW_DATA_ALL块(包含.data和.bss段)、HEAP块和CSTACK块放置在RAM_region32中。这确保了可读写数据、堆和栈在RAM中进行操作,以实现快速访问和修改。

相关文章:

  • java接口自动化初识
  • 在 Azure OpenAI 上使用 Elastic 优化支出和内容审核
  • OpenCV 图像色彩空间转换
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Rotating Navigation (旋转导航)
  • 在 Win 10 上,Tcl/Tk 脚本2个示例
  • ubuntu kubeasz 部署高可用k8s 集群
  • 电磁感应在量子计算中如何应用
  • day018-磁盘管理-案例
  • Babylon.js学习之路《六、材质与纹理:为模型赋予真实的表面效果》
  • 医疗影像中,DICOM点云、三角面片实体混合渲染(VR)
  • Oracle中如何解决FREE BUFFER WAITS
  • Oracle基础知识
  • Redis哨兵(Sentinel)模式详解:构建高可用Redis架构
  • 【c# 中 == 和jave 的== 区别】
  • 数据库与存储安全
  • 演示:【WPF-WinCC3D】 3D工业组态监控平台源代码
  • 深入理解Redis Cluster:架构、原理与实践
  • 【latex】文本颜色修改
  • 解决 Incorrect username or password (access token)
  • 系统架构设计(十七):微服务数据一致性和高可用策略
  • 赣州蓉江新区党工委原书记王凌主动交代问题,正接受审查调查
  • 巴西商业农场首次确诊高致病性禽流感,中国欧盟暂停进口巴西禽肉产品
  • 山西资深公益人士孙超因突发急病离世,终年37岁
  • 电子凭证会计数据标准推广至全国
  • 苏丹港持续遭无人机袭击,外交部:呼吁各方保护民用设施和平民安全
  • 习近平:坚持科学决策民主决策依法决策,高质量完成“十五五”规划编制工作