1、汇编语言来初始化 I.MX6U 外设 寄存器、了解 I.MX6UL 最基本的 IO 输出功能。
2、STM32 的 GPIO 操作流程
①、
使能
指定
GPIO
的
时钟
。
②、
初始化 GPIO
,比如
输出功能、上拉、速度
等等。
③、
STM32
有的
IO
可以作为其它外设引脚,也就是
IO
复用,如果要将
IO
作为其它外设
引脚使用的话就需要设置
IO
的
复用
功能。
④、最后设置
GPIO
输出高
电平或者
低
电平。
3、“
IOMUXC_SW_MUC_CTL_PAD_
XX_XX
”,后面的“
XX_XX
”就是
GPIO
命名
IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA”这个 IO,这个 IO 对应的复用。
观察
芯片的
数据手册 和
用户参考手册 (
芯片官网获取) 查找
寄存器地址 和
bit 位含义
IOMUXC_SW_
MUX_
CTL_PAD_GPIO1_IO00 复用 寄存器地址为
0X020E005C
IOMUXC_SW_ PAD _CTL_PAD_GPIO1_IO00 高低配置 寄存器地址为 0X020E02E8
IOMUXC_SW_ PAD _CTL_PAD_GPIO1_IO00 高低配置 寄存器地址为 0X020E02E8
OMUXC_SW_MUX_CTL_PAD_XX_XX 和 IOMUXC_SW_PAD_CTL_PAD_XX_XX 这两
种寄存器都是配置 IO 的
,注意是
IO
!不是
GPIO
,
GPIO
是一个
IO
众多复用功能中的一种。比
如
GPIO1_IO00
这个
IO
可以复用为:
I2C2_SCL、GPT1_CAPTURE1、ANATOP_OTG1_ID、
ENET1_REF_CLK 、 MQS_RIGHT 、 GPIO1_IO00 、 ENET1_1588_EVENT0_IN 、
SRC_SYSTEM_RESET 和 WDOG3_WDOG_B 这 9 个功能
,
GPIO1_IO00
是其中的一种,我们
想要把
GPIO1_IO00 用作哪个外设就复用为哪个外设功能
即可。
4、GPIO 操作流程总结:
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 direcrion 输出模式
GPIO1_IO03
是作为输出功能的,因此
GPIO1_GDIR
的
bit3
要设置为
1
,表示输
出。
只需要向 GPIO1_DR 寄存器的 bit3 写入 0 即 可控制 GPIO1_IO03 输出低电平,打开 LED,向 bit3 写入 1 可控制 GPIO1_IO03 输出高电平, 关闭 LED。
5、源码的编译:
其中
0X08000000
就是
STM32
内
部
ROM 的起始地址
,编译出来的指令肯定是要从
0X08000000
这个地址开始存放的。
这里我们要区分“
存储地址
”和“
运行地址
”这两个概念,“
存储地址
”就是可执
行文件存储在哪里,可执行文件的存储地址可以随意选择。“
运行地址
”就是代码运行的时候
所处的地址,这个我们在链接的时候就已经确定好了,代码要运行,那就必须处于
运行地址
处
,否则代码肯定运行出错。
比如
I.MX6U
支持
SD
卡、
EMMC
、
NAND
启动,因此代码可以
存储到
SD
卡、
EMMC
或者
NAND
中,但是要运行的话就必须将代码从
SD
卡、
EMMC
或者
NAND
中
拷贝到其运行地址(链接地址)处
,“
存储地址”和“运行地址”可以一样
,比如
STM32
的
存储起始地址和运行起始地址都是 0X08000000
。
1、上电以后
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
,这样我们统一使用
0X87800000
这个链接地址,不容易记混。
2、arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf.
-Ttext
就是指定链接地址,“
-o
”选项指定链接生成的
elf
文件名
led.elf
文件转换为
.bin 文件 arm-linux-gnueabihf-objcopy
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
4、反汇编调试
因此就需要进行反汇编,一般可以将
elf
文件反汇编,比如如下命令:
arm-linux-gnueabihf-objdump -D led.elf > led.dis
6、uboot代码 裸板 烧写:
stm32 :我们学习 STM32 等其他的单片机的时候,编译完代码以后可以直接通过 MDK 或者 IAR
下载到内部的
flash
中。
i.mx6u :I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP
自己用的,
不向用户开放
。所以相当于说
I.MX6U
是没有内部
flash
的,但是我们的代码得有地
方存放啊,为此,
I.MX6U
支持从
外置
的
NOR Flash
、
NAND Flash
、
SD/EMMC
、
SPI NOR Flash
和
QSPI Flash
这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中.
在这些存 储介质中,除了 SD
卡以外,其他的一般都是焊接到了板子上的,我们没法直接烧写。但是
SD 卡是活动的,是可以从板子上插拔的,我们可以将 SD
卡插到电脑上,在电脑上使用软件将
.
bin 文件
烧写到
SD 卡
中. 然后
再插到板子上就可以了
.
调试裸机和
Uboot
的时候是将代码下载到
SD
中,因为方便嘛,当调试完成 以后量产的时候要将
裸机
或者
Uboot
烧写到
SPI NOR Flash
、
EMMC
、
NAND
等这些存储介质 中的。
led.bin
到
SD
卡中不就行了,错!编译出来的可执行文件是怎么存放到
SD
中的,存放的位置是
什么?这个
NXP 是有详细规定的!我们必须按照
NXP 的规定来将代码烧写到 SD 卡中,否则 代码是绝对运行不起来的。
《
IMX6UL
参考手册》的第
8
章“
Chapter 8 System Boot
”就是专门 讲解
I.MX6U 启动的
,我们下一章会详细的讲解
I.MX6U 启动方式
的. imxdownload 下载到 SD卡中。只能再ubuntu中用。
开发板光盘
->5
、开发工具
->2
、 Ubuntu 下裸机烧写软件
->imxdownload
chmod 777 imxdownload.
插上 sd卡 查看 ls /dev/sd*
因为只有 /dev/sdd 有个对应的/dev/sdd1,/dev/sdd 是我的 SD 卡,/dev/sdd1 是 SD 卡 的第一个分区
.
./imxdownload <.bin file>
./imxdownload led.bin /dev/sdd
//
不能烧写到
/dev/sda
或
sda1
设备里面!那是系统磁盘
load.imx
这个文件就是软件
imxdownload
根据
NXP
官方启动方式介绍的内容,
在 led.bin 文
件前面添加了一些数据头以后生成的
。
代码已经烧写到了
SD 卡中
了,接下来就是将
SD 卡
插到
开发板的 SD 卡槽中
,然后设置拨
码开关为
SD 卡启动
,
拨码开关设置
如图
8.4.4.1
所示:
后面所有
裸机代码 和
UBoot 代码都是采用
SD卡 启动的方式 烧写代码进行验证。