参考教程:
正点原子【第二期】手把手教你学Linux之ARM(MX6U)裸机篇_哔哩哔哩_bilibili
一、SDK移植
1、SDK包说明
(1)在上一章进行驱动开发时,外设寄存器组结构体需要自己根据数据手册定义,当寄存器的数量越来越多时,这种开发方式就显得非常低效了。
(2)NXP官方其实提供了一个SDK包,包内有所有寄存器的定义,程序员在开发的时候,可以直接将包内的定义移植到工程中,这样就不需要重复定义了。
(3)SDK包可直接在NXP官网下载。

2、SDK包移植方式
(1)在NXP官网上下载的是一个.exe可执行程序,运行它之后,可以在指定目录生成所需要的配置文件,如下图所示。

(2)SDK包中有非常多的文件,如果只是针对裸机开发,那么真正有用的文件只有如下3个:
①fsl_common.h:位置为SDK_2.2_MCIM6ULL\devices\MCIMX6Y2\drivers\fsl_common.h
②fsl_iomuxc.h: 位置为SDK_2.2_MCIM6ULL\devices\MCIMX6Y2\drivers\fsl_iomuxc.h
③MCIMX6Y2.h: 位置为SDK_2.2_MCIM6ULL\devices\MCIMX6Y2\MCIMX6YH2.h
(3)以上三个文件中的内容仍然非常冗余,对于裸机开发,只需要保留IOMUXC引脚复用、PAD配置结构体及宏定义、GPIO等外设寄存器结构体和地址宏,其余内容(如CMSIS、SDK驱动、多芯片兼容代码、无关及缺失的头文件等)全部删除,由于改动的代码量较大,此处不详细展开。
二、程序编写与验证
1、启动配置文件编写
在Board_Drivers文件夹中新建文件夹“4_ledc_sdk”,然后将上一章的start.s文件拷贝至该文件夹中
2、外设配置文件编写
(1)在文件夹4_ledc_sdk中新建cc.h文件,里面存放一些SDK库文件需要使用到的数据类型别名,内容如下:
#ifndef __CC_H
#define __CC_H
#define __I volatile
#define __O volatile
#define __IO volatile
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef signed char s8;
typedef signed short int s16;
typedef signed int s32;
typedef signed long long int s64;
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef unsigned long long int u64;
#endif
(2)将上一小节提到的3个SDK包中的文件拷贝到文件夹4_ledc_sdk中,并做裁剪(裁剪的具体内容这里不详细展开)。
(3)原本cc.h文件中的定义在标准库stdint.h文件中已有实现,但裸机工程在编译时带参数“-nostdlib”,不链接C标准库,所以需要另行定义,并在SDK文件中原本包含stdint.h的地方包含cc.h文件。
3、C语言点灯程序编写
(1)将上一章的main.c文件拷贝至该文件夹中,因为点灯的业务代码和LED外设初始化的代码与上一章在功能上基本等价,只是初始化寄存器所调用的接口有变化。
(2)修改main.c文件中的内容:
①包含的头文件需要替换为:
#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
②LED的初始化函数需要更改,使用SDK提供的函数和宏完成GPIO初始化:
/*
* @description : 初始化 LED 对应的 GPIO
* @param : 无
* @return : 无
*/
void led_init(void)
{
/* 1、初始化 IO 复用, 复用为 GPIO1_IO03 */
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
/* 2、配置 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 低转换率
*/
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
/* 3、初始化 GPIO, GPIO1_IO03 设置为输出 */
GPIO1->GDIR = 0X0000008;
/* 4、设置 GPIO1_IO03 输出低电平,打开 LED0 */
GPIO1->DR &= ~(1 << 3);
}
(3)两个SDK初始化配置函数说明:
①IOMUXC_SetPinMux函数用于设置引脚的复用功能,其函数参数定义如下所示(按定义顺序说明)。
| 参数名 | 用途 |
| muxRegister | IO引脚MUX寄存器地址 |
| muxMode | IO复用值,也就是ALT值,决定该引脚复用何种功能 |
| inputRegister | 外设输入IO选择寄存器地址(IO复用为某个功能时可能需要设置外设多路输入IO选择寄存器,如串口RX功能,需要选择数据输入源) |
| inputDaisy | 外设输入IO选择寄存器配置值(不配置或者是配置为输出引脚,则写0) |
| configRegister | 未使用参数 |
| inputOnfield | IO软件输入使能标志 |
②IOMUXC_SetPinConfig函数用于设置引脚的电气属性。
| 参数名 | 用途 |
| muxRegister | 未使用参数 |
| muxMode | 未使用参数 |
| inputRegister | 未使用参数 |
| inputDaisy | 未使用参数 |
| configRegister | IO引脚PAD寄存器地址 |
| configValue | IO引脚PAD寄存器配置值 |
③这两个函数都有6个函数参数,但SDK提供的宏定义已经将IO引脚复用寄存器地址、复用值、外设输入IO寄存器地址、外设输入IO寄存器配置值、IO配置寄存器地址这5个参数集成在一起了。
[1]对上层来说,使用IOMUXC_SetPinMux函数,只需要指定想要配置的引脚功能和引脚的IO软件输入使能与否,SDK就能精确匹配要操作的MUX寄存器的地址,并将配置值写入。
[2]对上层来说,使用IOMUXC_SetPinConfig函数,只需要指定想要配置的引脚功能和要写入寄存器的值,SDK就能精确匹配要操作的PAD寄存器的地址,并将配置值写入。
4、Makefile文件与链接脚本编写
(1)由于本章例程的架构与上一章类似,故可直接复用上一章的Makefile,将其复制到本工程的根目录下即可,不过之前编写的Makefile通用性较差,如果有些变量产生变化,就需要改很多处地方,非常麻烦,对此可以进行优化,如下所示。
# 如果外部没有定义,才赋值(方便命令行覆盖:make CROSS_COMPILE=xxx)
CROSS_COMPILE ?= arm-linux-gnueabihf-
NAME ?= ledc
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
# 需要编译的目标文件列表
OBJS := start.o main.o
$(NAME).bin: $(OBJS)
# 使用链接脚本 imx6ul.lds,链接输出 elf
$(LD) -T imx6ul.lds -o $(NAME).elf $^
# 从 elf 提取纯二进制 bin;-S:去掉重定位、符号信息
$(OBJCOPY) -O binary -S $(NAME).elf $@
# 反汇编,生成 dis 汇编查看文件
$(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis
%.o: %.s
$(CC) -Wall -nostdlib -c -O2 -o $@ $<
%.o: %.S
$(CC) -Wall -nostdlib -c -O2 -o $@ $<
%.o: %.c
$(CC) -Wall -nostdlib -c -O2 -o $@ $<
.PHONY: clean
clean:
rm -rf *.o $(NAME).bin $(NAME).elf $(NAME).dis
(2)除了Makefile以外,链接脚本也可直接复用,将上一章的imx6u.lds复制到本工程的根目录下即可。
5、程序烧写验证
(1)将imxdownload拷贝到工程的根目录下,也就是和ledc.bin处于同一个文件夹下,并赋予其可执行权限。
(2)将SD卡接入虚拟机,然后在当前目录运行命令“./imxdownload ledc.bin /dev/sdb”即可将固件刷入SD卡(设备名需要核对,与/dev下的设备名一致),然后在开发板上验证即可。
445



被折叠的 条评论
为什么被折叠?



