首页 > 系统相关 >linux学习第三天

linux学习第三天

时间:2024-05-07 22:37:41浏览次数:19  
标签:GPIO1 led linux 第三天 学习 r0 IO 寄存器 GPIO

嵌入式linux学习第三天汇编语言点灯

今天学习如何在linux板子上点灯。

I.MX6U GPIO 详解

我们发现I.MX6U GPIO是分为两类的,:SNVS 域的和通用的。在讨论i.MX6U或类似的复杂微处理器时,了解其GPIO(通用输入输出)引脚的不同分类是很重要的。i.MX6U的GPIO引脚被分为两大类:SNVS(Secure Non-Volatile Storage)域的GPIO和通用GPIO。这种分类反映了它们不同的用途和特性。

IO:Input Output,用于CPU与外界进行信息交互
GPIO:General Purpose IO ports,通用IO口
SNVS:Secure Non-Volatile Storage 安全的非易失性存储
IOMUX:Input Output Multiplexer 输入/输出多路复用器
IOMUXC:Input Output Multiplexer Controller 输入/输出多路复用控制器
SW:Switch 开关

SNVS域的GPIO

SNVS域是指与安全和非易失性存储相关的功能区域。这个域主要关注的是安全功能,比如加密、安全启动、电源管理和保护敏感数据等。

  • 用途:SNVS域的GPIO通常用于安全相关的功能,例如检测篡改事件、管理安全启动过程中的信号或者控制与安全相关的外设。
  • 特性:这些GPIO在系统的低功耗模式下仍然可以工作,因此它们特别适合于那些需要在系统休眠或低功耗状态下监视外部事件的应用。此外,它们还可能支持一些特定的安全功能,比如硬件加密引擎的控制信号。
  • 电源域:SNVS域的GPIO与特定的电源域相关联,即使在系统其它部分关闭电源的情况下,这部分电源域仍然保持供电。这样可以确保安全功能在系统的各种电源状态下都能正常工作。

通用GPIO

与SNVS域的GPIO相比,通用GPIO没有那么多特定的安全或电源管理功能。它们被设计用于更广泛的目的,从简单的LED控制到与外部设备的复杂通信等。

  • 用途:通用GPIO用于各种标准输入输出任务,如数据收发、信号触发、电机控制等。
  • 灵活性:这些GPIO通常提供高度的配置灵活性,包括但不限于方向控制(输入或输出)、上拉/下拉电阻配置、中断触发设置等。
  • 电源域:通用GPIO通常随主系统电源一起工作,这意味着它们在系统进入低功耗模式时可能不可用。

在这里插入图片描述
STM32 的很多 IO 是可以复用为其它功能的,那么 I.MX6ULL 的其它 IO 也 是 可 以 复 用 为 GPIO 功能。同样的,GPIO1_IO00~GPIO_IO09 也是可以复用为其它外设引脚的,
一般来说配置GPIO步骤分为以下几步:
①、使能 GPIO 对应的时钟。
②、设置寄存器 IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能,使其复用
为 GPIO 功能。
③、设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置 IO 的上下拉、速度等等。
④、第②步已经将 IO 复用为了 GPIO 功能,所以需要配置 GPIO,设置输入/输出、是否使
用中断、默认输出电平等

1:使能对应GPIO时钟

CCM 里 面 的 外 设 时 钟 使 能 寄 存 器 。 CMM 有CCM_CCGR0~CCM_CCGR6 这 7 个寄存器,这 7 个寄存器控制着 I.MX6U 的所有外设时钟开关,
在这里插入图片描述
在这里插入图片描述
CCM_CCGR0 是个 32 位寄存器,其中每 2 位控制一个外设的时钟,比如 bit31:30 控制着GPIO2 的外设时钟,两个位就有 4 种操作方式.

在这里插入图片描述

2:设置寄存器 IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能,使其复用 为 GPIO 功能。

在这里插入图片描述
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 的寄存器,寄存器地址为 0X020E005C,这个寄存器是 32 位的,但是只用到了最低 5 位,其中bit0~bit3(MUX_MODE)就是设置 GPIO1_IO00 的复用功能的。GPIO1_IO00 一共可以复用为 9种功能 IO,分别对应 ALT0~ALT8,

3: 设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置 IO 的上下拉、速度等等。

在这里插入图片描述

IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 也是个寄存器,寄存器地址为 0X020E02E8。这也是个 32 位寄存器,但是只用到了其中的低 17 位,下面是GPIO功能图的具体配置。

在这里插入图片描述
HYS(bit16):对应图 8.1.4.2 中 HYS,用来使能迟滞比较器,当 IO 作为输入功能的时候有效,用于设置输入接收器的施密特触发器是否使能。如果需要对输入波形进行整形的话可以使能此位。此位为 0 的时候禁止迟滞比较器,为 1 的时候使能迟滞比较器。
PUS(bit15:14):对应图 8.1.4.2 中的 PUS,用来设置上下拉电阻的,一共有四种选项可以选择,如表 8.1.4.1 所示:
在这里插入图片描述
PUE(bit13):图 8.1.4.2 没有给出来,当 IO 作为输入的时候,这个位用来设置 IO 使用上下拉还是状态保持器。当为 0 的时候使用状态保持器,当为 1 的时候使用上下拉。状态保持器在IO 作为输入的时候才有用,顾名思义,就是当外部电路断电以后此 IO 口可以保持住以前的状态。
PKE(bit12):对应图 8.1.4.2 中的 PKE,此位用来使能或者禁止上下拉/状态保持器功能,为0 时禁止上下拉/状态保持器,为 1 时使能上下拉和状态保持器。
ODE(bit11):对应图 8.1.4.2 中的 ODE,当 IO 作为输出的时候,此位用来禁止或者使能开路输出,此位为 0 的时候禁止开路输出,当此位为 1 的时候就使能开路输出功能。
SPEED(bit7:6):对应图 8.1.4.2 中的 SPEED,当 IO 用作输出的时候,此位用来设置 IO 速度,设置如表所示:
在这里插入图片描述
DSE(bit5:3):对应图 8.1.4.2 中的 DSE,当 IO 用作输出的时候用来设置 IO 的驱动能力,总共有 8 个可选选项,如表 8.1.4.3 所示:
在这里插入图片描述
SRE(bit0):对应图 8.1.4.2 中的 SRE,设置压摆率,当此位为 0 的时候是低压摆率,当为 1的时候是高压摆率。这里的压摆率就是 IO 电平跳变所需要的时间,比如从 0 到 1 需要多少时间,时间越小波形就越陡,说明压摆率越高;反之,时间越多波形就越缓,压摆率就越低。如果你的产品要过 EMC 的话那就可以使用小的压摆率,因为波形缓和,如果你当前所使用的 IO做高速通信的话就可以使用高压摆率。

4: I.MX6U GPIO 配置

IOMUXC_SW_MUX_CTL_PAD_XX_XX 和 IOMUXC_SW_PAD_CTL_PAD_XX_XX 这两种寄存器都是配置 IO 的,注意是 IO!不是 GPIO,GPIO 是一个 IO 众多复用功能中的一种。如果我们要用 GPIO1_IO00 来点个灯、作为按键输入啥的就是使用其 GPIO(通用输入输出)的功能。将其复用为 GPIO 以后还需要对其 GPIO 的功能进行配置,
在这里插入图片描述
这两种寄存器前面说了用来设置 IO 的复用功能和 IO 属性配置。左上角部分的 GPIO 框图就是,当 IO 用作 GPIO 的时候需要设置的寄存器,一共有八个:DR、GDIR、PSR、ICR1、ICR2、EDGE_SEL、IMR 和 ISR。前面我们说了 I.MX6U 一共有
GPIO1~GPIO5 共五组 GPIO,每组 GPIO 都有这 8 个寄存器。
在这里插入图片描述此寄存器是 32 位的,一个 GPIO 组最大只有 32 个 IO,因此 DR 寄存器中的每个位都对应一个 GPIO。当 GPIO 被配置为输出功能以后,向指定的位写入数据那么相应的 IO 就会输出相应的高低电平,比如要设置 GPIO1_IO00 输出高电平,那么就应该设置 GPIO1.DR=1。被配置为输入模式以后,此寄存器就保存着对应 IO 的电平值,每个位对对应一个 GPIO,例如,当 GPIO1_IO00 这个引脚接地的话,那么 GPIO1.DR 的 bit0 就是 0。
在这里插入图片描述
GDIR 寄存器也是 32 位的,此寄存器用来设置某个 IO 的工作方向,是输入还是输出。同样的,每个 IO 对应一个位,如果要设置 GPIO 为输入的话就设置相应的位为 0,如果要设置为输出的话就设置为 1。比如要设置 GPIO1_IO00 为输入,那么 GPIO1.GDIR=0;

在这里插入图片描述
接下来来看ICR1和ICR2寄存器,ICR1 用于 IO0~15 的配置, ICR2 用于 IO16~31 的配置。ICR1 寄存器中一个 GPIO 用两个
位,这两个位用来配置中断的触发方式,和 STM32 的中断很类似,可配置的选线如图所示:
在这里插入图片描述
在这里插入图片描述
IMR 寄存器,这是中断屏蔽寄存器。

在这里插入图片描述
IMR 寄存器也是一个 GPIO 对应一个位,IMR 寄存器用来控制 GPIO 的中断禁止和使能,如果使能某个 GPIO 的中断,那么设置相应的位为 1 即可,反之,如果要禁止中断,那么就设置相应的位为 0 即可。例如,要使能 GPIO1_IO00 的中断,那么就可以设置 GPIO1.MIR=1 即可。
接下来看寄存器 ISR,ISR 是中断状态寄存器。

在这里插入图片描述
ISR 寄存器也是 32 位寄存器,一个 GPIO 对应一个位,只要某个 GPIO 的中断发生,那么ISR 中相应的位就会被置 1。所以,我们可以通过读取 ISR 寄存器来判断 GPIO 中断是否发生,相当于 ISR 中的这些位就是中断标志位。当我们处理完中断以后,必须清除中断标志位,清除方法就是向 ISR 中相应的位写 1,也就是写 1 清零。
EDGE_SEL 寄存器,这是边沿选择寄存器,
在这里插入图片描述

硬件原理图

以上就是配置GPIO的过程。接下来看具体的硬件原理图。LED0 接到了 GPIO_3 上,GPIO_3 就是 GPIO1_IO03,当 GPIO1_IO03输出低电平(0)的时候发光二极管 LED0 就会导通点亮,当 GPIO1_IO03 输出高电平(1)的时候发
光二极管 LED0 不会导通,因此 LED0 也就不会点亮。所以 LED0 的亮灭取决于 GPIO1_IO03
的输出电平,输出 0 就亮,输出 1 就灭。
在这里插入图片描述

汇编程序编写

1、使能 GPIO1 时钟
GPIO1 的时钟由 CCM_CCGR1 的 bit27 和 bit26 这两个位控制,将这两个位都设置位 11 即可。本教程所有例程已经将 I.MX6U 的所有外设时钟都已经打开了,因此这一步可以不用做。
2、设置 GPIO1_IO03 的复用功能
找到 GPIO1_IO03 的复用寄存器“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03”的地址为0X020E0068,然后设置此寄存器,将 GPIO1_IO03 这个 IO 复用为 GPIO 功能,也就是 ALT5。

在这里插入图片描述

3、配置 GPIO1_IO03
找到 GPIO1_IO03 的配置寄存器“IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03”的地址为0X020E02F4,根据实际使用情况,配置此寄存器。

在这里插入图片描述
4、设置 GPIO
我们已经将 GPIO1_IO03 复用为了 GPIO 功能,所以我们需要配置 GPIO。找到 GPIO3 对应的 GPIO 组寄存器地址,
在这里插入图片描述
具体汇编程序如下:
我们在虚拟机系统进行程序编写以及编译。

.global _start
_start:
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]
@将GPIO1_IO03复用为GPIO
ldr r0,=0x020E0068
ldr r1,=0x5
str r1,[r0]

ldr r0,=0x020E02F4
ldr r1,=0x10B0
str r1,[r0]

ldr r0, =0X0209C004 /*寄存器 GPIO1_GDIR */
ldr r1, =0X0000008 
str r1,[r0]

ldr r0, =0X0209C000 /*寄存器 GPIO1_DR */
ldr r1, =0 
str r1,[r0]

loop:
    b loop

上面汇编的操作并不复杂,只是按照上面已经列出的步骤对对应寄存器进行赋值。

编译下载验证

1、arm-linux-gnueabihf-gcc 编译文件
我们是要编译出在 ARM 开发板上运行的可执行文件,所以要使用安装的交叉编译器 arm-linux-gnueabihf-gcc 来编译。就一个 led.s 源文件,所以编译比较简单。先将 led.s 编译为对应的.o 文件,在终端中输入如下命令:

arm-linux-gnueabihf-gcc -g -c led.s -o led.o

上述命令就是将 led.s 编译为 led.o,其中“-g”选项是产生调试信息,GDB 能够使用这些调试信息进行代码调试。“-c”选项是编译源文件,但是不链接。“-o”选项是指定编译产生的文件名字,这里我们指定 led.s 编译完成以后的文件名字为 led.o。执行上述命令以后就会编译生成一个 led.o 文件。
在这里插入图片描述
2、arm-linux-gnueabihf-ld 链接文件
arm-linux-gnueabihf-ld 用来将众多的.o 文件链接到一个指定的链接位置。因此我们现在需要做的就是确定一下本试验最终的可执行文件其运行起始地址,也就是链接地址。这里我们要区分“存储地址”和“运行地址”这两个概念,“存储地址”就是可执
行文件存储在哪里,可执行文件的存储地址可以随意选择。“运行地址”就是代码运行的时候所处的地址,这个我们在链接的时候就已经确定好了,代码要运行,那就必须处于运行地址处,否则代码肯定运行出错。比如 I.MX6U 支持 SD 卡、EMMC、NAND 启动,因此代码可以存储到 SD 卡、EMMC 或者 NAND 中,但是要运行的话就必须将代码从 SD 卡、EMMC 或者
NAND 中拷贝到其运行地址(链接地址)处,“存储地址”和“运行地址”可以一样,比如STM32 的存储起始地址和运行起始地址都是 0X08000000。
上电以后 I.MX6U 的内部 boot rom 程序会将可执行文件拷贝到链接地址处,这个链接地址可以在 I.MX6U 的内部 128KB RAM 中(0X900000~0X91FFFF),也可以在外部的 DDR 中。本教程所有裸机例程的链接地址都在 DDR中,链接起始地址为 0X87800000。I.MX6U-ALPHA 开发板的 DDR 容量有两种:512MB 和256MB,起始地址都为 0X80000000,只不过 512MB 的终止地址为 0X9FFFFFFF,而 256MB 容量的终止地址为 0X8FFFFFFF。之所以选择 0X87800000 这个地址是因为后面要讲的 Uboot 其链接地址就是 0X87800000,

arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf

在这里插入图片描述

3、arm-linux-gnueabihf-objcopy 格式转换
arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 led.elf 文件转换为led.bin 文件,命令如下:

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出,选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试信息。
在这里插入图片描述
4、arm-linux-gnueabihf-objdump 反汇编
大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:

arm-linux-gnueabihf-objdump -D led.elf > led.dis

在这里插入图片描述
5:创建Makefile文件:

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

代码烧写

烧写使用正点原子提供的
1、将 imxdownload 拷贝到工程根目录下
2、给予 imxdownload 可执行权限
3、确定要烧写的 SD 卡。
在这里插入图片描述
比如我们插入sb多出了几个,烧写的确认的就是/dev/sdc。

./imxdownload led.bin /dev/sd

在这里插入图片描述
烧写速度226kb每秒证明烧写成功。
然后还要设置板子的启动方式为sd卡启动。拨码开关组合为:
在这里插入图片描述
插入板子按下复位,发现这个灯亮起,证明点灯成功!!!
在这里插入图片描述

标签:GPIO1,led,linux,第三天,学习,r0,IO,寄存器,GPIO
From: https://www.cnblogs.com/bathwind/p/18178557

相关文章

  • 原始翎风CLIENT8位 (8) CLUNIT的学习
    这个里面是绘图,有汇编,那个绘画效果的汇编看明白了,实际是先建立了一个颜色的转换索引表,颜色对应下标,数据是转换后的颜色在绘画效果中用函数功能找到混合表面的的指针,锁定它用汇编语言,将混合表面的每一个像素查找转换索引表,转换过去。因为用了MM0寄存器,这是个MMX的指令里面的,它是64......
  • 原始翎风CLIENT8位 (9) magieff的学习
    定义类型这里的魔法效果,是扔出去的魔法效果,魔法释放后的效果在施咒的动作的,如火球术的施咒效果图样是在自身的,却不在这里,由Actor单元里面实现有个m_nCurEffFrame,但是奇怪的是空间移动,是图样是在于自身这些效果,又是由本单元里面实现的。 TMagicType枚举开头mtmtReady准备?mt......
  • m基于Q-Learning强化学习的迷宫路线规划策略matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要       Q-Learning是一种无模型的强化学习算法,它能够使代理(Agent)在与环境互动的过程中学习最优策略,无需了解环境的完整动态模型。在迷宫路线规划问题中,Q-Learning被用来指导代理找到从起......
  • Linux 系统目录和文件夹的区别
    Linux系统目录和文件夹的区别概念1.系统目录:在Linux系统中,目录是文件系统的一种特殊类型,用于组织和存储文件和其他目录。每个目录都包含零个或多个文件和其他目录,以及一些与之相关的属性,如权限、所有者等。目录在文件系统中以目录项的形式存在,每个目录项包含了文件或子目录的......
  • 学习笔记:FFT与拉格朗日插值
    多项式的表示形式系数表示与点值表示假设\(f(x)\)是一个\(n\)次多项式,则\(f(x)\)的系数表示为\(f(x)=a_nx^n+a_{n-1}x^{n-1}+\cdots+a_0\)\(f(x)\)的点值表示为\((x_0,f(x_0)),\(x_1,f(x_1)),\dots,(x_n,f(x_n))\),其中\(\foralli\neqj,\x_i......
  • Linux系统管理-系统概述
    一、系统概述3.系统安装1.系统安装1.选择第一项installcentos7,并且设置语言,推荐使用中文,简体中文2.字符界面安装选择最小或基本网页服务器即可,接下来就是进行磁盘分区,也可以自己分配或者系统自动分配3.手动分区里面也可以让系统自动创建,或者自己手动创建4.接受分区的修......
  • 在Linux上使用CAN
    1、相关背景知识CAN控制器局域网络(ControllerAreaNetwork),一种串行数据通信协议。CAN是一种异步通讯,只有CAN_high和CAN_low两条信号线(实际上还需要共地,GND),共同构成一组差分信号线,以差分信号的形式进行通讯。CAN通讯节点由一个CAN控制器及CAN收发器,CAN控制器用于实现实......
  • ###什么是Linux内核###什么是MMU
    什么是Linux内核Linux内核简介Linux®内核是Linux操作系统(OS)的主要组件,也是计算机硬件与其进程之间的核心接口。它负责两者之间的通信,还要尽可能高效地管理资源。之所以称为内核,是因为在操作系统中就像果实硬壳中的种子一样,控制着硬件(无论是电话、笔记本电脑、服务器,还是任......
  • Linux系统目录和文件夹的区别
    V1.02024年5月7日发布于博客园目录Linux系统目录和文件夹的区别?目录文件(DirectoryFile)文件夹(Folder)技术区别结论参考资料Linux系统目录和文件夹的区别?在Linux系统中,目录是指目录文件!Linux中的目录并不是一种容器,而仅仅是一个文件索引表。其内容是其他文件和目录的索引......
  • Linux内核的作用
    Linux内核是操作系统的核心组件,它负责管理计算机的硬件资源,并提供访问这些资源的接口,以便其他软件程序可以在计算机上运行。它的主要作用为:硬件抽象层:Linux内核提供了一个抽象层,将不同类型的硬件资源(如处理器、内存、存储设备、网络接口等)统一起来,使软件开发人员不需要直接与硬......