嵌入式 - ARM3

发布于:2025-09-13 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、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