嵌入式 - ARM3
一、arm启动C语言
1. 配置异常向量表
2. 实现了软件中断的部分
注:
ldmfd sp!, {r0-r12, lr} == ldmfd sp!, {r0-r12, pc}^
bx lr
左半部分:
繁琐易理解的返回方式:
先弹出所有通用寄存器和lr => 再用bx lr指令返回
右半部分:
高效简洁的返回方式:
一句指令实现回复所有通用寄存器(r0-r12),将保存的lr直接弹入pc实现返回跳转(pc),恢复了中断发生时的处理器状态(^ 实现 程序状态寄存器cpsr 的恢复)
软件中断需要:
主函数中调用软中断 => 触发函数接口 => 执行软中断处理 => 返回主函数
3. 配置start与main.c的链接
异常向量表设置0x00 为复位,直接进入start部分
分段解析
1. 初始化supervisor模式栈
ldr sp, =0x40001000 // 初始化栈指针,复位后默认为supervisor模式
在进入主函数操作前,需要对当前默认的supervisor模式设置一个有效的栈空间,确保能够进行函数调用和临时数据存储
通过ldr命令将预先分配的地址(0x40001000)存入到栈指针
2. 声明主函数
import main // 声明主函数
告知汇编器,符号main是在C语言文件中定义的,定义后可以调用
3. 切换至user模式
1. mrs,msr
手册496
mrs r0, cpsr // 将当前状态寄存器备份到r0中msr cpsr_c, r0 // 改写后的值写回cpsr的控制域,完成模式切换
mrs指令将整个cpsr的值备份到r0中
MRS{cond} <Rd>, <PSR>
mrs <目标寄存器>, <CPSR / SPSR>
msr指令将修改后的值写回cpsr,完成CPU切换到user模式
MSR{cond} <PSR>_<fields>, <Rm>
msr <CPSR / SPSR>_修改的部分, 源寄存器
<fields>:c:控制域,低8位包含模式位和中断使能位
x:扩展域
s:状态域,条件标志位NZCV
f:标志域,条件标志位NZCV
2. 工作模式配置
bic r0, r0, #(0x1F << 0) // 更改arm工作模式,手册Label - ARM processor // 低五位清零,准备更改模式
orr r0, r0, #(0x10 << 0) // 更改工作模式为10000,为user模式
arm工作模式:手册Label - ARM processor
3. 响应中断配置
bic r0, r0, #(1 << 7)
清除I位,确保在user模式下开启IRQ中断,否则user模式无法响应中断
4. 初始化user模式下的栈指针
ldr sp, =0x40001000 // 初始化user模式下的栈指针
sub sp, sp, #1024 // 与spv模式的栈相隔一段距离
为即将运行的主函数设置独立的栈空间
先与superviosr模式设置成同一个地址,在此基础上位移一段字节防止相互覆盖
5. 跳转并调用执行main函数
b main // 执行主函数
4. 配置main.c
1. 主函数内容
目前只实现完成软中断的跳转
2. 软中断处理
可通过 .s 的软中断跳转到软中断处理函数部分并成功返回
3. 函数声明
除了主函数与软中断处理函数的声明外,还需声明在 .s 文件中的软中断触发响应部分
5. 魔术棒设置
Target:设置ROM1地址
Linker:勾选使用设置的地址 “Use Memory Layout from Target Dialog”
Debug :取消勾选 “run to main()” ,使运行时从.s开始
二、安装环境
1. visual studio code
ARM插件:Chinese(Simplified)
Arm Assembly
C语言插件:Back & Forth
C / C++
C / C++ Extension Pack
C / C++ Themes
CMake
CMake Tools
highlight - words
Makefile Tools
2. Ubuntu下的编译器
确认版本 arm-linux-gnueabihf-gcc -v
3. filezilla上传文件
上传步骤:文件 => 站点管理器 => 新站点
右侧win本地站点,左侧Ubuntu远程站点,选择对应文件夹,右键点击上传文件夹上传
复习
1、arm汇编调用c语言函数以及c语言函数调用汇编编写的函数,函数的参数和返回值如何处理?
1. 汇编调用C语言
1. 参数:
前四个参数通过寄存器r0,r1, r2,r3传递
后续参数通过栈传递,通过压栈出栈实现传参
2. 返回值:
通过寄存器r0返回
2. C语言调用汇编
1. 参数
调用规则与 汇编调用C语言一致
2. 返回值
汇编函数直接读取寄存器或栈位置
需保存被调用的寄存器(r0-r12,lr)否则会破坏原状态
2、arm内核中有几种异常,分别是什么,会使内核切换到那种工作模式
异常中断 | 含义 | 工作模式 |
reset | 复位中断 | supervisor |
undefined | 未定义指令 | undifined |
sortware | 软件中断 | supervisor |
prefetch | 指令预取中止 | abort |
data | 数据访问中止 | abort |
IRQ | 外部普通中断请求 | IRQ |
FIQ | 外部快速中断请求 | FIQ |