0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言驱动实现

汽车电子技术 来源:程序猿搬砖 作者:程序猿搬砖 2023-03-02 16:28 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

ARM Coretex-A的不同模式

为了尽可能的保护计算机资源(CPU、内存、IO等),不同的CPU架构实现了不同的权限等级,等级越高可访问的系统资源越多(包括执行一些特权指令),这是因为普通用户级别的程序代码质量不能得到完全的保障,为了更好的保护计算机资源会让用户级别的代码工作在尽可能少的访问系统资源的模式下,而像操作系统这样经过千锤百炼的程序质量有保障,CPU可以放心的把计算机资源交出来让操作系统可以随意访问。

在当前的实验中,由于我们是工作在祼机状态下的程序,可以简单的认为我们的代码与操作系统代码是一个级别的,就算代码有问题那从CPU的角度来讲我们的祼机代码也是高质量的,也就是说可以工作在高等级权限的模式下。

ARM Coretex-A系列处理器有以下几种工作模式:图片其中,SVC是超级管理员模式,可以访问所有的计算机资源。

设置CPU工作模式为SVC

Coretex-A提供了一个专门的寄存器CPSR程序状态寄存器来控制当前CPU的工作模式, CPSR的每一位的逻辑如下:图片

其中的低5位M[4:0]用于指定当前CPU的工作模式,具体表格如下:

M[4:0] CPU工作模式
10000 User模式
10001 FIQ模式
10010 IRQ模式
10011 Supervisor(SVC)模式
10110 Monitor(MON)模式
10111 Abort(ABT)模式
11010 Hyp(HYP)模式
11011 Undef(UND)模式
11111 System(SYS)模式

通过表格可以看出,如果要设置成SVC模式,则需要将CPSR寄存器的低5位M[4:0]设置成10011

读写CRSR寄存的操作指令与读取通用寄存器使用的ldrstr不要样,需要使用mrs读取CPSR的数据,msrCPSR写入数据。

/// 将cpsr寄存器中的数据读取到r0
/// 这是因为cpsr是不能使用运算符指令对其进行直接的操作的,需要使用通用寄存器
mrs r0, cpsr
/// 通过使用bic指令将,r0的低5位都清空,这里使用了0x1f=11111. bic指令后面的操作数掩码位的值是1表示将此位清空,否则保持不变
bic r0, r0, #0x1f
/// 通过orr(或)指令将r0寄存器中的低5位设置成10011
orr r0, r0, #0x13
/// 将r0的数据写入cprs寄存器,完成svc模式切换
msr cprs, r0

设置C语言运行环境

C语言要工作,需要指定一个栈空间,通过指定sp指针就可以给C语言开辟一块栈空间。

Coretex-A的栈是向下生长的,也就是从高地址向低地址生成(即栈顶在高地址)。I.MX6ULLDDR的起始地址是0x80000000,这里设置一个2MB的空间大小,实际上也可以设置成1MB或者512KB也是完全够用的。所以需要设置sp指针的初始位置是0x802000000.

/// 设置sp指针地址
ldr sp, =0x80200000
/// 跳转到c语言的main函数开始执行
b main

编写C语言LED驱动程序

  • 1.使能CCM_CCGR1
#define CCM_CCGR1 *((volatile unsigned int *)0x020C406C)
CCM_CCGR1 = 0xFFFFFFFF;
  • 2.复用SW_MUX_CTL_PAD_GPIO1_IO03为GPIO1_IO03
#define MUX_CTL_PAD_GPIO1_IO03 *((volatile unsigned int *)0x020E0068)
MUX_CTL_PAD_GPIO1_IO03 = 0x5; /// 10011
  • 3.配置SW_PAD_CTL_PAD_GPIO1_IO03电气属性
#define SW_PAD_CTL_PAD_GPIO1_IO03 *((volatile unsigned int *)0x020E02F4)
SW_PAD_CTL_PAD_GPIO1_IO03 = 0x10B0
  • 4.设置GPIO1_GDIR的信号输出方向
#define GPIO01_GDIR *((volatile unsigned int *)0x0209C004)
GPIO01_GDIR = 0x08;
#define GPIO01_DR *((volatile unsigned int *)0x0209C000)
void delay_ms(volatile unsigned int n) {
    while (n--) { }
}
void delay(volatile unsigned int n) {
    while (n--) {
        delay_ms(0x7FF);
    }
}
whilte(1) {
  delay(500);
  GPIO01_DR = 0x0;
  delay(500);
  GPIO01_DR = 0x8;
}

编译代码

  • 编写Makefile
/// 定义目标文件变量
objs := start.o main.o

/// 生成ledc.bin,依赖objs
ledc.bin:${objs}
  arm-linux-gnueabihf-ld -Ttext 0x87800000 -o ledc.elf $^    /// 将目标文件链接生成ledc.elf $^表示所有依赖文件的集合,使用空格分开,去重
  arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@       /// 将ledc.elf生成ledc.bin, $@指目标集合,这里的目标就是上面定义的ledc.bin
  arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis  /// 将ledc.elf反汇编成ledc.dis,主是要方便查看连接后的代码段指令是否符合预期

/// 当目标文件没有时会使用如下的模式规则去生成对应的目标文件
/// $@指要生成的.o文件, $<指生成.o的源文件,比如start.o:start.s, $@(start.o) $<(start.s)
%.o:%.s
  arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
%.o:%.S
  arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $< 
%.o:%.c
  arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $< 

/// 定义清楚方法
clean:
  rm -rf *.o ledc.bin ledc.elf ledc.dis

编译

make clean && make

编译完成之后烧写到SD卡,选择SD卡启动观察LED灯闪烁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    11218

    浏览量

    222956
  • 计算机
    +关注

    关注

    19

    文章

    7764

    浏览量

    92688
  • 操作系统
    +关注

    关注

    37

    文章

    7329

    浏览量

    128643
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C语言:标准和实现

    C 语言:标准与实现 The Standards and Implementations of the C Programming Language前言
    发表于 11-27 22:27 58次下载

    CRC算法原理及C语言实现

    CRC算法原理及C语言实现:本文从理论上推导出CRC 算法实现原理,给出三种分别适应不同计算机或微控制器硬件环境的C 语言程序。读者更能根据
    发表于 09-23 23:38 31次下载

    pid算法原理和C语言的简单实现

    pid算法原理和C语言的简单实现,有兴趣的可以看看
    发表于 12-07 18:34 9次下载

    C语言教程之不使用strcpy()函数实现

    C语言教程之不使用strcpy()函数实现,很好的C语言资料,快来学习吧。
    发表于 04-25 15:03 0次下载

    C语言标准与实现

    C语言标准与实现 HENBUCUO BJBUI
    发表于 06-08 18:18 0次下载

    C语言模拟实现strcat函数

    C语言模拟实现strcat函数
    的头像 发表于 06-29 16:18 2820次阅读

    C语言模拟实现strcmp函数

    C语言模拟实现strcmp函数
    的头像 发表于 06-29 16:51 3077次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>模拟<b class='flag-5'>实现</b>strcmp函数

    CC2540驱动C语言源代码

    CC2540驱动C语言源代码
    发表于 03-10 11:13 5次下载
    CC2540<b class='flag-5'>驱动</b>的<b class='flag-5'>C</b><b class='flag-5'>语言</b>源代码

    使用单片机实现1602字符液晶工作于8位模式直接驱动显示的C语言程序

    本文档的主要内容详细介绍的是使用单片机实现1602字符液晶工作于8位模式直接驱动显示的C语言程序。
    发表于 03-24 14:45 7次下载

    使用单片机实现ULN2803驱动点阵屏仿电梯数字滚动显示的C语言实例

    本文档的主要内容详细介绍的是使用单片机实现ULN2803驱动点阵屏仿电梯数字滚动显示的C语言实例免费下载。
    发表于 03-31 16:45 38次下载

    EE-188:在ADSP-219x DSP上用C语言实现中断驱动系统

    EE-188:在ADSP-219x DSP上用C语言实现中断驱动系统
    发表于 04-17 14:59 0次下载
    EE-188:在ADSP-219x DSP上用<b class='flag-5'>C</b><b class='flag-5'>语言实现</b>中断<b class='flag-5'>驱动</b>系统

    累加校验和C语言实现

    累加校验和C语言实现
    发表于 11-29 18:06 10次下载
    累加校验和<b class='flag-5'>C</b><b class='flag-5'>语言实现</b>

    怎么用C语言实现多态

    这里我想主要介绍下在C语言中是如何实现的面向对象。知道了C语言实现面向对象的方式,我们再联想下,C
    的头像 发表于 10-12 09:12 2587次阅读

    C语言实现简单工厂模式

    在我们的印象中,设计模式是由面向对象的语言(C++、JAVA)才能完成的,而 C 语言是面向过程的语言,不能
    发表于 06-05 11:28 1296次阅读
    用<b class='flag-5'>C</b><b class='flag-5'>语言实现</b>简单工厂模式

    EE-188:使用C语言在ADSP-219x DSP上实现中断驱动系统

    电子发烧友网站提供《EE-188:使用C语言在ADSP-219x DSP上实现中断驱动系统.pdf》资料免费下载
    发表于 01-15 16:06 0次下载
    EE-188:使用<b class='flag-5'>C</b><b class='flag-5'>语言</b>在ADSP-219x DSP上<b class='flag-5'>实现</b>中断<b class='flag-5'>驱动</b>系统