SDK 移植及BSP工程管理

2024-02-21 10:28
文章标签 sdk 管理 移植 工程 bsp

本文主要是介绍SDK 移植及BSP工程管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

NXP 官方为 I.MX6ULL 编写了 SDK 包,在 SDK 包里面 NXP 已经编写好了寄存器定义文件,
所以我们可以直接移植 SDK 包里面的文件来用
1 I.MX6ULL 官方 SDK 包简介
NXP 针对 I.MX6ULL 编写了一个 SDK 包,这个 SDK 包就类似于 STM32 STD 库或者
HAL 库,这个 SDK 包提供了 Windows Linux 两种版本,分别针对主机系统是 Windows 和 Linux。
NXP 的 定位里面,I.MX6ULL 就是一个 Cotex-A 内核的高端单片机,定位类似 ST STM32H7。I.MX6ULL SDK 包在 NXP 官网下载,下载界面如图
双击 SDK_2.2_MCIM6ULL_RFP_Win.exe 安装 SDK 包,
安装的时候需要设置好安装位置,安装完成以后的 SDK 包如图
我们重点是需要 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 包我们就需要上面这三个文件,把这三个文件准备好,我们后面移植要用。

SDK 文件移植

使用 VSCode 新建工程,将 fsl_common.h fsl_iomuxc.h MCIMX6Y2.h 这三个文件拷贝
到工程中,这三个文件直接编译的话肯定会出错的!需要对其做删减,因为这三个文件里面的 代码都比较大,所以就不详细列出这三个文件删减以后的内容了
创建 cc.h 文件
新建一个名为 cc.h 的头文件, cc.h 里面存放一些 SDK 库文件需要使用到的数据类型,在
cc.h 里面输入如下代码:
1 #ifndef __CC_H
2 #define __CC_H14 * 自定义一些数据类型供库文件使用
15 */
16 #define __I volatile
17 #define __O volatile
18 #define __IO volatile
19
20 #define ON 1
21 #define OFF 0
22
23 typedef signed char int8_t;
24 typedef signed short int int16_t;
25 typedef signed int int32_t;
26 typedef unsigned char uint8_t;
27 typedef unsigned short int uint16_t;
28 typedef unsigned int uint32_t;
29 typedef unsigned long long uint64_t;
30 typedef signed char s8; 
31 typedef signed short int s16;
32 typedef signed int s32;
33 typedef signed long long int s64;
34 typedef unsigned char u8;
35 typedef unsigned short int u16;
36 typedef unsigned int u32;
37 typedef unsigned long long int u64;
38
39 #endif
编写实验代码
新建 start.S main.c 这两个文件,start.S 文件的内容和上一章一样,直接复制过来就可以, 创建完成以后工程目录如图 main.c 中输入如下所示代码:
1 #include "fsl_common.h"
2 #include "fsl_iomuxc.h"
3 #include "MCIMX6Y2.h"
4 
5 /*
6 * @description : 使能 I.MX6U 所有外设时钟
7 * @param : 无
8 * @return : 无
9 */
10 void clk_enable(void)
11 {
12 CCM->CCGR0 = 0XFFFFFFFF;
13 CCM->CCGR1 = 0XFFFFFFFF;
14 
15 CCM->CCGR2 = 0XFFFFFFFF;
16 CCM->CCGR3 = 0XFFFFFFFF;
17 CCM->CCGR4 = 0XFFFFFFFF;
18 CCM->CCGR5 = 0XFFFFFFFF;
19 CCM->CCGR6 = 0XFFFFFFFF;
20
21 }
22 
23 /*
24 * @description : 初始化 LED 对应的 GPIO
25 * @param : 无
26 * @return : 无
27 */
28 void led_init(void)
29 {
30 /* 1、初始化 IO 复用 */
31 IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
32 
33 /* 2、、配置 GPIO1_IO03 的 IO 属性 
34 *bit 16:0 HYS 关闭
35 *bit [15:14]: 00 默认下拉
36 *bit [13]: 0 kepper 功能
37 *bit [12]: 1 pull/keeper 使能
38 *bit [11]: 0 关闭开路输出
39 *bit [7:6]: 10 速度 100Mhz
40 *bit [5:3]: 110 R0/6 驱动能力
41 *bit [0]: 0 低转换率
42 */
43 IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
44 
45 /* 3、初始化 GPIO,设置 GPIO1_IO03 设置为输出 */
46 GPIO1->GDIR |= (1 << 3); 
47 
48 /* 4、设置 GPIO1_IO03 输出低电平,打开 LED0 */
49 GPIO1->DR &= ~(1 << 3); 
50 }
51 
52 /*
53 * @description : 打开 LED 灯
54 * @param : 无
55 * @return : 无
56 */
57 void led_on(void)
58 {
59 /* 将 GPIO1_DR 的 bit3 清零 */
60 GPIO1->DR &= ~(1<<3);
61 }
62 
63 /*
64 * @description : 关闭 LED 灯
65 * @param : 无
66 * @return : 无
67 */
68 void led_off(void)
69 {
70 /* 将 GPIO1_DR 的 bit3 置 1 */
71 GPIO1->DR |= (1<<3);
72 }
73 
74 /*
75 * @description : 短时间延时函数
76 * @param - n : 要延时循环次数(空操作循环次数,模式延时)
77 * @return : 无
78 */
79 void delay_short(volatile unsigned int n)
80 {
81 while(n--){}
82 }
83 
84 /*
85 * @description : 延时函数,在 396Mhz 的主频下
86 * 延时时间大约为 1ms
87 * @param - n : 要延时的 ms 数
88 * @return : 无
89 */
90 void delay(volatile unsigned int n)
91 {
92 while(n--)
93 {
94 delay_short(0x7ff);
95 }
96 }
97 
98 /*
99 * @description : main 函数
100 * @param : 无
101 * @return : 无
102 */
103 int main(void)
104 {
105 clk_enable(); /* 使能所有的时钟 */
106 led_init(); /* 初始化 led */
107
108 while(1) /* 死循环 */
109 { 
110 led_off(); /* 关闭 LED */
111 delay(500); /* 延时 500ms */
112
113 led_on(); /* 打开 LED */
114 delay(500); /* 延时 500ms */
115 }
116
117 return 0;
118 }
编译下载验证
编写 Makefile 和链接脚本
Makefile 文件内容如下:
1 CROSS_COMPILE ?= arm-linux-gnueabihf-
2 NAME ?= ledc
3 
4 CC := $(CROSS_COMPILE)gcc
5 LD := $(CROSS_COMPILE)ld
6 OBJCOPY := $(CROSS_COMPILE)objcopy
7 OBJDUMP := $(CROSS_COMPILE)objdump
8 
9 OBJS := start.o main.o
10
11 $(NAME).bin:$(OBJS)
12 $(LD) -Timx6ul.lds -o $(NAME).elf $^
13 $(OBJCOPY) -O binary -S $(NAME).elf $@
14 $(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis
15
16 %.o:%.s
17 $(CC) -Wall -nostdlib -c -O2 -o $@ $<
18 
19 %.o:%.S
20 $(CC) -Wall -nostdlib -c -O2 -o $@ $<
21 
22 %.o:%.c
23 $(CC) -Wall -nostdlib -c -O2 -o $@ $<
24 
25 clean:
26 rm -rf *.o $(NAME).bin $(NAME).elf $(NAME).dis
编译下载
使用 Make 命令编译代码,编译成功以后使用软件 imxdownload 将编译完成的 ledc.bin
件下载到 SD 卡中,命令如下:
烧写成功以后将 SD 卡插到开发板的 SD 卡槽中,然后复位开发板,如果代码运行正常的
LED0 就会以 500ms 的时间间隔亮灭,实验现象和上一章一样

BSP工程管理原理

目的就是为了模块化整理代码,同一个属性的文件存放在同一个目录里面

1.修建所需的文件夹,将同一属性的文件放到相应的文件夹中

2.修改clk,led,delay驱动,创建对应的驱动文件,然后放置到对应的目录中

3.根据编写的驱动新文件。修改main.c文件内容

设置vs code头文件路径。先创建.vscode目录,然后打开C/C++配置器,会在.vscode目录下生成一个叫做c_cpp_properties.json的文件

新建名为“ 5_ledc_bsp ”的文件夹,在里面新建 bsp imx6ul obj project 4 个文件夹,
完成以后如图
其中 bsp 用来存放驱动文件; imx6ul 用来存放跟芯片有关的文件,比如 NXP 官方的 SDK
库文件; obj 用来存放编译生成的 .o 文件; project 存放 start.S main.c 文件,也就是应用文件; 将十二章实验中的 cc.h fsl_common.h fsl_iomuxc.h MCIMX6Y2.h 这四个文件拷贝到文件 夹 imx6ul 中;将 start.S main.c 这两个文件拷贝到文件夹 project 中。我们前面的实验中所有 的驱动相关的函数都写到了 main.c 文件中,比如函数 clk_enable led_init delay ,这三个函数 可以分为三类:时钟驱动、LED 驱动和延时驱动。因此我们可以在 bsp 文件夹下创建三个子文 件夹:clk delay led ,分别用来存放时钟驱动文件、延时驱动文件和 LED 驱动文件,这样 main.c 函数就会清爽很多,程序功能模块清晰。工程文件夹都创建好了,接下来就是编写代码 了,其实就是将时钟驱动、LED 驱动和延时驱动相关的函数从 main.c 中提取出来做成一个独立 的驱动文件 。
实验程序编写
创建 imx6ul.h 文件
新建文件 imx6ul.h ,然后保存到文件夹 imx6ul 中,在 imx6ul.h 中输入如下内容:
#ifndef __IMX6UL_H
#define __IMX6UL_H#include "cc.h"#include "MCIMX6Y2.h"#include "fsl_common.h"#include "fsl_iomuxc.h"#endif
编写 led 驱动代码
新建 bsp_led.h bsp_led.c 两个文件,将这两个文件存放到 bsp/led 中,在 bsp_led.h 中输入 输入如下内容:
1 #ifndef __BSP_LED_H
2 #define __BSP_LED_H
3 #include "imx6ul.h"
15 #define LED0 0
16
17 /* 函数声明 */
18 void led_init(void);
19 void led_switch(int led, int status);
20 #endif
bsp_led.h 的内容很简单,就是一些函数声明,在 bsp_led.c 中输入如下内容:
1 #include "bsp_led.h"
18 void led_init(void)
19 {
20 /* 1、初始化 IO 复用 */
21 IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); 
22 
23 /* 2、、配置 GPIO1_IO03 的 IO 属性 */
24 IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
25 
26 /* 3、初始化 GPIO,GPIO1_IO03 设置为输出*/
27 GPIO1->GDIR |= (1 << 3); 
28
29 /* 4、设置 GPIO1_IO03 输出低电平,打开 LED0*/
30 GPIO1->DR &= ~(1 << 3); 
31 }
33 /*
34 * @description : LED 控制函数,控制 LED 打开还是关闭
35 * @param - led : 要控制的 LED 灯编号
36 * @param - status : 0,关闭 LED0,1 打开 LED0
37 * @return : 无
38 */
39 void led_switch(int led, int status)
40 { 
41 switch(led)
42 {
43 case LED0:
44 if(status == ON)
45 GPIO1->DR &= ~(1<<3); /* 打开 LED0 */
46 else if(status == OFF)
47 GPIO1->DR |= (1<<3); /* 关闭 LED0 */
48 break;
49 }
50 }
bsp_led.c 里面就两个函数 led_init led_switch led_init 函数用来初始化 LED 所使用的
IO led_switch 函数是控制 LED 灯的打开和关闭,这两个函数都很简单。
编写时钟驱动代码
新建 bsp_clk.h bsp_clk.c 两个文件,将这两个文件存放到 bsp/clk 中,在 bsp_clk.h 中输入 输入如下内容:
1 #ifndef __BSP_CLK_H
2 #define __BSP_CLK_H14 #include "imx6ul.h"
15
16 /* 函数声明 */
17 void clk_enable(void);
18
19 #endif
bsp_clk.h 很简单,在 bsp_clk.c 中输入内容:
1 #include "bsp_clk.h"
14 /*
15 * @description : 使能 I.MX6U 所有外设时钟
16 * @param : 无
17 * @return : 无
18 */
19 void clk_enable(void)
20 {
21 CCM->CCGR0 = 0XFFFFFFFF;
22 CCM->CCGR1 = 0XFFFFFFFF;
23 CCM->CCGR2 = 0XFFFFFFFF;
24 CCM->CCGR3 = 0XFFFFFFFF;
25 CCM->CCGR4 = 0XFFFFFFFF;
26 CCM->CCGR5 = 0XFFFFFFFF;
27 CCM->CCGR6 = 0XFFFFFFFF;
28 }
bsp_clk.c 只有一个 clk_enable 函数,用来使能所有的外设时钟。
编写延时驱动代码
新建 bsp_delay.h bsp_delay.c 两个文件,将这两个文件存放到 bsp/delay 中,在 bsp_delay.h 中输入输入如下内容:
1 #ifndef __BSP_DELAY_H
2 #define __BSP_DELAY_H
13 #include "imx6ul.h"
14
15 /* 函数声明 */
16 void delay(volatile unsigned int n);
17
18 #endif
bsp_delay.c 中输入内容:
1 #include "bsp_delay.h"
2 
3 /*
4 * @description : 短时间延时函数
5 * @param - n : 要延时循环次数(空操作循环次数,模式延时)
6 * @return : 无
7 */
8 void delay_short(volatile unsigned int n)
9 {
10 while(n--){}
11 }
12
13 /*
14 * @description : 延时函数,在 396Mhz 的主频下
15 * 延时时间大约为 1ms
16 * @param - n : 要延时的 ms 数
17 * @return : 无
18 */
19 void delay(volatile unsigned int n)
20 {
21 while(n--)
22 {
23 delay_short(0x7ff);
24 }
25 }
修改 main.c 文件
1 #include "bsp_clk.h"
2 #include "bsp_delay.h"
3 #include "bsp_led.h"
4 
5 /*
6 * @description : main 函数
7 * @param : 无
8 * @return : 无
9 */
10 int main(void)
11 {
12 clk_enable(); /* 使能所有的时钟 */
13 led_init(); /* 初始化 led */
14
15 while(1)
16 { 
17 /* 打开 LED0 */
18 led_switch(LED0,ON); 
19 delay(500);
20
21 /* 关闭 LED0 */
22 led_switch(LED0,OFF); 
23 delay(500);
24 }
25
26 return 0;
27 }
编译下载验证
编写 Makefile 和链接脚本
在工程根目录下新建 Makefile 和 imx6ul.lds 这两个文件,创建完成以后的工程如图
在文件 Makefile 中输入如下所示内容:
1 CROSS_COMPILE ?= arm-linux-gnueabihf-
2 TARGET ?= bsp
3 
4 CC := $(CROSS_COMPILE)gcc
5 LD := $(CROSS_COMPILE)ld
6 OBJCOPY := $(CROSS_COMPILE)objcopy
7 OBJDUMP := $(CROSS_COMPILE)objdump
8 
9 INCDIRS := imx6ul \
10 bsp/clk \
11 bsp/led \
12 bsp/delay 
13 
14 SRCDIRS := project \
15 bsp/clk \
16 bsp/led \
17 bsp/delay 
18 
19 INCLUDE := $(patsubst %, -I %, $(INCDIRS))
20
21 SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
22 CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
23
24 SFILENDIR := $(notdir $(SFILES))
25 CFILENDIR := $(notdir $(CFILES))
26
27 SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
28 COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
29 OBJS := $(SOBJS) $(COBJS)
30
31 VPATH := $(SRCDIRS)
32
33 .PHONY: clean
34 
35 $(TARGET).bin : $(OBJS)
36 $(LD) -Timx6ul.lds -o $(TARGET).elf $^
37 $(OBJCOPY) -O binary -S $(TARGET).elf $@
38 $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
39
40 $(SOBJS) : obj/%.o : %.S
41 $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
42
43 $(COBJS) : obj/%.o : %.c
44 $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
45 
46 clean:
47 rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
链接脚本 imx6ul.lds 的内容基本和上一章一样,主要是 start.o 文件路径不同,本章所使用
imx6ul.lds 链接脚本内容如下所示:
1 SECTIONS{
2 . = 0X87800000;
3 .text :
4 {
5 obj/start.o 
6 *(.text)
7 }
8 .rodata ALIGN(4) : {*(.rodata*)} 
9 .data ALIGN(4) : { *(.data) } 
10 __bss_start = .; 
11 .bss ALIGN(4) : { *(.bss) *(COMMON) } 
12 __bss_end = .;
13 }
编译下载
使用 Make 命令编译代码,编译成功以后使用软件 imxdownload 将编译完成的 bsp.bin 文件
下载到 SD 卡中,命令如下:
烧写成功以后将 SD 卡插到开发板的 SD 卡槽中,然后复位开发板,如果代码运行正常的
LED0 就会以 500ms 的时间间隔亮灭

wink成功

 

这篇关于SDK 移植及BSP工程管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/731465

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

Sentinel 高可用流量管理框架

Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 Sentinel 具有以下特性: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应

NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854 一 前言 当管理大量连接时,特别是只有少量活跃连接,NGINX有比较好的CPU和RAM利用率,如今是多终端保持在线的时代,更能让NGINX发挥这个优点。本文做一个简单测试,NGINX在一个普通PC虚拟机上维护100k的HTTP