IMX6ULL学习笔记(17)——工程管理

news2025/2/28 21:11:19

一、简介

之前我们把所有源码文件放在一个文件夹下。 这样做存在两个主要问题,第一,代码存放混乱不易阅读。第二,程序可移植性差。如果工程源文件达到几十、甚至数百个的时候,这样一股脑全部放到根目录下就会使工程显得混乱不堪。所以我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中。另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理。

如何对一个工程进行整理,使其美观、功能模块清晰、易于阅读。

  • 创建文件夹分类存储代码
  • 修改makefile

二、分类存储代码

修改前的程序结构:

修改后的程序结构:

  • base.lds :将led.lds更改为base.lds。连接脚本与具体的外设无关,并且后面的程序我们几乎不会去修改链接脚本,这里把它修改为base.lds,你也可以根据自己喜好命令,只要和makefile中一致即可。
  • device文件夹 :保存外设驱动的源文件(.c文件)。
  • include文件夹 :保存程序中使用的头文件。
  • makefile :主makefile 。在主makefile中会调用“device”文件夹下的子makefile。

三、修改makefile

修改makefile主要包括两部分

  • 第一部分,在“device”文件夹下添加并编写子makefile。
  • 第二部分,修改主makefile。

3.1 编写子makefile

子makefile: 用于将“device”文件夹下的驱动源文件编译为一个“.o”文件

all : button.o  led.o
  arm-none-eabi-ld -r $^  -o device.o

%.o : %.c
  arm-none-eabi-gcc ${header_file} -c $^

%.o : %.S
  arm-none-eabi-gcc ${header_file} -c $^

.PHONY: clean
clean:
  -rm -f *.o *.bak
  • 添加最终目标以及依赖文件
    生成最终目标“device.o”。如果程序中新增了某个外设驱动程序,只需要将对应的“.o”文件填入“依赖”处即可。
    “$^” 代表所有的依赖文件。
    “-o” 指定输出文件名。
all : button.o  led.o
  arm-none-eabi-ld -r $^  -o device.o
  • 添加编译C文件的命令
    编译“device”文件夹下的所有“.c”文件并生成对应的“.o”文件,其中“header_file”是头文件路径,它是定义在主makefile的变量。
    “$^” 替代要编译的源文件。
%.o : %.c
  arm-none-eabi-gcc ${header_file} -c $^
  • 添加汇编文件编译命令
    编译“device”文件夹下的所有“.S”文件并生成对应的“.o”文件,其中“header_file”是头文件路径,它是定义在主makefile的变量。
    “$^” 替代要编译的源文件。
%.o : %.S
  arm-none-eabi-gcc ${header_file} -c $^
  • 添加清理命令
    “.PHONY” 定义了伪目标“clean”。伪目标一般没有依赖,并且 “clean” 伪目标一般放在Makefile文件的末尾。
    “clean” 为目标用于删除make生成的文件。
.PHONY: clean
clean:
  -rm -f *.o *.bak

3.2 修改主makefile

主makefile的改动主要有两点:

  1. 在编译命令中指明头文件位置。
  2. 使用命令调用子makefile,生成依赖文件。
#定义变量,用于保存编译选项和头文件保存路径
header_file := -fno-builtin -I$(shell pwd)/include
export header_file

all : start.o main.o device/device.o
  arm-none-eabi-ld -Tbase.lds $^ -o base.elf
  arm-none-eabi-objcopy -O binary -S -g base.elf base.bin

%.o : %.S
  arm-none-eabi-gcc -g -c $^
%.o : %.c
  arm-none-eabi-gcc $(header_file) -c $^

#调用其他文件的makefile
device/device.o :
  make -C device all

#定义清理伪目标
.PHONY: clean
clean:
  make -C device clean
  -rm -f *.o *.elf *.bin
  • 添加编译选项和头文件保存路径
    定义变量 “header_file”。在makefile中“变量”更像C原因中的宏定义。
    “-fno-builtin” 是一个编译选项,用于解决库函数与自己编写函数同名问题。
    “-I$(shell pwd)/include” 用于指定头文件路径。
    “export header_file” 声明后可以在其他makefile中调用。
header_file := -fno-builtin -I$(shell pwd)/include
export header_file
  • 添加最终目标以及依赖文件
all : start.o main.o device/device.o
  • 添加链接命令
    “-Tbase.lds” 表示使用base.lds链接脚本链接程序。
    “$^” 代表所有的依赖文件。
    “-o” 指定输出文件名。
arm-none-eabi-ld -Tbase.lds $^ -o base.elf
  • 添加格式转换命令
    “-O binary” 指定输出二进制文件。
    “-S” 不从源文件中复制重定位信息和符号信息。
    “-g” 不从源文件中复制可调试信息。
arm-none-eabi-objcopy -O binary -S -g base.elf base.bin
  • 添加汇编文件编译命令
    “$^” 替代要编译的源文件。
%.o : %.S
  arm-none-eabi-gcc -g -c $^
  • 添加编译C文件的命令
    “$^” 替代要编译的源文件。
%.o : %.c
  arm-none-eabi-gcc $(header_file) -c $^
  • 添加调用其他文件的makefile
    定义生成“device/device.o”的命令,“device.o”文件由子makefile生成,所以这里只需要调用子makefile即可。
device/device.o :
  make -C device all
  • 添加清理命令
    在清理命令中不但要清理主makefile所在文件夹的内容还要调用子makefile的清理命令以清理子makefile所在文件夹的内容。
    “.PHONY” 定义了伪目标“clean”。伪目标一般没有依赖,并且 “clean” 伪目标一般放在Makefile文件的末尾。
    “clean” 为目标用于删除make生成的文件。
.PHONY: clean
clean:
  make -C device clean
  -rm -f *.o *.elf *.bin

• 由 Leung 写于 2023 年 2 月 21 日

• 参考:9. 整理工程文件
    i.MX6ULL裸机开发 四:BSP 工程管理
    IMX6ULL——BSP工程管理Makefile文件格式
    【Linux裸机开发】-C语言点灯-基于NXP官方库及BSP项目工程管理
    IMX6Ull_BSP工程整理

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32开发(13)----获取唯一设备标识符UID

获取唯一设备标识符UID前言一、什么事UID二、实验过程1.CubeMx配置2.代码实现3.实验结果总结前言 这一章节介绍如何获取STM32芯片中的唯一的ID号的两种方法。 一、什么事UID 在许多项目中,识别设备是必要的。从简单的设备描述到更复杂的设备,如 USB 串…

Open3d入门

目录 点云数据 1 主成分分析 1.1 Method 1.2 Results 2 表面法线估计 2.1 Method 2.2 Results 3 体素网格下采样 3.1 Method 3.2 Results 点云数据 常用数据下载(免积分) 1 主成分分析 1.1 Method 对点云进行主成分分析(PCA&…

[5/101] 101次面试之经典面试题

目录 01、什么是黑盒测试? 02、为什么要做黑盒测试? 03、你在软件生命周期中的哪些测试阶段用到过黑盒测试? 04、什么是白盒测试? 05、白盒测试与黑盒测试有什么区别? 06、为什么要对程序进行单元测试? 07、由谁来做单元测试&#…

RK3566添加湿度传感器以及浅析hal层

RK3566添加一款温湿度传感器gxht3x.挂在i2c总线下。驱动部分就不多做解析。大致流程硬件接好i2c线以及vcc gnd。后看数据手册。初始化寄存器,然后要读数据的话读那个寄存器,读出来的数据要做一个转化,然后实现open read write ioctl函数就行了。本文主要…

【LeetCode】剑指 Offer 10- Ⅲ. 矩形覆盖 p79 -- Java Version

题目链接:无 1. 题目介绍(10- Ⅲ. 矩形覆盖 ) 我们可以用2x1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2x1的小矩形无重叠地覆盖一个2xn的大矩形,总共有多少种方法? 【测试用例】: 示例 1&#xff…

[学习笔记]Rocket.Chat业务数据备份

Rocket.Chat 的业务数据主要存储于mongodb数据库的rocketchat库中,聊天中通过发送文件功能产生的文件储存于/app/uploads中(文件方式设置为"FileSystem"),因此在对Rocket.Chat做数据移动或备份主要分为两步,…

JavaScript高级程序设计读书分享之4章——4.2执行上下文与作用域

JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 执行上下文 变量或函数的上下文决定 了它们可以访问哪些数据,以及它们的行为。在浏览器中,全局上下文就是我们常说的 window 对象(第 12 章会详细介绍)&am…

【技术分享】Web自动化之Selenium安装

Web 应用程序的验收测试常常涉及一些手工任务,例如打开一个浏览器,并执行一个测试用例中所描述的操作。但是手工执行的任务容易出现人为的错误,也比较费时间。因此,将这些任务自动化,就可以消除人为因素。Selenium 可以…

Js中blob、file、FormData、DataView、TypedArray

引言 最开始我们看网页时,对网页的需求不高,显示点文字,显示点图片就很满足了,所以对于浏览器而言其操作的数据其实并不多(比如读取本地图片显示出来,或上传图片到服务器),那么浏览器…

网络安全之认识挖矿木马

一、什么是挖矿木马? 比特币是以区块链技术为基础的虚拟加密货币,比特币具有匿名性和难以追踪的特点,经过十余年的发展,已成为网络黑产最爱使用的交易媒介。大多数勒索病毒在加密受害者数据后,会勒索代价高昂的比特币…

GEE学习笔记 六十三:新的地图图层ui.Map.CloudStorageLayer

在GEE中导出数据有一种方式是直接导出地图到Google Cloud Storage中,也就是Export.map.toCloudStorage(xxx),这种方式是将我们计算生成影像导出成为静态瓦片的格式存放在Google Cloud Storage中。我们可以在其他的前端程序比如OpenLayer、Mapbox GL JS等…

Python开发-学生管理系统

文章目录1、需求分析2、系统设计3、系统开发必备4、主函数设计5、 学生信息维护模块设计6、 查询/统计模块设计7、排序模块设计8、 项目打包1、需求分析 学生管理系统应具备的功能: ●添加学生及成绩信息 ●将学生信息保存到文件中 ●修改和删除学生信息 ●查询学生…

Docker之路(1.Docker概述、组成以及特点)

1.docker为什么会出现? 一款产品或者项目来说,一般有三个环境,日常/测试环境、预发环境、正式/线上环境 这么多环境,对其环境的配置是十分麻烦的,每一个机器都要部署环境,有的会有集群Redis、Hadoop等&…

最全es6数组方法

1.arr.push()从后面添加元素,返回值为添加完后的数组的长度 let arr [1,2,3,4,5] console.log(arr.push(5)) // 6 console.log(arr) // [1,2,3,4,5,5]2.arr.pop()从后面删除元素,只能是一个,返回值是删除的元素 let arr [1,2,3,4,5] console.log(arr.pop())//5 …

学UI设计,可以向哪些方向发展?该怎么学?

1、什么是UI设计?UI设计,全称 User Interface,翻译成中文意思叫做用户界面设计。2、UI设计的类型UI设计按用户和界面来分可分成四种UI设计。分别是移动端UI设计,PC端UI设计,游戏UI设计,以及其它UI设计。第一…

信号量(上)

竞争是协作的特例,竞争关系是属于协作关系 信号量可以解决协作关系存在的问题,那么它也可以解决竞争关系存在的问题 信号量 信号量就是一个整数 先等待,然后再发送信号 p在荷兰语中代表测试 v在荷兰语代表增加 这个函数的执行流需要自己画&a…

C# FFmpeg推流Vlc.DotNet拉流优化参数

FFmpeg是流媒体开源神器,视频转换、剪裁包括推流,无所不能,很多系统都是基于其开发的。拉流可以用FFplay,但是不利于集成到自己的代码中,因此拉流选择了Vlc.DotNet。 在使用中,仅使用默认参数,…

hadoop3.*集群搭建,小白必看

hadoop广义上讲是一个大数据生态圈,接受大量处理、处理大量数据的一个全套的框架!hadoop3.x版本以后,主要有三大模块,HDFS、YARN、mapReduce这三大核心组成!什么是HDFS?分布式文件系统,hadoop集群的功能类…

Centos7搭建hadoop3.3.4分布式集群

文章目录1、背景2、集群规划2.1 hdfs集群规划2.2 yarn集群规划3、集群搭建步骤3.1 安装JDK3.2 修改主机名和host映射3.3 配置时间同步3.4 关闭防火墙3.5 配置ssh免密登录3.5.1 新建hadoop部署用户3.5.2 配置hadoopdeploy用户到任意一台机器都免密登录3.7 配置hadoop3.7.1 创建目…

IO多路复用

文章目录1 概念2. IO多路复用的出现2.1 阻塞IO2.2 非阻塞IO2.3 IO 多路复用2.3.1 select2.3.2 poll2.3.3 epoll总结1 概念 IO多路复用(IO Multiplexing) 是一种同步IO模型,在单个进程/线程内就可以同时处理多个IO请求。一个进程/线程可以监视多个文件句柄&#xff…