LV04-03-BSP工程管理-01-NXP官方SDK
本文主要是使用官方提供的SDK来驱动LED的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows版本 | windows11 |
Ubuntu版本 | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) |
Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
Win32DiskImager | Win32DiskImager v1.0 |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
https://elixir.bootlin.com/linux/latest/source | 在线阅读linux kernel源码 | |
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga | NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga | NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) |
一、I.MX6ULL 官方 SDK 包简介
1. SDK简介
NXP 针对 I.MX6ULL 编写了一个 SDK 包,这个 SDK 包就类似于 STM32 的 STD 库或者HAL 库,对于这个 SDK 包的安装方式,NXP提供了 Windows 和 Linux 两种版本,分别针对主机系统是 Windows 和Linux(意思就是SDK的安装就跟软件安装一样,后边就会看到啦)。因为我们是在 Windows 下使用 Source Insight 来编写代码的,因此我们使用的是 Windows版本的。
Windows 版本 SDK 里面的例程提供了 IAR 版本,肯定有人会问既然 NXP 提供了 IAR版本的 SDK,那我们为什么不用 IAR 来完成裸机试验,偏偏要用复杂的 GCC?因为我们要从简单的裸机开始掌握 Linux 下的 GCC 开发方法,包括 Ubuntu 操作系统的使用、 Makefile 的编写、 shell 等等。如果为了偷懒而使用 IAR 开发裸机的话,那么后续学习 Uboot 移植、 Linux 移植和 Linux 驱动开发就会很难上手,因为开发环境都不熟悉!再者,不是所有的半导体厂商都会为 Cortex-A 架构的芯片编写裸机 SDK 包,我使用过那么多的 Cotex-A 系列芯片,也就发现了 NXP 给 I.MX6ULL 编写了裸机 SDK 包。而且去 NXP 官网看一下,会发现只有 I.MX6ULL这一款 Cotex-A 内核的芯片有裸机 SDK 包, NXP 的其它 Cotex-A 芯片都没有。说明在 NXP 的定位里面, I.MX6ULL 就是一个 Cotex-A 内核的高端单片机,定位类似 ST 的 STM32H7。
总的来说就是,使用 Cortex-A 内核芯片的时候不要想着有类似 STM32 库一样的东西, I.MX6ULL 是一个特例,基本所有的 Cortex-A 内核的芯片都不会提供裸机 SDK 包。因此在使用 STM32 的时候那些用起来很顺手的库文件,在 Cotex-A 芯片下基本都需要我们自行编写,比如.s 启动文件、寄存器定义等等。
2. 在哪下载?
我们来到官网:i.MX 6ULL应用处理器_Arm® Cortex®-A7单核,频率为900 MHz | NXP 半导体,找到这个页面:
我们在windows下安装库的话,就选下边的WIN版进行安装就行。Linux下的话就选第一个。他们只是安装程序不同罢了,安装后得到的SDK库文件是一样的。例如,在windows环境下,我们选择的第二个,下完后会得到这样一个可执行文件:
如果是选linux,会得到一个.run文件:
3. Windows下的SDK安装
我们双击上边的exe可执行文件,就会进入SDK的安装流程,一直 next 下一步就好啦,然后在这里我们要选择一下安装的位置:
然后继续一直下一步就可以啦,安装完成如下所示:
然后我们来看一下安装目录下的文件:
我们就不重点学习这个 SDK 包了,所有的例程都在 boards 这个文件夹里面。我们重点是需要 SDK 包里面与寄存器定义相关的文件,一共需要如下三个文件:
fsl_common.h:位置为 SDK_2.2_MCIM6ULL/devices/MCIMX6Y2/driver/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 包我们就需要上面这三个文件,把这三个文件准备好,我们后面移植要用。
4. Linux下的SDK安装
我们拷贝到ubuntu中后,直接./xxx.run即可执行:
这里我们选择同意,然后来到这里:
这里是选择安装目录,前两个都是默认路径,想安装到哪里的话可以选择,不过我安装到这个路径下:
1 | /home/sumu/7Linux/SDK_2.2_MCIM6ULL/ |
所以选择第三个,然后输入路径后按下确认:
这里继续确认,确认后目录不存在的花灰提示创建:
这里我们选择创建即可,然后就是一直按确定就行了,最后来到安装的部分:
这里注意一下路径是否则正确,然后选择安装即可。安装完毕会退出这个图形界面,并且给出提示:
然后我们来看一下都有哪些文件:
其实文件跟windows下是一样的。
二、SDK目录、文件简介
主要后面还是在linux中开发,所以这里就以linux下的SDK为例。关于这个目录和文件的介绍可以看这个文件:
这个会有很多的说明。
1 | sumu@sumu-virtual-machine:~/7Linux/SDK_2.2_MCIM6ULL$ tree -L 1 |
1. boards:示例程序
SDK的boards目录包含了NXP官方评估版MCIMX6ULL-EVK的各种示例程序。例如,下图是“boards/evkmcimx6ull”目录。
这些文件夹的说明如下:
- demo_apps:包含了一些应用范例,如串口打印“hello world”、使用lwip协议栈进行网络通讯等内容
- driver_examples包含了i.mx6主要片上外设的使用范例。
- project_template包含了官方示例使用的一些必备文件,这些文件主要是针对官方评估板做了一些引脚定义、时钟配置等功能。
- rtos_examples包含了使用FreeRTOS实时操作系统的应用范例。
- usb_examples包含了各种USB程序示例。USB设备种类繁多且驱动复杂, 参考官方的这些示例能快速建立自己需要的USB应用。
2. CMSIS:包含CMSIS标准相关的文件
在2.2版本的SDK中,CMSIS只有一个GCC 相关头文件,使用到时我们将会详细学习。
3. CORTEXA:Cortex相关头文件
SDK目录下的CORTEXA文件夹包含了cortexa核适配iar、gcc的头文件。我们暂时不需要研究它们的作用。
4. devices:i.mx固件库
SDK中的devices目录包含的内容就是外设驱动固件库,该目录下的MCIMX6Y2文件夹即是针对开发板板载芯片对应的固件库:
4.1 MCIMX6Y2目录下的全局文件
在MCIMX6Y2根目录下,可发现它直接包含一些文件,这些文件非常重要,是使用固件库编程最基础的部分。
(1)fsl_device_registers.h文件:根据CPU型号包含相应的头文件(在开发环境的全局宏定义中应根据CPU 指定芯片型号)。固件库通常可以兼容很多型号的芯片,不同的芯片部分寄存器定义、芯片特性等内容可能会有差异。通过这样的条件编译代码,就可以根据宏来包含不同的头文件,达到兼容不同芯片的目的了。当前仅支持一种芯片。
(2)MCIMX6Y2.h文件:它主要是包含i.MX6芯片的各种寄存器定义和中断编号定义,是非常重要,非常基础的一个头文件。 会在前面fsl_device_registers.h文件中就根据CPU型号添加这个文件。
(3)MCIMX6Y2_features.h:此文件主要定义了一些关于i.MX6芯片特性的内容,例如我们想知道本芯片有多少个IIS外设或UART外设,可以在这个文件中找到。在前面的fsl_device_registers.h的内容中也包含了这个文件。
(4)system_MCIMX6Y2.c/h文件:system_MCIMX6Y2包含一个源文件和头文件。其中头文件system_MCIMX6Y2.h中主要包含时钟定义以及源文件相应函数的声明。而源文件system_MCIMX6Y2.c中则主要包含系统初始化和配置系统时钟的函数。
(5)MCIMX6Y2.xml文件:MCIMX6Y2.xml文件是NXP的开发环境需要的一些记录信息。
4.2 gcc目录
Windows版本的SDK还会有一个iar目录,在不同的编译平台下,使用汇编语言编写的启动文件、各种版本的分散加载文件的语法稍有区别,所以固件库把这些内容放在独立的文件夹。gcc和iar文件夹分别对应ARM-GCC和IAR开发环境,这些文件夹内的文件功能是一样的。这里linux版本的SDK只有gcc目录,我们看一下:
这里都是一些链接文件。
4.3 drivers目录
drivers目录是固件库的主体,有时我们把这些文件称为外设驱动库,具体如下所示:
- 这些文件都使用fsl_xxx.c/h的命名格式,其中xxx是对应的片上 外设名字,如ADC、GPIO、UART、I2C等外设,大部分外设包含一个C源文件和头文件。
- 当使用到某个外设时,我们会把此处对应的外设驱动源文 件添加到工程中,加入编译,对于没有源文件的IOMUXC外设,则直接使用“#include”包含其头文件fsl_iomuxc.h。
- 特别地,其中的fsl_common.c和fsl_common.h中的common不是i.MX6芯片 的某个外设名字,它表示绝大多数工程都会需要这些“共同”的内容,所以一般工程都 会添加这个fsl_common.c文件,并且可以通过fsl_common.h文件包含前面介绍的fsl_device_regi sters.h头文件,达到最终包含具有大量寄存器定义的MCIMX6Y2.h核心头文件的目的。
4.4 utilities目录
utilities是实用工具集的意思,此目录下包含了开发常用的一些调试工具,如串口输出、运行日志,通常我们都会把这些文件加到工程以方便开发。
5. docs:部分说明文档
回到SDK的根目录,打开它的docs文件夹,可见到文件夹中包含如下图中的内容:
这目录下有个《Getting Started with MCUXpresso SDK for i.MX 6ULL Derivatives》文件,它介绍了使用官方评估板时的基础使用步骤。文件夹 lwip、rtos、usb、分别保存对应的说明文档。文件夹MCUXpresso SDK API Reference Manual_MCIMX6Y2保存有.html格式的SDK API接口函数说明文档。
6. middleware:中间件
SDK中的middleware文件夹主要包含一些中间层软件,即这些软件常为应用层提供一些协议、架构上的支撑,它的主要部分又与芯片底层的硬件外设驱动(前面drivers目录中的文件)联系不甚紧密,是不同芯片之间通用的一些构件:
- fatfs :这是一个嵌入式常用的文件系统,有了文件系统后能更好地管理存储器以及使用通用的文件形式来访问存储器。
- lwip :这是嵌入式常用网络TCP/IP协议栈,使用协议栈可以方便地接入网络。
- sdmmc :它是遵照SDIO协议编写的集成识别、读写SD存储卡功能的驱动。
- usb :包含了遵照USB协议编写的基本驱动,在它之上可方便地编写USB应用程序。
7. rtos:实时操作系统
SDK目录下的rtos文件夹包含了FreeRTOS实时操作系统的源代码,位于“boards/evkmcimx6ull/rtos_examples”目录的FreeRTOS例程会使用到这里的源码,我们只需要知道源码再这里就可以了。
8. tools:开发工具
各个文件中间件的简要说明如下:
- cmake_toolchain_files :提供cmake工具,用于生成arm gcc编译器需要的makefile文件。
- imgutil :提供图片压缩工具。
- mfgtools 与 mfgtools-with-rootfs (Windows SDK中会有这个):提供MFG批量下载工具,
9. 其它文件
在SDK的根目录下还包含了几个.xml、.txt、.htm以及.bat文件:
.xml和txt文件它们主要是包含SDK第三方构件的一些版权、出处说明以及EVK-MCIMX6UL生成的一些说明信息,Windows版本SDK中还会有keilkill.bat批处理文件用于清理编译程序生成的中间文件。
三、官方demo
1. SDK demo说明
我们这里以linux下的SDK为例,inux下的SDK是没有IAR版本的demo的。只有armgcc版本。我们可以看一下这个hello world:
1 | sumu@sumu-virtual-machine:~/7Linux/SDK_2.2_MCIM6ULL/boards/evkmcimx6ull/demo_apps/hello_world$ tree |
可以看到arngcc文件夹下包含很多build_xx脚本,这些脚本用于在linux环境下编译生成.bin 可执行文件, 所以我们需要一个arm gcc交叉编译器。CMakeList.txt用于生成编译过程中需要的Makefile,所以我们还需要一个CMake工具。 以.ld结尾的文件是链接器脚本相关文件,根据运行的脚本不同,脚本会自动调用相应的链接文件。
2. linux搭建SDK编译环境
2.1 cmake
我们可以看一下cmake有没有安装,若是没安装,可以用这个命令安装:
1 | sudo apt-get install cmake |
我们可以用这个命令查看版本:
1 | cmake --version |
2.2 交叉编译工具
2.2.1 用的什么交叉编译器?
官方demo用的是什么工具?我们打开一个脚本看一眼:
发现这里会使用armgcc.cmake这个文件,我们到tool目录下看一下这个文件:
可以看到这里有一个交叉编译工具链的目录配置和前缀配置,由此可知,编译demo需要使用arm-none-eabi-gcc。但是我们之前没有安装这个,那就装一个吧。
2.2.2 安装arm-none-eabi
错误的尝试1
我们来到交叉编译工具链的官网:GNU Arm Embedded Toolchain in Launchpad:
我们点一些这个External downloads我们可以找到这里:Arm GNU Toolchain Downloads – Arm Developer:
然后就会发现这个页面的版本都很新,也没啥必要,这里我们装一个和arm-linux-gnueabihf-gcc 8.3.0同一年份的版本吧:Downloads | GNU-A Downloads – Arm Developer
跑到这里一看,好像没有arm-none-eabi,那这没办法了,往前找找,看看哪个版本有就装那个吧,由于这个SDK也挺早了,所以最好还是装个年份差不多的,防止有问题,往前找的话会发现这个版本有:
这里还有一个坑,就是安装完后,用这个编译工具链编译会报错:
错误的尝试2
上面安装不是有问题吗,我们看一下文档吧:
翻译一下最后一句就是:GCC工具链应与最新支持的版本相对应,如MCUXpresso SDK发行说明中所述。(文档MCUXSDKRN)。虽然没怎么看懂,但是我去翻了一下demo中的说明文档:
发现这里有写交叉编译工具链的版本,那我还有啥说的,直接去搜这个就是了,可以找到这个页面Downloads | 5-2016-q3-update – Arm Developer或者5-2016-q3-update : Series 5.0 : GNU Arm Embedded Toolchain (launchpad.net)
下载完毕后,会发现这是一个脚本:
那就直接执行吧:
待执行完毕,我们会看到如下
没看见可执行文件啊,我们怎么用?这样用:
1 | source /home/sumu/2software/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi |
然后到最后发现,工具名不对啊,又踩一个坑。
最后一次尝试,后来总是找不到合适的版本,那就按照野火的教程试一下:
1 | sudo apt-get install gcc-arm-none-eabi |
安装完毕后看一下版本:
1 | sumu@sumu-virtual-machine:~$ arm-none-eabi-gcc -v |
但是其实吧,这里的版本跟上面手动安装的一样,但是不是很清楚为什么那次尝试没成功?难道是安装目录问题?算了,不纠结了,这也不重要。
3. 编译demo
我们来到hello world这个demo的armgcc目录下,编译这个demo,我们执行这个脚本:
1 | ./build_release.sh |
然后发现报错了,这是因为没有指定交叉编译工具链的位置,我们指定一下:
1 | 不需要到bin这一级 arm-none-eabi-gcc的上一级目录即可 |
然后重新执行脚本就没问题啦:
然后我们会在boards/evkmcimx6ull/demo_apps/hello_world/armgcc路径下生成这两个目录:
1 | sumu@sumu-virtual-machine:~/7Linux/SDK_2.2_MCIM6ULL/boards/evkmcimx6ull/demo_apps/hello_world/armgcc$ tree -L 2 |
生成的是CMakeFiles和release目录,得到的成果物在release中。这个sdk20-app.bin就是做后得到的bin文件。
4. 烧录到SD卡
官方的SDK也同样为我们提供了裸机的烧录方式,我们看一下这个SDK_2.2_MCIM6ULL/tools/imgutil目录下的readme文件:
1 |
|
从这里我们可以知道我们需要把.bin文件拷贝到 imgutil/<board>目录下,然后重命名为sdk20-app.bin,然后执行mkimage.sh sd就可以生成img文件,我们可以来试一下:
1 | mkimage.sh sd |
发现这里提示权限不够,我们修改一下上面两个bin文件的权限:
1 | chmod 777 ../bin/dcdgen.bin |
然后我们会看到以下打印信息:
1 | sumu@sumu-virtual-machine:~/7Linux/SDK_2.2_MCIM6ULL/tools/imgutil/evkmcimx6ull$ ./mkimage.sh sd |
然后就会生成一个img文件:
我们使用dd命令将这个img文件烧写到sd卡中:
1 | sudo dd if=sdk20-app.img of=/dev/sdx bs=512 conv=fsync |
这个img文件直接从0开始烧写就可以了,这里设置块大小为512。
5. 开发板验证
我们将拨码开关拨到SD卡启动:
然后启动开发板,发现是跑不起来的,我猜测可能是硬件上哪里不兼容吧,不过问题不大,后面我们是移植这个SDK来用于自己的工程中,这里主要是学习一下怎么用这个工具烧录。
四、使用SDK控制GPIO
1. SDK移植
我们需要的的三个文件如下,前边已经说明了这三个文件的位置。
这三个文件直接编译的话肯定会出错的!需要对其做删减,因为这三个文件里面的代码都比较大 我们可以看这里:01_GPIO_LED/05_led_c_nxp_sdk——C语言点亮LED实验(NXP官方SDK移植) · 1e13542 · sumumm/imx6ull-bare-demo - Gitee.com,这一次的提交我同时修改了编译脚本和Makefile文件,可以直接看上边这三个文件的更改就会知道文件发生了哪些变化了。
2. 新建cc.h文件
新建一个名为 cc.h 的头文件, cc.h 里面存放一些 SDK 库文件需要使用到的数据类型,可以看工程里边的:01_GPIO_LED/05_led_c_nxp_sdk/cc.h · sumumm/imx6ull-bare-demo - 码云 - 开源中国 (gitee.com)
3. 其他文件
像led的GPIO配置,延时函数、时钟配置等与前边都是一样的,只是我们可以使用SDK中已经定义好的一些函数和结构体来实现,就不需要自己再定义了,这里就不详细说明了,大概了解就可以了。
4. 编译和下载
我在工程里写了脚本和Makefile文件,可以直接使用脚本来编译:01_GPIO_LED/05_led_c_nxp_sdk/1.sh · 苏木/imx6ull-bare-demo - 码云 - 开源中国 (gitee.com)。我们编译完后,可以通过这个脚本完成下载功能:
5. 链接地址
我们在mkimage.sh中会看到这么一句:
1 | ../bin/$IMG_BUILDER --combine base_addr=0x80000000 ivt_offset=0x400 app_offset=0x2000 dcd_file=dcd.bin app_file=sdk20-app.bin ofile=sdk20-app.img image_entry_point=0x80002000 |
这个主要是生成img文件的,按理来说image_entry_point这个值应该填我们的链接文件中链接的地址,我们这里注意和链接脚本保持一致。
注意:其实吧这里我试过,编译的时候链接脚本是0x87800000,这个烧写工具填0x80002000的话也能跑,不是很明白内部是怎么搞的,我甚至还试了mkimage工具,好像也一样,有点不懂,后面有问题再补充吧。
6. 开发板测试
我们将拨码开关拨到SD卡启动,然后复位开发板,我们就可以看到灯闪烁了。