Linux学习笔记8---官方 SDK 移植实验

        在上一章中,我们参考 ST 官方给 STM32 编写的 stm32f10x.h 来自行编写 I.MX6U 的寄存器定义文件。自己编写这些寄存器定义不仅费时费力,没有任何意义,而且很容易写错,幸好NXP 官方为 I.MX6ULL 编写了 SDK 包,在 SDK 包里面 NXP 已经编写好了寄存器定义文件,所以我们可以直接移植 SDK 包里面的文件来用。虽然 NXP 是为 I.MX6ULL 编写的 SDK 包,但是 I.MX6UL 也是可以使用的!本章我们就来讲解如何移植 SDK 包里面重要的文件,方便我们的开发。

1、官网SDK下载

I.MX6ULL 的 SDK 包在 NXP 官网下载,下载界面如图所示:

下载链接:i.MX 6ULL应用处理器NXP官网下载链接

将下载下来的SDK_2.2_MCIM6ULL_RFP_Win.exe文件安装完成以后的SDK如图所示:

所有的例程都在 boards 这个文件夹里面。我们重点是需要 SDK 包里面与寄存器定义相关的文件,一共需要如下三个文件:
        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。
整个 SDK 包我们就需要上面这三个文件,把这三个文件准备好,我们后面移植要用。

2、 硬件原理分析

 

        可以看出,LED0 接到了 GPIO_3 上,GPIO_3 就是 GPIO1_IO03,当 GPIO1_IO03输出低电平(0)的时候发光二极管 LED0 就会导通点亮,当 GPIO1_IO03 输出高电平(1)的时候发光二极管 LED0 不会导通,因此 LED0 也就不会点亮。所以 LED0 的亮灭取决于 GPIO1_IO03的输出电平,输出 0 就亮,输出 1 就灭。

3、 SDK 文件移植

新建一个工程,将 fsl_common.h、fsl_iomuxc.h 和 MCIMX6Y2.h 这三个文件拷贝到工程中,需要对其不需要的地方进行删减,修改完成以后的工程目录如图所示:

4、创建 cc.h 文件

新建一个名为 cc.h 的头文件,cc.h 里面存放一些 SDK 库文件需要使用到的数据类型,在cc.h 里面输入如下代码:

#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	  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

        在 cc.h 文件中我们定义了很多的数据类型,因为有些第三方库会用到这些变量类型。

5、编写实验代码

        新建 start.S 和 main.c 这两个文件,start.S 文件的内容和上一章一样,直接复制过来就可以,创建完成以后工程目录如图所示:

在 main.c 中输入如下所示代码:

#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"

/*
 * @description	: 使能I.MX6U所有外设时钟
 * @param 		: 无
 * @return 		: 无
 */
void clk_enable(void)
{
	CCM->CCGR0 = 0XFFFFFFFF;
	CCM->CCGR1 = 0XFFFFFFFF;

	CCM->CCGR2 = 0XFFFFFFFF;
	CCM->CCGR3 = 0XFFFFFFFF;
	CCM->CCGR4 = 0XFFFFFFFF;
	CCM->CCGR5 = 0XFFFFFFFF;
	CCM->CCGR6 = 0XFFFFFFFF;

}

/*
 * @description	: 初始化LED对应的GPIO
 * @param 		: 无
 * @return 		: 无
 */
void led_init(void)
{
	/* 1、初始化IO复用 */
	IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);		/* 复用为GPIO1_IO0 */

	/* 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 |= (1 << 3);	
	
	/* 4、设置GPIO1_IO03输出低电平,打开LED0 */
	GPIO1->DR &= ~(1 << 3);			
}

/*
 * @description	: 打开LED灯
 * @param 		: 无
 * @return 		: 无
 */
void led_on(void)
{
	/* 将GPIO1_DR的bit3清零 	*/
	GPIO1->DR &= ~(1<<3); 
}

/*
 * @description	: 关闭LED灯
 * @param 		: 无
 * @return 		: 无
 */
void led_off(void)
{
	/* 将GPIO1_DR的bit3置1 */
	GPIO1->DR |= (1<<3); 
}

/*
 * @description	: 短时间延时函数
 * @param - n	: 要延时循环次数(空操作循环次数,模式延时)
 * @return 		: 无
 */
void delay_short(volatile unsigned int n)
{
	while(n--){}
}

/*
 * @description	: 延时函数,在396Mhz的主频下
 * 			  	  延时时间大约为1ms
 * @param - n	: 要延时的ms数
 * @return 		: 无
 */
void delay(volatile unsigned int n)
{
	while(n--)
	{
		delay_short(0x7ff);
	}
}

/*
 * @description	: mian函数
 * @param 		: 无
 * @return 		: 无
 */
int main(void)
{
	clk_enable();		/* 使能所有的时钟 			*/
	led_init();			/* 初始化led 			*/

	while(1)			/* 死循环 				*/
	{	
		led_off();		/* 关闭LED 			*/
		delay(500);		/* 延时500ms 			*/

		led_on();		/* 打开LED 			*/
		delay(500);		/* 延时500ms 			*/
	}

	return 0;
}

和上一章一样,main.c 有 7 个函数,这 7 个函数的含义都一样,只是本例程我们使用的是移植好的 NXP 官方 SDK 里面的寄存器定义。main.c 文件的这 7 个函数的内容都很简单,前面都讲过很多次了,我们重点来看一下 led_init 函数中的第 31 行和第 43 行,这两行的内容如下:

IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0X10B0);

这 里 使 用 了 两 个 函 数 IOMUXC_SetPinMux 和 IOMUXC_SetPinConfig , 其 中 函 数IOMUXC_SetPinMux 是用来设置 IO 复 用 功 能 的 , 最 终 肯 定 设 置 的 是 寄 存 器“IOMUXC_SW_MUX_CTL_PAD_XX”。函数 IOMUXC_SetPinConfig 设置的是 IO 的上下拉、速度等的,也就是寄存器“IOMUXC_SW_PAD_CTL_PAD_XX”,所以上面两个函数其实就是上一章中的:

IOMUX_SW_MUX->GPIO1_IO03 = 0X5;
IOMUX_SW_PAD->GPIO1_IO03 = 0X10B0;

函数 IOMUXC_SetPinMux 在文件 fsl_iomuxc.h 中定义,函数源码如下:

static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
                                                                  uint32_t muxMode,
                                                                  uint32_t inputRegister,
                                                                  uint32_t inputDaisy,
                                                                  uint32_t configRegister,
                                                                  uint32_t inputOnfield)
 {
        *((volatile uint32_t *)muxRegister) =
                 IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | 
                         IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
         if (inputRegister)
         {
                 *((volatile uint32_t *)inputRegister) = 
                         IOMUXC_SELECT_INPUT_DAISY(inputDaisy);
         }
 }

 函数 IOMUXC_SetPinMux 有 6 个参数,这 6 个参数的函数如下:

        muxRegister : IO 的 复 用 寄 存 器 地 址 , 比 如 GPIO1_IO03 的 IO 复 用 寄 存 器SW_MUX_CTL_PAD_GPIO1_IO03 的地址为 0X020E0068。
        muxMode: IO 复用值,也就是 ALT0~ALT8,对应数字 0~8,比如要将 GPIO1_IO03 设置为 GPIO 功能的话此参数就要设置为 5。
        inputRegister:外设输入 IO 选择寄存器地址,有些 IO 在设置为其他的复用功能以后还需要设置 IO 输入寄存器,比如 GPIO1_IO03 要复用为 UART1_RX 的话还需要设置寄存器UART1_RX_DATA_SELECT_INPUT,此寄存器地址为 0X020E0624。
        inputDaisy:寄存器 inputRegister 的值,比如 GPIO1_IO03 要作为 UART1_RX 引脚的话此参数就是 1。
        configRegister:未使用,函数 IOMUXC_SetPinConfig 会使用这个寄存器。
        inputOnfield : IO 软件输入使能,以 GPIO1_IO03 为例就是寄存器SW_MUX_CTL_PAD_GPIO1_IO03 的 SION 位(bit4)。如果需要使能 GPIO1_IO03 的软件输入功能的话此参数应该为 1,否则的话就为 0。
        IOMUXC_SetPinMux 的函数体很简单,就是根据参数对寄存器 muxRegister 和inputRegister进行赋值。在“示例代码”中的 31 行使用此函数将 GPIO1_IO03 的复用功能设置为GPIO,如下:

IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);

其中IOMUXC_GPIO1_IO03_GPIO1_IO03 是个宏,在文件fsl_iomuxc.h 中有定义,NXP 的 SDK 库将一个 IO 的所有复用功能都定义了一个宏,比如GPIO1_IO03 就有如下 9 个宏定义:

IOMUXC_GPIO1_IO03_I2C1_SDA
IOMUXC_GPIO1_IO03_GPT1_COMPARE3 
IOMUXC_GPIO1_IO03_USB_OTG2_OC 
IOMUXC_GPIO1_IO03_USDHC1_CD_B 
IOMUXC_GPIO1_IO03_GPIO1_IO03 
IOMUXC_GPIO1_IO03_CCM_DI0_EXT_CLK 
IOMUXC_GPIO1_IO03_SRC_TESTER_ACK 
IOMUXC_GPIO1_IO03_UART1_RX 
IOMUXC_GPIO1_IO03_UART1_TX

上面 9 个宏定义分别对应着 GPIO1_IO03 的九种复用功能,比如复用为 GPIO 的宏定义就是:

#define IOMUXC_GPIO1_IO03_GPIO1_IO03 0x020E0068U, 0x5U, 0x00000000U, 
                                                                          0x0U, 0x020E02F4U

将这个宏带入到“示例代码”的 31 行以后就是:

IOMUXC_SetPinMux (0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U, 0);

        接下来看一下函数 IOMUXC_SetPinConfig,此函数同样在文件 fsl_iomuxc.h 中有定义,函数源码如下:

static inline void IOMUXC_SetPinConfig(uint32_t muxRegister,
                                                                         uint32_t muxMode,
                                                                         uint32_t inputRegister,
                                                                         uint32_t inputDaisy,
                                                                         uint32_t configRegister,
                                                                         uint32_t configValue)
{
         if (configRegister)
         {
                 *((volatile uint32_t *)configRegister) = configValue;
         }
}

函数 IOMUXC_SetPinConfig 有 6 个参数,其中前五个参数和函数 IOMUXC_SetPinMux 一样,但是此函数只使用了参数 configRegister 和 configValue,cofigRegister 参数是 IO 配置寄存器地址,比如 GPIO1_IO03 的 IO 配置寄存器为 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03,其地址为 0X020E02F4,参数 configValue 就是要写入到寄存器 configRegister 的值。同理,“示例代码”的 43 行展开以后就是:

IOMUXC_SetPinConfig(0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U,                                                                 0X10B0);

        main.c 就讲到这里,基本和上一章一样,只是我们使用了 NXP 官方写好的寄存器定义,以后就可以使用这两个函数来方便的配置 IO 的复用功能和 IO 配置。

6、编写 Makefile 和链接脚本

新建 Makefile 文件,Makefile 文件内容如下:

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)
	$(LD) -Timx6ul.lds -o $(NAME).elf $^
	$(OBJCOPY) -O binary -S $(NAME).elf $@
	$(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 $@ $<
	
clean:
	rm -rf *.o $(NAME).bin $(NAME).elf $(NAME).dis
	
	

本章实验的 Makefile 文件是在第6章中的 Makefile 上修改的,只是使用到了变量。链接脚本 imx6ul.lds 的内容和上一章一样,可以直接使用上一章的链接脚本文件。

7、编译下载

        使用 Make 命令编译代码,编译成功以后使用软件 imxdownload 将编译完成的 ledc.bin 文件生成可执行的img文件。

make 
./imxdownload2 ledc.bin

 利用Win32DiskImager软件将load.img执行文件写入SD卡,SD卡插入开发板上即可正常运行。如果代码运行正常的话 LED0 就会以 500ms 的时间间隔亮灭。

8、实验代码

【免费】Linux学习笔记8-官方SDK移植实验代码资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/617866.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue+Mysql的校园闲置物品租售系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

C++小程序:同一路由器下两台计算机间简单通信(2/2)——客户端

客户端的程序结构前半部分与服务器端基本相同&#xff0c;后半部分也相对简单。相关函数的解释可以参考前文服务器端的内容。有关客户端的内容除个别地方外&#xff0c;就不再做长篇大论的解释。强调一点&#xff0c;如果将此程序移到其它电脑上运行&#xff0c;编译需要releas…

Linux网络编程】传输层中的TCP和UDP(UDP篇)

【Linux网络编程】传输层中的TCP和UDP&#xff08;UDP篇&#xff09; 目录 【Linux网络编程】传输层中的TCP和UDP&#xff08;UDP篇&#xff09;传输层再谈端口端口号范围划分认识知名端口号netstatiostatpidofxargs UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲数据UDP使…

20-LINUX--网络编程

一. 主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序&#xff0c;不同的主机采用的字节序列可能不同。大 端字节序是指一个整数的高位字节存储在内存的低地址处&#xff0c;低位字节存储在内存的高地址 处。小端字节序则是指整数的高位字节存储在内存的高…

CentOS 8.5 安装配置 Tinyproxy 轻量代理服务器 Windows10 系统设置http代理 详细教程

1 下载 下载地址 2 上传服务器并解压 tar zxvf tinyproxy-1.11.2.tar.gz 3 安装配置 #安装依赖软件 yum install automake cd tinyproxy-1.11.2/ #生成configure ./autogen.sh # ./configure --prefix/usr/local/tinyproxy make make install 4 配置环境 vim /etc/prof…

四川汇昌联信:拼多多运营属于什么行业?

拼多多运营属于什么行业?这个问题看似简单&#xff0c;实则涉及到了电商行业的深层次理解。拼多多运营&#xff0c;顾名思义&#xff0c;就是在拼多多这个电商平台上进行商品销售、推广、客户服务等一系列活动。那么&#xff0c;这个行业具体包含哪些内容呢?下面就从四个不同…

【计算机毕业设计】用于日语词汇学习的微信小程SSM

日语词汇学习小程序是高校人才培养计划的重要 组成部分&#xff0c;是实现人才培养目标、培养学生科研能力与创新思维、检验学生综合素质与实践能力的重要手段与综合性实践教学环节。本学生所在学院多采用半手工管理日语词汇学习小程序的方式&#xff0c;所以有必要开发日语词汇…

深度学习--DCGAN

代码之后的注释和GAN的一样&#xff0c;大家如果已经掌握GAN&#xff0c;可以忽略掉哦&#xff01;&#xff01;&#xff01; 在学习DCGAN之前&#xff0c;我们要先掌握GAN&#xff0c;深度学习--生成对抗网络GAN-CSDN博客 这篇博客讲的就是GAN的相关知识&#xff0c;还是很详…

吃掉 N 个橘子的最少天数

代码实现&#xff1a; 方法一&#xff1a;递归——超时 #define min(a, b) ((a) > (b) ? (b) : (a))int minDays(int n) {if (n 1 || n 2) {return n;}if (n % 3 0) {if (n % 2 0) {return min(min(minDays(n - 1), minDays(n / 2)), minDays(n - 2 * (n / 3))) 1;} e…

引擎:主程渲染

一、引擎发展 二、引擎使用 1.游戏渲染流程 2.3D场景编辑器操作与快捷键 3.节点的脚本组件 脚本介绍 引擎执行流程 物体节点、声音组件\物理组件\UI组件、脚本组件 暴露变量到面板 4.节点的查找 基本查找 this.node&#xff1a;挂载当前脚本的节点A&#xff1b; this.nod…

echarts环形图 legend文字过长显示...鼠标移动上展示全称

legend: {type: scroll,orient: vertical,x: left,y: bottom,top: "42%",left: 13%,data: this.dutyNames,textStyle: { color: #fff },triggerEvent: true,tooltip: {show: true,trigger: item,//鼠标移动上去展示全称},formatter: function (params) {var val &qu…

【每日刷题】Day38

【每日刷题】Day38 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 2696. 删除子串后的字符串最小长度 - 力扣&#xff08;LeetCode&#xff09; 2. LCR 123. 图书整理…

使用 Spring Boot 配合策略模式增强系统接口扩展能力

使用 Spring Boot 配合策略模式增强系统接口扩展能力 在软件开发中&#xff0c;系统的可扩展性是一个至关重要的方面。而策略模式是一种常见的设计模式&#xff0c;它可以帮助我们实现灵活的算法选择和系统功能扩展。结合 Spring Boot 框架&#xff0c;我们可以更加方便地利用策…

域控操作十四:统一修改域控内计算机用户头像

1&#xff0c;Windows默认头像存储路径&#xff0c;所以我们把这里面的图片都改成自己想要的头像&#xff0c;然后写策略强制使用默认头像就行了 此设置是替换默认头像使用 此设置是为设置默认头像

039——解决室内不能使用GPS问题

目录 引入 GUI整改 client添加GPS分析 完善服务器网络通讯部分代码 添加GPS的BSW层 GPS操作部分代码&#xff08;相当于驱动&#xff09; 效果展示 项目管理操作 引入 最近在写论文加上出去玩了一圈所以停更了一段时间。上次咱们GPS有个室内用不了的问题&#xff0c;咱…

本地vite启动的vue项目使用nginx代理

前提&#xff1a; 必须在同一网段或者相同的局域网&#xff01;&#xff01;&#xff01; nginx下载通道&#xff1a; https://nginx.org/en/download.html 步骤&#xff1a; 1、最好下载稳定版本&#xff1a; 2、下载后直接解压&#xff08;注意&#xff1a;解压后不要放…

C++入门系列-拷贝构造函数

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 拷贝构造函数 概念 在创建对象的时候&#xff0c;能不能创建一个和已知已存在的对象一模一样的对象呢&#xff1f; 拷贝构造函数&#xff1a;只有单个形参&#xff0c;该形参…

【JavaWeb】Day74.Spring——AOP进阶(连接点)

连接点 连接点可以简单理解为可以被AOP控制的方法。我们目标对象当中所有的方法不是都是可以被AOP控制的方法。而在SpringAOP当中&#xff0c;连接点又特指方法的执行。 在Spring中用JoinPoint抽象了连接点&#xff0c;用它可以获得方法执行时的相关信息&#xff0c;如目标类名…

Mybatis操作数据库的两种方式:原生API

mybatis操作数据的两种方式&#xff1a;原生api和mapper代理对象 1.mybatis的api提供的方法 insert() 增加 delete() 删除 update() 更新 selectOne() 返回一个数据 selectList() 返回多个数据&#xff0c;结果类型为List selectMap() 返回多个数据&…

算法学习系列(六十):区间DP

目录 引言区间合并模板一、石子合并二、环形石子合并三、能量项链 引言 关于这个区间 D P DP DP &#xff0c;其实是有套路和模板的&#xff0c;题型的话也是变化不多&#xff0c;感觉就那几种&#xff0c;只不过有些题会用到高精度或者是要记录方案&#xff0c;所以整体来说…