IMX6ULL裸机程序--1.汇编点亮LED

实验必需

硬件

  • 开发板:野火Linux开发板-EBF6ULL S1Pro
  • TF卡
  • USB读卡器

软件

  • Ubuntu 16.0.4 (环境已搭建完成)
  • imxdownload (正点原子裸机烧写软件,没错白嫖真香,感谢正点原子大大)
  • VSCode代码编辑器

原理分析

IO命名规则

  • IOMUXC_SW_MUX_CTL_PAD_XX_XX为IMX6ULL引脚命名规则,后面的XX_XX即为IO名,根据其具体功能命名。
    IMX6ULL裸机程序--1.汇编点亮LED_第1张图片

IO功能复用

6ULL的IO是可以复用多种功能的,通过寄存器配置其具体功能。
以IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00为例,其复用寄存器如下:

IMX6ULL裸机程序--1.汇编点亮LED_第2张图片
寄存器地址:0x020E_005C
为32位寄存器,只用了低五位[4:0]。其中bit0~bit3(MUX_MODE)就是设置 GPIO1_IO00 的复用功能的。共9种功能,ALT5就是作为GPIO1_IO00。

IO属性配置

选择复用功能为GPIO后,需要对其进行进行属性配置。配置寄存器如下:
IMX6ULL裸机程序--1.汇编点亮LED_第3张图片
IMX6ULL裸机程序--1.汇编点亮LED_第4张图片
此寄存器也是32位寄存器,只用了低17位。

  • HYS(bit16):迟滞比较器使能位,IO输入时有效,设置施密特触发器是否使能。0 禁止,1使能
  • PUS(bit15:14):上下拉电阻设置,00:100K下拉,01:47K上拉,10:100K上拉,11:22K上拉。
  • PUE(bit13):IO作输入时,设置IO使用状态保持器还是上下拉,0:使用状态保持器,1:使用上下拉。状态保持器:外部电路断电时,IO保持以前状态不变。
  • PKE(bit12):使能/禁止上下拉/状态保持器。0:禁止,1:使能。
  • ODE(bit11):当 IO 作为输出的时候,此位用来禁止或者使能开路输出,此位为 0 的时候禁止开路输出,当此位为 1 的时候就使能开路输出功能。
  • SPEED(bit7:6): IO 用作输出的时候,此位用来设置 IO 速度,00:低速50M,01:中速100M,10:中速100M,11:高速200M。
  • DSE(bit5:3):当 IO 用作输出的时候用来设置 IO 的驱动能力,000:输出驱动关闭,001:R0(3.3V下260ohm,1.8V–150ohm,DDR–240ohm),010:R0/2,011:R0/3,100:R0/4,101:R0/5,110:R0/6,111:R0/7。
  • SRE(bit0):设置压摆率,0:低压摆率,1:高压摆率。

GPIO配置

当IO作为GPIO使用时,需要设置的寄存器一共有八个:

  • DR:数据寄存器,每位对应一个GPIO,输出时写入0/1控制高低电平,输入时保存对应GPIO电平状态。
  • GDIR:方向寄存器,32位,设置IO工作方向,0:输入,1:输出。每个IO对应1位。
  • PSR:GPIO状态寄存器,每一个GPIO对应1位,功能和输入状态的DR寄存器一样。
  • ICR1:中断控制寄存器,ICR1用于配置低16个GPIO,IO0-15,ICR1 寄存器中一个 GPIO 用两个位,这两个位用来配置中断的触发方式。00:低电平触发,01:高电平触发,10:上升沿触发,11:下降沿触发
  • ICR2:中断控制寄存器,ICR2 用于配置高 16 个 GPIO,IO16-31,ICR2 寄存器中一个 GPIO 用两个位,这两个位用来配置中断的触发方式。00:低电平触发,01:高电平触发,10:上升沿触发,11:下降沿触发
  • EDGE_SEL
  • IMR:中断屏蔽寄存器,每个IO对应1位,1:使能中断,0:禁止中断。
  • ISR:中断状态寄存器,一个 GPIO 对应一个位,只要某个 GPIO 的中断发生,那么ISR 中相应的位就会被置 1。当我们处理完中断以后,必须清除中断标志位,即写0。

GPIO时钟使能

时钟使能寄存器有CCM_CCGR0~CCM_CCGR6这7个寄存器。控制着所有外设时钟开关。
以CCM_CCGR0为例:
IMX6ULL裸机程序--1.汇编点亮LED_第5张图片
每 2 位控制一个外设的时钟,比如 bit31:30 控制着
GPIO2 的外设时钟,两个位就有 4 中操作方式,00:关闭,01:运行模式下开启。10:未使用,11:除停止模式外,其他所有模式都打开。

代码编写

代码分析

前面原理分析可知,GPIO使用需要如下步骤:

  • 使能GPIO对应时钟
  • 设置复用寄存器,选择功能
  • 设置配置寄存器,配置IO属性
  • 设置GPIO属性。
  • 控制GPIO。

代码编写

新建工程

新建1.leds文件夹,在文件夹内新建led.s文件,.vscode文件夹。其中.vscode文件夹是vs工程。

代码

vscode打开文件夹,编辑led.s代码:

.global _start      /*全局标识*/


/*  _start函数,程序从此函数开始执行,此函数完成
    时钟使能,GPIO初始化,最终控制GPIO输出低电平
    点亮LED灯 */
_start:

/* 1.使能所有时钟 */
ldr r0, =0x020C4068  /*  寄存器CCGR0    */
ldr r1, =0xffffffff
str r1, [r0]

ldr r0, =0x020C406C  /*  寄存器CCGR1    */
str r1, [r0]

ldr r0, =0x020C4070  /*  寄存器CCGR2    */
str r1, [r0]

ldr r0, =0x020C4074  /*  寄存器CCGR3    */
str r1, [r0]

ldr r0, =0x020C4078  /*  寄存器CCGR4    */
str r1, [r0]

ldr r0, =0x020C407C  /*  寄存器CCGR5    */
str r1, [r0]

ldr r0, =0x020C4080  /*  寄存器CCGR6    */
str r1, [r0]


/*  2.设置GPIO1_IO04为复用GPIO1_IO04    */
ldr r0, =0x020E006C  /* 将寄存器SW_MUX_CTL_PAD_GPIO1_IO04 添加到r0中  */
ldr r1, =0x05 /*    设置寄存器的MUX_MODE为5*/
str r1, [r0]

/*
    3.配置GPIO1_IO04的IO属性
    *bit 16:0 HYS关闭
    *bit 15:14 :00默认下拉
    *bit 13    :0 keeper使能
    *bit 12    :1 pull/keeper使能
    *bit 11    : 0 关闭开路输出
    *bit 7:6   :10 速度100Mhz
    *bit 5:3   : 110 R0/6驱动能力
    *bit 0     : 0 低转换率

*/

ldr r0, =0x20E02F8   /*   寄存器SW_PAD_GPIO1_IO03_BASE  */
ldr r1, =0x10B0     /*  */
str r1, [r0]  


/*  4.设置GPIO1_IO04为输出*/
ldr r0, =0X0209C004   /*  寄存器 GPIO1_GDIR   */
ldr r1, =0X00000010     /*  */
str r1, [r0]  

/* 5.打开LED */
ldr r0, =0X0209C000   /*  寄存器 GPIO1_DR   */
ldr r1, =0x00000010     /*  */
str r1, [r0]  

loop:
    b loop

编译链接

  • 编译:将程序换换成二进制文件,生成.o文件
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
  • 链接:将多个.O文件连接到一起,从指定地址开始。
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
  • 格式转换:将链接好的文件转换为.bin文件
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
  • 反汇编:将elf文件反汇编为.dis文件
arm-linux-gnueabihf-objdump -D led.elf > led.dis

Makefile文件

为了方便编译,一般把多条指令编辑成Makefile文件。

led.bin:led.s
	arm-linux-gnueabihf-gcc -g -c led.s -o led.o
	arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
	arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
	arm-linux-gnueabihf-objdump -D led.elf > led.dis
clean:
	rm -rf *.o led.bin led.elf led.dis

程序烧录运行

下载代码到SD卡

前面我们已经得到了led.bin文件,下面还需要在bin文件前添加一个头部信息,才可以运行。我们使用的工具是正点原子提供的imxdownload软件。

  • 将软件拷贝到代码所在文件夹
  • 给软件开执行权限
chmod 777 imxdownload
  • 查看U盘盘符
ls /dev/sd*
  • 烧录代码
./imxdownload led.bin /dev/sdc

运行

运行前需要把开发板调到SD卡启动模式,然后把SD卡查到卡槽内,上电看到彩灯红色亮,即控制了IO输出低电平。
开发板启动方式选择如下:
IMX6ULL裸机程序--1.汇编点亮LED_第6张图片

你可能感兴趣的:(IMX6ULL学习--裸机篇)