Alientek I.MX6UL Linux Note,Welcom Come To Discuss

淺唱寂寞╮ 提交于 2019-11-28 20:21:58

第六章 Contex-A7 MPCore架构

Contex-A处理器运行模型

  以前的ARM处理器有七种运行模式,现在有九种,新增加Monitor和Hyp运行模式。

模式 描述
USR(User) 用户模式,非特权模式,大部分程序运行的时候处于此模式
FIQ 快速中断模式,进入FIQ中断异常
IRQ 一般中断模式
SVC(Supervisor) 超级管理员模式,特权模式,宫操作系统使用
MON(Monitor) 监视模式,这个模式用于安全扩展模式,指用户安全
ABT(Abort) 数据访问终止模式,用于虚拟存储以及存储保护
HYP(Hyp) 超级监视模式,用于虚拟化扩展
UND(Undef) 未定义指令终止模式
SYS(System) 系统模式,用于运行特权级的操作系统任务

记忆(UFIS MAHUS)

Contex-A寄存器组

  ARM提供了16个32位通用寄存器(R0R15)供软件使用,前15个(R0R14)可以用作通用的数据存储,R15是程序计数器PC,用来保存将要执行的命令,ARM还提供了一个当前程序状态寄存器CPSR和一个备份程序寄存器SPSR,SPSR是CPSR的备份。
总结一下, Cortex-A内核寄存器组成如下(共43个):
①、 34个通用寄存器,包括 R15程序计数器 (PC),这些寄存器都是 32位的。
②、 8个状态寄存器,包括 CPSR和 SPSR。
③、 Hyp模式下独有一个 ELR_Hyp寄存器。

第七章 ARM汇编基础

  学习汇编的目的:初始化C语言运行环境。

GNU汇编语法

label:instruction@comment
label:标号,表示地址位置,有些指令前面可能会有标号
instruction:指令,即汇编指令或者伪指令
@:注释符号
comment:注释内容
示例代码:
add:
MOVS R0, #0X12 @设置 R0=0X12

注意! ARM中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用
小写,但是不能大小写混用。

用户可以使用.section伪操作来定义一个段,汇编系统预定义了一些段名:
.text 表示代码段
.data 表示初始化的数据段
.base 表示未初始化的数据段
.rodata 表示只读数据段

Contex-A7常用的汇编指令

  处理器做的最多的事情就是在处理器内部来回传递数据,常见的操作有:

  1. 将数据从一个寄存器传递到另一个寄存器。
  2. 将数据从一个寄存器传递到特殊寄存器,如CPSR和SPSR.
  3. 将立即数传递到寄存器。
    数据传输常用的指令有三个:MOV、MRS、MSR.

处理器内部传输指令

指令 目的 描述
MOV R0 RI 将R1里面的数据复制到R0中
MRS R0 CPSR 将特殊寄存器CPSR里面的数据复制到R0
MSR CPSR RI 将R1里面的数据复制到特殊寄存器CPSR里

存储器访问指令

指令 描述
LDR Rd, [Rn , #offset] 从存储器Rn+offset的位置读取数据存放到 Rd中
STR Rd, [Rn, #offset] 将Rd中的数据写入到存储器中的 Rn+offset位置。

压栈和出栈指令

指令 描述
PUSH 将寄存器列表入栈
POP 从栈中恢复寄存器列表

PUSH 和POP 的另外一种写法是“STMFD SP!”和“LDMFD SP!”。

跳转指令

  有多种跳转指令

  1. 直接使用调转指令B、BL、BX等。
  2. 直接向PC寄存器里面写入数据。
指令 描述
B 调转到label,如果跳转范围超过+/-2KB,可以指定B.W
BX 间接跳转,跳转到存放Rm中的地址处,并且切换指令集
Bl 跳转到标号地址,并将返回地址保存在LR中
BlX 结合BX和BL的特点,跳转到Rm指定的地址,并将返回地址保存在LR中,切换指令集

第八章 汇编LED灯实验

在这里插入图片描述

GPIO功能图

IO控制初始化所需要用到的寄存器

1. SW_MUX_CTL Register

  Address:20E_0000h base+5Ch offset=20E_005Ch
在这里插入图片描述

UART1_TX_DATA IO 复用

2. SW_PAD_CTL Register

  Address:20E_0000h base+2E8h offset=20E_02E8h
在这里插入图片描述

IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 寄存器



  从上图中可以看出,该寄存器只用到了低17位:


  HYS(Bits16):用来使能迟滞比较器,输入有效时,需要对输入波形进行整形可以使用此使能位,0禁止,1使能。


  PUS(Bits15:14):用来设置上下拉电阻,

位设置 含义
00 100K下拉
01 47K上拉
10 100K上拉
11 22K上拉

  PUE(Bits13):用来设置IO使用上下拉还是状态保持器,0为状态保持器,1为使用上下拉,状态保持器在IO作为输入时才有效。
  PKE(Bits12):用来使能或者禁止上下拉/状态保持器功能,为0禁止上下拉/状态保持器,为1使能上下拉和状态保持器。
  SPEED(Bits7:6):当IO用作输出时,设置IO速度。
位设置 速度
00 低速50M
01 中速100M
10 中速100M
11 最大速度200M

  DSE(Bits5:3):用来设置IO的驱动能力。
位设置 速度
000 输出驱动关闭
001 R0(3.3V下 R0是 260Ω, 1.8V下 R0是 150Ω,接 DDR的时候是 240ΩΩ)
010 R0/2
011 R0/3
100 R0/4
101 R0/5
110 R0/6
111 R0/7

  DSE(Bits5:3):设置压摆率,压摆率指的是IO电平跳变所需要的时间,时间越短压摆率越高,反之越低。过EMC需要低压摆率,高速通信需要高压摆率。

3.GPIO的配置

  IOMUXC_SW_MUX_CTL_PAD_XX_XX和 IOMUXC_SW_PAD_CTL_PAD_XX_XX这两种寄存器都是配置 IO的,注意以下IO与GPIO的区别,GPIO是IO众多复用的其中一种。
  当IO用作GPIO时需要设置的寄存器共有8个:DR、GDIR、PSR、ICRC、ICR2、EDGE_SEL、IMR和ISR…

DR寄存器

在这里插入图片描述

DR寄存器

  一个GPIO组最大只有32个IO,DR寄存器的每一个位对应一个GPIO,当GPIO被设置成输出功能后,相应的IO就会输出相应的高低电平,置1为高电平,置0为低电平。当GPIO被设置成输入功能后,该寄存器将会保存对应IO的电平值,1为高电平,0为低电平。
GDIR寄存器

在这里插入图片描述

GDIR寄存器

  GDIR也是32位,用来设置某个IO的工作方向,是输入还是输出,一个IO对应一个位,置0为输入,置1为输出。
PSR寄存器

在这里插入图片描述

PSR寄存器

  PSR是GPIO状态寄存器,一个GPIO对应一个位,读取相应的位即可获取GPIO的状态,也就是GPIO的高低电平。功能和输入状态下的DR寄存器一样。
ICR1和ICR2寄存器

在这里插入图片描述

ICR1寄存器

  ICR1和ICR2是中断控制寄存器,ICR1用于配置低16位GPIO,ICR2用于配置高16位。配置选线如下表:
位设置 速度
00 低电平触发
01 高电平触发
10 上升沿触发
11 下降沿触发

IMR寄存器

在这里插入图片描述

IMR寄存器

  IMR寄存器是中断屏蔽寄存器,也是一个GPIO对应一个位,使能GPIO中断置1,反之禁止。
ISR寄存器

在这里插入图片描述

ISR寄存器

  ISR寄存器是中断状态存器,也是一个GPIO对应一个位,某个GPIO中断发生了,相应的位将会被置1,我们可以通过读取ISR来判断GPIO是否发生中断,当中断处理完成之后,必须清除中断标志位,清除方法是向ISR相应的位写1,也就是清零。
EDGE_SEL寄存器

在这里插入图片描述

EDGE_SEL寄存器

  EDGE_SEL寄存器用来设置边沿中断,这个寄存器会覆盖ICR1和ICR2的设置,同样是一个GPIO对应一个位,置1表示双边沿触发中断,无论GPIO_CR1设置的是多少,都是双边沿触发。
### 时钟使能 I.MX6U的系统时钟参考 《 I.MX6UL参考手册》的第 18章“ Chapter 18: Clock Controller Module(CCM)”,这一个章主要将时钟系统。目前不研究,只看CMM的外设时钟使能寄存器。CMM有CCM_CCGR0~CCM_CCGR6这7个寄存器, ##### CCM_CCGR0 寄存器 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191126172527689.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTM1MTY5,size_16,color_FFFFFF,t_70)
CCM_CCGR0寄存器

  CCM_CCGR0是32位寄存器,其中每2位控制一个外设时钟,比如bit31:30控制着GPIO2的外设时钟,两个位有4种操作方式。
位设置 时钟控制
00 所有模式下都关闭外设时钟
01 只有在运行模式下打开外设时钟,等待模式和停止模式均关闭外设时钟
10 未使用(保留)
11 除了停止模式以外,其他所有模式下时钟都打开

I.MX6U的IO作为GPIO使用,初始化步骤如下:
1. 使能GPIO对应时钟。
2. 设置寄存器IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置IO复用功能,使其复用位GPIO功能。
3. 设置寄存器IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置IO的上下拉、速度等等。
4. 第2步已经将IO复用为GPIO功能,所以需要配置GPIO,设置输入/输出、是否使能中断、默认输出电平等。

示例代码:

.global _start

_start:
/*
*1.使能所有的时钟(CCGR0~CCGR1)
*/
ldr r0,=0x020C4068          /*打开CCM_CCGR0寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

ldr r0,=0x020C406C          /*打开CCM_CCGR1寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

ldr r0,=0x020C4070          /*打开CCM_CCGR2寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

ldr r0,=0x020C4074          /*打开CCM_CCGR3寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

ldr r0,=0x020C4078          /*打开CCM_CCGR4寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

ldr r0,=0x020C407C          /*打开CCM_CCGR5寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

ldr r0,=0x020C4080          /*打开CCM_CCGR6寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]

/*
*2.设置复用
*/

ldr r0,=0x02E00068
ldr r1,=0x00000005
str r1,[r0]

/*
*3.配置GPIO1_IO03 IO的属性
*/
/*bit 16:0 HYS关闭  
 *bit [15:14]: 00 默认下拉 
 *bit [13]: 0 kepper功能 
 *bit [12]: 1 pull/keeper使能 
 *bit [11]: 0 关闭开路输出 
 *bit [7:6]: 10 速度100Mhz
 *bit [5:3]: 110 R0/6驱动能力 
 *bit [0]: 0 
 *低转换率 48
 */
ldr r0,=0x020E02F4
ldr r1,=0x000010B0
ldr r1,[r0] 
/*
*4.设置GPIO1_IO3为输出
*/
ldr r0,=0x0209C004          /*配置GDIR寄存器*/
ldr r1,=0x00000008           /*默认电平为1*/
str r1,[r0]
/*
*5.打开LED0,设置GPIO1_IO03为高电平
*/
ldr r0,=0x0209C0000          /*配置DR寄存器*/
ldr r1,=0x000000000           /*默认电平为1*/
str r1,[r0]
/*
*loop死循环
*/
loop:
	b loop

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-guneabihf-objdump -D led.elf > led.dis
clean:
	rm -rf *.o led.bin led.elf led.dis
arm-linux-gnueabihf-gcc -g -c led.s -o led.o(编译文件)

  arm-linux-gnueabihf-gcc :表示编译文件;
  -g:选项表示产生调试信息;
  -c:选项表示编译源文件,但是不链接;
  -o:选项表示指定编译产生的文件名字。

arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf(链接文件)

  arm-linux-gnueabihf-ld:表示将众多的.o文件链接到一个指定的链接位置;
  -Ttext:表示连接时将初始地址重定向为0x87800000;

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin(格式转换)

  arm-linux-gnueabihf-objcopy 表示将led.elf文件转换成led.bin文件;
  -O:选项表示指定以什么格式输出;
  binary:表示以二进制格式输出;
  -S:表示不要复制源文件的重定位信息和符号信息;
  -g:表示不要复制源文件中的调试信息。

arm-linux-guneabihf-objdump -D (-m arm)led.elf > led.dis(反汇编)

  arm-linux-gnueabihf-objdump:表示进行反汇编,用来查看其汇编代码来调试代码;
  -D:表示反汇编所有的段;
  -m:表示后面跟CPU架构;
  >:表示将这个程序的反汇编程序写入到led.dis这个文件中,在终端中不显示出来。

第九章 I.MX6U的启动方式

启动方式选择

  BOOT模式有两种
  1.改写eFUSE(熔丝);
  2. 修改相应的GPIO高低电平。
  第一种修改eFUSE的方式只能修改一次,后面就不能再修改了,所以作为学习与调试我们不能使用。第二种是修改GPIO对应的高低电平来选择启动方式,所有的开发板都使用这种方式。

BOTE_MODE[1:0] BOOT类型
00 从FUSE启动
01 串行下载
10 内部BOOT模式
11 保留

  开发板只用到第二和第三种BOOT方式。

串行下载

  串行下载是指可以通过USB或UART将代码下载到外置存储设备中,所以我们可以使用OTG1这个USB口向开发板的存储设备下载代码。使用时需要用到NXP提供的一个软件,一般用来最终量产的时候烧写到外置存储设备中。

内部BOOT模式

  在此模式下,芯片会执行内部boot ROM代码,这段boot ROM代码会进行硬件初始化,然后从boot设备(存储代码的设备如SD/EMMC/NAND)将代码拷贝至指定的RAM,一般是DDR。

BOOT ROM初始化内容

BOOT 启动设备

在这里插入图片描述

BOOT_CFG引脚含义

在这里插入图片描述

BOOT选择拨码开关

除了BOOT_MODE1和BOOT_MODE0必须引出来,LCD_DATA3LCDDATA7、LCD_DTAT11这六个IO也被引出来,可以通过拨码开关进行设置,其中LCD_DTAT11是BOOT_CFG2[3],LCD_DAT3LCD_DATA7就是BOOT_CFG[3]~BOOT_CFG1[7],这六个IO配置如下:

BOOT_CFG引脚[1:0] 对应LCD引脚 含义
BOOT_CFG2[3] LCD_DATA11 LCD_DATA11|为0时从SDHC上的SD/EMMC启动,为1时从SDHC2上的SD/EMMC启动
BOOT_CFG1[3] LCD_DATA3 当从SD/EMMC启动的时候设置启动速度,当从NAND启动的话设置NAND数量
BOOT_CFG1[4] LCD_DATA4 BOOT_CFG1[7:4]
0000 NOR/OneNAND(EIM)启动。
0001 QSPI 启动。
0011 SPI启动。
010x SD/eSD/SDXC启动。
011x MMC/eMMC启动。
1xxx NAND Flash启动。
BOOT_CFG1[5] LCD_DATA5
BOOT_CFG1[6] LCD_DATA6
BOOT_CFG1[7] LCD_DATA7
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!