【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本

这篇具有很好参考价值的文章主要介绍了【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、BSP 工程

【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本

文件夹 描述
bsp 存放驱动文件
imx6ul 存放跟芯片有关的文件,比如 NXP 官方的 SDK库文件
obj 存放编译生成的.o 文件
project 存放 start.S 和 main.c 文件,也就是应用文件

二、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)
描述
1~7 定义了一些变量,除了第 2 行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第 1 行即可。第 2 行的变量 TARGET 目标名字,不同的例程肯定名不一样。
9 变量 INCDIRS 包含整个工程的.h 头文件目录,文件中的所有头文件目录都要添加到变量INCDIRS中。比如本例程中包含.h头文件的目录有imx6ul、bsp/clk、bsp/delaybsp/led,所以就需要在变量 INCDIRS 中添加这些目录,即:
INCDIRS := imx6ul bsp/clk bsp/led bsp/delay
14 变量 SRCDIRS,和变量 INCDIRS 一样,只是 SRCDIRS 包含的是整个工程的所有.c 和.S 文件目录比如本例程包含有.c 和.S 的目录有 bsp/clk、 bsp/delay、 bsp/led 和 project,即:
SRCDIRS := project bsp/clk bsp/led bsp/delay
19 变量 INCLUDE 使用到了函数 patsubst,通过函数 patsubst 给变量 INCDIRS 添加一个“-I”,加“-I”的目的是因为 Makefile 语法要求指明头文件目录的时候需要加上“-I”,即:
INCLUDE := -I imx6ul -I bsp/clk -I bsp/led -I bsp/delay
21 变量 SFILES 保存工程中所有的.s 汇编文件(包含绝对路径),变量 SRCDIRS 已经存放了工程中所有的.c 和.S 文件,所以我们只需要从里面挑出所有的.S 汇编文件即可,这里借助了函数 foreach 和函数 wildcard,最终 SFILES 如下:
SFILES := project/start.S
22 变量 CFILES 和变量 SFILES 一样,只是 CFILES 保存工程中所有的.c 文件(包含绝对路径),最终 CFILES 如下:
CFILES = project/main.c bsp/clk/bsp_clk.c bsp/led/bsp_led.c bsp/delay/bsp_delay.c
24~25 变量 SFILENDIR 和 CFILENDIR 包含所有的.S 汇编文件和.c 文件,相比变量 SFILES 和 CFILES, SFILENDIR 和 CFILNDIR 只是文件名,不包含文件的绝对路径。使用函数 notdir 将 SFILES 和 CFILES 中的路径去掉即可, SFILENDIR 和 CFILENDIR 如下:
SFILENDIR = start.S
CFILENDIR = main.c bsp_clk.c bsp_led.c bsp_delay.c
27~28 变量 SOBJS 和 COBJS 是.S 和.c 文件编译以后对应的.o 文件目录,默认所有的文件编译出来的.o 文件和源文件在同一个目录中,这里我们将所有的.o 文件都放到 obj 文件夹下, SOBJS 和 COBJS 内容如下:
SOBJS = obj/start.o
COBJS = obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o
29 变量 OBJS 是变量 SOBJS 和 COBJS 的集合,如下:
OBJS = obj/start.o obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o
编译完成以后所有的.o 文件就全部存放到了 obj 目录下。
31 VPATH 是指定搜索目录的,这里指定的搜素目录就是变量 SRCDIRS 所保存的目录,这样当编译的时候所需的.S 和.c 文件就会在 SRCDIRS 中指定的目录中查找。
33 指定了一个伪目标 clean

三、链接脚本

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 	}

注意第 5 行设置的 start.o 文件路径


* Makefile 的静态模式和函数

1. 静态模式

静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活,语法如下:

<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
....
参数 描述
targets 定义了一系列的目标文件,可以有通配符。是目标的一个集合
target-parrtern 是指明了 targets 的模式,也就是的目标集模式
prereq-parrterns 是目标的依赖模式,它对 target-parrtern 形成的模式再进行一次依赖目标的定义

示例:
  如果我们的 <target-parrtern> 定义成“%.o”,意思是我们的 <target> 集合中都是以“.o”结尾的,而如果我们的 <prereq-parrterns> 定义成“%.c”, 意思是对 <target-parrtern>所形成的目标集进行二次定义,其计算方法是,取 <target-parrtern> 模式中的“%”(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合。
  所以,我们的“目标模式”或是“依赖模式”中都应该有“%”这个字符,如果你的文件名中有“%”那么你可以使用反斜杠“\”进行转义,来标明真实的“%”字符。

objects = foo.o bar.o

all: $(objects)

$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@

  上面的例子中,指明了我们的目标从$object 中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object 集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.c bar.c”。而命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”), “$@”表示目标集(也就是“foo.o bar.o”)。于是,上面的规则展开后等价于下面的规则:

foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o

bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o

2. 函数

2.1 patsubst

模式字符串替换函数

$(patsubst <pattern>,<replacement>,<text>)
功能 查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”, 表示任意长度的字串。 如果<replacement>中也包含“%”, 那么, <replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义, 以“%”来表示真实含义的“%”字符)
返回 函数返回被替换过后的字符串

示例:

$(patsubst %.c,%.o,x.c.c bar.c)

把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”


2.2 dir

取目录函数

$(dir <names...>)
功能 从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”
返回 返回文件名序列<names>的目录部分

2.3 notdir

取文件函数

$(notdir <names...>)
功能 从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“ /”)之后的部分
返回 返回文件名序列的非目录部分

2.4 foreach

循环函数

$(foreach <var>,<list>,<text>)
功能   把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>所返回的每个字符串所组成的整个字符串(以空格分隔)将会是 foreach 函数的返回值

<var>最好是一个变量名, <list>可以是一个表达式,而<text>中一般会使用<var>这个参数来依次枚举<list>中的单词。举个例子:

names := a b c d
files := $(foreach n,$(names),$(n).o)

上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为 foreach 函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。

注意,foreach 中的<var>参数是一个临时的局部变量,foreach 函数执行完后,参数<var>的变量将不在作用,其作用域只在 foreach 函数当中。文章来源地址https://www.toymoban.com/news/detail-419164.html

到了这里,关于【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • I.MX6ULL开发笔记(二)——硬件外设操作

    在文章http://t.csdnimg.cn/EGWt9中有介绍Linux下文件目录,那么在Linux系统下,RGB灯也是一个设备,所以我们需要到 /sys 目录下去操作这个设备。 之后,我们进入到 class 目录,这里挂载着开发板上的外设: 在这里就能看到熟悉的硬件接口了,那么我们进入到 leds 的目录下: 可以看

    2024年01月24日
    浏览(35)
  • 012——LED模块驱动开发(基于I.MX6uLL)

    目录 一、 硬件原理图 二、 驱动程序 三、 应用程序 四、 Makefile 五、操作         又是非常经典的点灯环节 ,每次学新语言第一步都是hello world,拿到新板子或者学习新的操作系统,第一步就是点灯。         LED 的驱动方式,常见的有四种。 ① 使用引脚输出 3.3V 点

    2024年04月13日
    浏览(31)
  • 016——DHT11驱动开发(基于I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 电路描述 1.3 通信协议 二、 驱动程序 三、 应用程序 四、 上机实验         DHT11 是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器,会测量空气中湿度,再根据测量结果决定是否继续加湿。DHT11 数字温湿度传感器是一款含有已

    2024年04月16日
    浏览(25)
  • I.MX6ull GPT高精度定时器

    一 简介 GPT的全称是General Purpose Timer,它是一个32位的向上的定时器, GPT 定时器也可以跟一个值进行比较,当计数器值和这个值相等的话就发生比较事件,产生比较中断。GPT 定时器有一个 12 位的分频器,可以对 GPT 定时器的时钟源进行分频。 分析方式 同EPTI  它具有以下特点

    2024年02月08日
    浏览(31)
  • I.MX6ULL ARM驱动开发---网络设备驱动框架

      网络驱动是 linux 里面驱动三巨头之一,linux 下的网络功能非常强大,嵌入式 linux 中也常常用到网络功能。前面我们已经讲过了字符设备驱动和块设备驱动,本章我们就来学习一下 linux 里面的网络设备驱动。   网络设备驱动程序的体系结构分为4层,依次为网络协议驱

    2023年04月17日
    浏览(27)
  • 017——DS18B20驱动开发(基于I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 主要特点 1.3 存储器介绍 1.4 时序 1.5 命令 1.5.1 命令大全    1.5.2 命令使用 1.5.3 使用示例 1.6 原理图 二、 驱动程序 三、 应用程序 四、 测试         DS18B20 温度传感器具有线路简单、体积小的特点,用来测量温度非常简单,在一根通信线上

    2024年04月12日
    浏览(33)
  • i.MX6ULL驱动开发 | 27 - 使用WM8960 CODEC播放音频

    WM8960是欧胜公司(wolfson)的一款低功耗、高质量的立体声音频编解码芯片。 其内部集成D类喇叭功放,每个通道可以驱动一个1W喇叭(8Ω),内部集成3个立体声输入源,可以灵活配置,拥有一路完整的麦克风接口。 WM8960内部ADC和DAC都为24位,主要特性如下: DAC的SNR(信噪比)

    2024年02月02日
    浏览(32)
  • 018——红外遥控模块驱动开发(基于HS0038和I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 协议 二、 驱动代码 三、 应用代码 四、 实验 五、 程序优化         红外遥控被广泛应用于家用电器、工业控制和智能仪器系统中,像我们熟知的有电视机盒子遥控器、空调遥控器。红外遥控器系统分为发送端和接收端,如图下图所示。

    2024年04月16日
    浏览(32)
  • 使用一根网线,让Ubuntu和正点原子I.MX6ULL开发板互相ping通

    准备一根网线即可 2.1 找根网线将I.MX6ULL和电脑连起来 2.2 让I.MX6ULL通电运行起来,我这里使用的是正点原子版本的内核、 2.3 进入电脑的网络连接后,按照如下步骤操作 2.4 将ip地址、子网掩码、默认网关设置如下,= 注意,子网掩码一定要是255.255.255.0 IP地址推荐使用192.168.5.

    2024年02月19日
    浏览(31)
  • 基于I.MX6ULL的Linux C多线程物联网网关+STM32+Qt上位机+Linux C++多线程服务器(含web)的多种无线通信系统的智慧农场

    我国是农业大国,而非农业强国。近30年来农业高产量主要依靠农药化肥的大量投入,大部分化肥和水资源没有被有效利用而随地弃置,导致大量养分损失并造成环境污染。我国农业生产仍然以传统生产模式为主,传统耕种只能凭经验施肥灌溉,不仅浪费大量的人力物力,也

    2024年04月14日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包