正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-11.1,11.2-BSP文件目录组织

ops/2024/9/23 4:24:31/

 前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第11.1讲, 11.2讲” 的读书笔记。第11.1,11.2讲介绍如何将我们写的C语言LED驱动程序组织成为一个业界典型的BSP目录的形式。

1. 将C语言LED驱动程序组织为BSP目录形式

上一节中移植了NXP SDK的文件到 C 语言LED驱动程序中,并调用 NXP SDK 里定义的api接口来设置GPIO 接口的IO接口复用模式和IO接口的电气特性,最后在 main.c 文件里调用api接口函数来实现 I.MX6ULL APLHA/Mini 开发板的 LED 指示灯闪烁。

在上一节的C语言LED驱动程序中,在 main.c 源文件中声明并定义了 'clk_init()', 'led_init()', 'delay_short()' , 'delay()' 这些函数并在 main.c 源文件中直接调用了这些函数。并且移植的 .h 头文件和 main.c 文件都是放在根目录下面的。在后续学习开发过程中,随着项目越来越复杂,项目的源文件也会越来越多,大量的源文件混在同一个根目录下面会让项目的管理变得混乱。本节中我们将会使用芯片驱动开发业界通用的模式,把项目的源码文件组织成BSP形式的目录形式,分门别类的把项目的源文件和头文件放到专门的目录里。按照BSP的方式来组织项目源码,项目的源码文件管理就变得清晰有条理。使用BSP的方式来管理项目的源码也从侧面反映出开发人员的是否有成熟专业素养。

BSP目录组织中的主要目录如下:

目录描述
bsp该目录存放项目的 BSP 开发 api 接口源码,和芯片底层相关的API接口的文件都放在该目录下
imx6u该目录存放项目存放特定处理器相关的文件,例如 I.MX6ULL 芯片的寄存器地址文件。
obj项目编译出来的 .o 中间文件放在这个目录
project项目的主体源码文件存放在该目录下,如 main.c start.s 

2. 根据BSP目录格式写Makefile

按照BSP的方式来组织项目源码,项目的源码文件按照类别分别放在了不同的目录里,例如 'bsp/', 'project', 'imx6u'等,之前的Makefile就不能满足当前这种多层目录结构的项目组织形式,我们需要修改 Makefile 来编译 BSP这种多层目录结构的源码。

本节Makefile将使用多用的make函数语法,本节写的是一个通用的makefile,在后续的正点原子 I.MX6U 裸机开发例程中都将使用本节写的Makefile,仅仅需要多Makefile做很小的修改就能适应不同的I.MX6U开发实验例程。

本节会使用到的makefile语法,主要有以下几种:

makefile函数:描述:
$(foreach <var>,<list>,<text>)这个函数的意思是,把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。
 
$(patsubst <pattern>,<replacement>,<text>)查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”, 表示任意长度的字串
 
$(wildcard $(dir)/*.c)wildcard 函数在定义变量的地方将通配符‘*’进行扩展,如果有符合通配符的格式字符串就返回改字符串,如果没有符合通配符格式的字符串就返回空。

通过这些makefile 模式匹配,模式替换,模式扩展函数,我们的新Makefile的内容如下,这是一种通用的 makefile 格式,它通过对 BSP 子目录里源文件的匹配替换,makefile语法格式中的模式替换函数对字符串的操作,实现了对BSP子目录中“*.c”,"*.s" 源文件的自动搜索并生成以来关系。在后续的正点原子I.MX6ULL APHAP/Mini开发例程实验里,只需要在makefile里加上BSP的子目录,就可以自动的生成编译目标的以来关系。

CROSS_COMPILE	?= arm-linux-gnueabihf-
TARGET 		:= ledcCC			:= 	$(CROSS_COMPILE)gcc
LD			:= 	$(CROSS_COMPILE)ld
OBJCOPY		:= 	$(CROSS_COMPILE)objcopy
OBJDUMP		:= 	$(CROSS_COMPILE)objdumpINCLUDEDIRS :=  bsp/clk \bsp/delay \bsp/led \imx6ullSRCDIRS		:=	bsp/clk \bsp/delay \bsp/led \projectINCLUDE		:= 	$(patsubst %, -I %, $(INCLUDEDIRS))#SFILES		:=	$(patsubst %.s,%.s,$(wildcard $(SRCDIRS)/*.s))
#CFILES		:=	$(patsubst %.c,%.c,$(wildcard $(SRCDIRS)/*.c)) 
#SFILES		:=	$(wildcard $(SRCDIRS)/*.s)
#CFILES		:=	$(wildcard $(SRCDIRS)/*.c)#错误的语法格式,因为 $(wildcard $(SRCDIRS)/*.c) 展开之后为 "$(wildcard bsp/clk bsp/delay bsp/led project/*.c)",这样只有最后一个展开为了 $(wildcard project/*.c)的形式
#按照我们的预期,应该使用 Makefile 的 $(foreach var,list,text) 函数
##SFILES		:= 	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.s))
CFILES		:= 	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))SFILENDIR	:= 	$(notdir $(SFILES))
CFILENDIR	:= 	$(notdir $(CFILES))SOBJS		:=	$(patsubst %, obj/% ,$(SFILENDIR:%.s=%.o))
COBJS		:=	$(patsubst %, obj/%, $(CFILENDIR:%.c=%.o))OBJS		:=	$(SOBJS) $(COBJS)VPATH		:= 	$(SRCDIRS)$(TARGET).bin : $(OBJS)echo $(LD) $(TARGET).elf$(LD) -Timx6u.lds -o $(TARGET).elf $^$(OBJCOPY) -O binary -S $(TARGET).elf $(TARGET).bin$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis# #%.o : %.s
$(SOBJS) : obj/%.o : %.s$(CC) -Wall -nostdlib $(INCLUDE) -c -o $@ $<#%.o : %.c
$(COBJS) : obj/%.o : %.c$(CC) -Wall -nostdlib $(INCLUDE) -c -o $@ $<clean:rm -rf obj/*.o $(TARGET).bin $(TARGET).elf.PHONY : print clean print:@echo "INCLUDE=" $(INCLUDE)@echo "SFILES="  $(SFILES)@echo "CFILES="  $(CFILES)@echo "SFILENDIR=" $(SFILENDIR)@echo "CFILENDIR=" $(CFILENDIR)@echo "SOBJS="   $(SOBJS)@echo "COBJS="   $(COBJS)@echo "OBJS="    $(OBJS)

3. 修改 imx6u.lds 链接文件

修改Makefile之后,执行编译项目,编译器输出如下错误:

错误提示信息显示,实在链接阶段 'ld' 找不到 'start.o'文件,因为本节中我们把LED驱动源程序组织成了 BSP 目录格式形式,所以在  imx6u.lds 链接文件中之前指定的 'start.o' ,在当前目录下就找不到 start.o 文件,在新的编译目录该文件的路径是 './obj/start.o' 所以需要修改 imx6u.lds 链接文件,执行 start.o 的文件目录为新的位置。

修正 imx6u.lds 链接文件之后,重新执行“make”命令进行编译,项目可以正确的编译成功并生成 .bin 文件。

4. 烧录SD卡,并验证LED灯是否正常闪烁

烧录SD卡验证LED灯,使用正点原子提供的 'imxdownload' 烧录SD卡,然后把SD卡查到正点原子 I.MX6U APLHA/Mini 开发板上验证移植的 NXP SDK LED 灯驱动程序是否运行正常,LED灯正常闪烁。我本地实验验证结果是 LED 正常闪烁。


http://www.ppmy.cn/ops/32740.html

相关文章

Android数据恢复软件快速比较:Android数据恢复的7最佳工具

您在 Android 设备上保留哪些类型的数据&#xff1f;如果您和大多数人一样&#xff0c;那么您可能已经列出了文档、照片、视频和音频文件。如果您使用智能手机或平板电脑的时间足够长&#xff0c;我们愿意打赌您拥有Android数据丢失的第一手经验。 幸运的是&#xff0c;我们也…

EKS创建ebs存储卷

1、创建ebs卷 也可以aws命令创建 # aws ec2 create-volume --availability-zone ap-east-1a --size 100 --volume-type gp3 {"AvailabilityZone": "ap-east-1a","Encrypted": false,"VolumeType": "gp3","VolumeId&q…

办公数据分析利器:Excel与Power Query透视功能

数据分析利器&#xff1a;Excel与Power Query透视功能 Excel透视表和Power Query透视功能是强大的数据分析工具&#xff0c;它们使用户能够从大量数据中提取有意义的信息和趋势&#xff0c;可用于汇总、分析和可视化大量数据。 本文通过示例演示Power Query透视功能的一个小技…

c语言——函数

1.函数的概念 在数学中我们学习过如一次函数&#xff1b;二次函数等&#xff0c;其实在c语言中也引入了函数(function)的概念 C语言函数是一种函数&#xff0c;用来编译C语言&#xff0c;一般包括字符库函数&#xff0c;数学函数&#xff0c;目录函数&#xff0c;进程函数&…

如何自己设计一个类似 Dubbo 的 RPC 框架?

目录 一、面试官心理分析 二、面试题剖析 一、面试官心理分析 说实话&#xff0c;就这问题&#xff0c;其实就跟问你如何自己设计一个 MQ 是一样的道理&#xff0c;就考察两个&#xff1a; 你有没有对某个 rpc 框架原理有非常深入的理解。 你能不能从整体上…

Three.js——基础材质、深度材质、法向材质、面材质、朗伯材质、Phong材质、着色器材质、直线和虚线、联合材质

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

pytorch 线性代数基本操作

pytorch是非常好的人工智能训练和推理框架&#xff0c;我们来通过李沐老师的《动手学深度学习》来简单学习一下。 首先&#xff0c;安装pytorch&#xff0c;请参考pytorch官网&#xff1a;PyTorch 也可以到kaggle、colab、启智社区等使用配置好的pytorch环境&#xff0c;更简单…

vue路由懒加载是什么

Vue路由懒加载是一种优化技术&#xff0c;旨在减少应用程序的初始加载时间并提高性能。具体来说&#xff0c;它允许我们在用户实际需要访问某个路由时&#xff0c;才加载对应的组件代码&#xff0c;而不是在应用程序启动时一次性加载所有组件。 举个例子来说明Vue路由懒加载的…