前面只使用了汇编代码来驱动LED,但是对于后续一些比较复杂的逻辑,使用汇编代码编写驱动的难度太大,因此,这次我们要使用C语言代码来驱动LED。
除了C代码外,依然需要编写汇编代码,在没有OS的情况下,环境的初始化是需要通过汇编代码来完成的。
- 汇编文件:用于完成C代码的环境搭建
- C文件:实现驱动逻辑
目录
一、start.s 汇编文件
1、编写思路
这里的汇编代码仅用于C代码的环境搭建,初始化环境的方式和 stm32 类似,这里我们可以先参考stm32 的初始化步骤:
- 设置栈大小
- 初始化SP指针
- 设置堆大小
- 中断复位
- 其他初始化(如DDR初始化)
- 跳转到 main 函数
但是对于 I.MX6U 而言,无需这么复杂,也不需要进行DDR的初始化,因为在 bin 文件的头部信息中,DCD部分已经初始化了DDR。基本步骤如下:
- 设置为 SVC 模式
- 初始化 SP 指针
- 跳转到 main 函数
2、具体实现
切换 SVC 模式
切换到SVC模式要用到控制寄存器 CPSR,其中控制模式切换的是第 4-0 bit。因此,切换到 SVC 模式的步骤如下:
- 取出 cpsr 寄存器中的值,保存到 r0。(目的是防止因为误操作而改变 cpsr 其他位的值)
- r0 寄存器将低五位清零。(低五位用于控制模式切换)
- r0 的低五位或上 10011(0x13)
- 将修改以后的值写入到 cpsr

| 工作模式 | 取值(左边高位,右边低位) |
| User | 10000 |
| FIQ | 10001 |
| IRQ | 10010 |
| SVC | 10011 |
| Abort | 10111 |
| Undef | 11011 |
| System | 11111 |
| Monitor | 10110 |
/* CPSR 比较特殊,不能使用mov或者ldr访问 */
/* 必须使用 mrs指令访问 */
mrs r0, cpsr @ 将 cpsr 寄存器的内容读取到 r0 寄存器
bic r0, r0, #0x1f @ 将 r0 的低五位清零,运算结果放到 r0
orr r0, r0, #0x13 @ 让 r0 的低五位或上 10011(0x13),结果保存到 r0
msr cpsr, r0 @ 将 r0 的值写入到 cpsr 寄存器
参考链接:

本文详细介绍了如何使用C语言和少量汇编代码来驱动LED,首先阐述了start.s汇编文件的编写思路和具体实现,包括切换到SVC模式和初始化SP指针。接着讨论了头文件register.h中如何定义寄存器地址的宏以提高可读性。然后在led.c文件中展示了C语言实现的LED驱动逻辑,包括时钟使能、IO复用、GPIO配置以及延时函数。最后提到了Makefile文件的更新,以适应包含C和汇编源文件的编译需求。
最低0.47元/天 解锁文章
1020

被折叠的 条评论
为什么被折叠?



