【ARM 裸机】BSP 工程管理

devtools/2024/10/21 7:41:15/

回顾一下上一节:【ARM 裸机】NXP 官方 SDK 使用,我们发现工程文件夹里面各种文件非常凌乱;
在这里插入图片描述
那么为了模块化整理代码,使得同一个属性的文件存放在同一个目录里面,所以学习 BSP 工程管理非常有必要。

1、准备工作

新建文件夹,准备将同一个属性的文件存放在一起;
在这里插入图片描述
将 .h 文件放在 imx6u 目录里面;
在这里插入图片描述
将 main.c 与 start.s 放在 project 目录里面;
在这里插入图片描述
进入 bsp 目录,新建三个目录(clk,delay,led);
在这里插入图片描述
现在在工程目录(5_ledc_bsp)的结构如下;
在这里插入图片描述
删除 ledc_sdk.code-workspace 工作区文件,然后在 VSCcode 中打开文件夹 5_ledc_bsp,然后将工作区另存为 ledc_bsp;
在这里插入图片描述
在这里插入图片描述

2、处理驱动文件

上面已经创建了 clk、delay、led 目录,但并未存放文件,需要创建对应的驱动文件并放在对应的目录;

2.1、clk

选择 clk,新建 bsp_clk.c 与 bsp_clk.h;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2、delay

选择 delay,新建 bsp_delay.c 与 bsp_delay.h;
在这里插入图片描述
在这里插入图片描述

2.3、led

选择 led,新建 bsp_led.c 与 bsp_led.h;
在这里插入图片描述
在这里插入图片描述

2.4、main.h

为了方便起见,在 project 目录下创建一个 main.h;
在这里插入图片描述
在 main.c 中的头文件包含如下;
在这里插入图片描述

2.5、设置 VScode 头文件路径

先创建 vscode 目录(在 VScode 中不好创建,直接在终端创建);
在这里插入图片描述
打开 c/c++ 配置器,在 VScode 中按住 ctrl + shift + p,输入 c/c++:ed 即可打开;
在这里插入图片描述
修改 c_cpp_properties.json 文件如下;
在这里插入图片描述
经过整理之后,现在的工程结构如下;
在这里插入图片描述
显然清晰且明,不再是乱乱的了。

3、重新编写 Makefile

在这里插入图片描述
原来的 Makefile 已经不能用了,需要重新编写才行,首先指定头文件和源文件;
在这里插入图片描述
需要使用 patsubst 函数,
在这里插入图片描述
在这里插入图片描述
测试一下 patsubst 函数的使用是否正确;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
wildcard 是关键字,可以让通配符在变量中展开,测试一下;
在这里插入图片描述
再来处理 obj 目录;
在这里插入图片描述
指定搜索路径;在这里插入图片描述
在这里插入图片描述
使用了 Makefile 的静态模式,$(SOBJS) : obj/%.o : %.s 这一行的意思是将所有的 .s 文件编译为 .o 文件并且存放到 obj 目录下, $(SOBJS) : obj/%.o : %.c 这一行的意思是将所有的 .c 文件编译为 .o 文件并且存放到 obj 目录下;
在这里插入图片描述
完整的 Makefile 文件如下;

CROSS_COMPILE   ?= arm-linux-gnueabihf-
TARGET          ?= ledcCC            := $(CROSS_COMPILE)gcc
LD            := $(CROSS_COMPILE)ld
OBJCOPY       := $(CROSS_COMPILE)objcopy 
OBJDUMP       := $(CROSS_COMPILE)objdumpINCUDIRS      := imx6u \bsp/clk \bsp/delay \bsp/led \SRCDIRS       := project \bsp/clk \bsp/delay \bsp/led \INCLUDE       := $(patsubst %,-I %, $(INCUDIRS))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).PHONY:clean$(TARGET).bin : $(OBJS)$(LD) -Timx6ul.lds -o $(TARGET).elf $^$(OBJCOPY) -O binary -S $(TARGET).elf $@$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis$(SOBJS) : obj/%.o : %.s$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<$(COBJS) : obj/%.o : %.c$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<clean:rm -rf $(OBJS)rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).disprint:@echo INCLUDE = $(INCLUDE)@echo SFILES  = $(SFILES)@echo CFILES  = $(CFILES)@echo SFILENDIR  = $(SFILENDIR)@echo CFILENDIR  = $(CFILENDIR)@echo SOBJS  = $(SOBJS)@echo COBJS  = $(COBJS)

4、编译

编译之前,修改一下 imx6u.lds,将原来的 start.o 改为 obj/start.o,main.o 可以去掉,保存;
在这里插入图片描述
在终端输入 make,可以看到 obj 目录下有很多输出文件;
在这里插入图片描述
在终端输入 make clean,可以看到 obj 目录下的输出文件被清理了;
在这里插入图片描述

5、烧写验证

在终端输入 ./imxdownload ledc.bin /dev/sdb 即可;
在这里插入图片描述
可以看到开发板上 led1 以 500 ms 的间隔进行亮灭。

好了,总结一下,可以说本节(BSP 工程管理)创建了一个基本的 ARM 裸机开发的模板,本节又添加了很多东西在 Makefile 里面,现在已经比较完善了,以后对于不同的工程,只需要修改一下工程名头文件路径源文件路径即可,连接脚本也是不需要修改什么,为我们的学习提供了大大的方便,打下了基础。


http://www.ppmy.cn/devtools/27455.html

相关文章

2024-04-30 区块链-以太坊-相关文档

摘要: 2024-04-30 区块链-以太坊-文档 以太坊-相关文档: https://github.com/ethereum/go-ethereum https://geth.ethereum.org/ https://geth.ethereum.org/docs https://ethereum.org/zh/ 以太坊开发文档 | ethereum.org 以太坊开发文档_w3cschool 以太坊开发文档 基础主题 …

JavaScript全套检验系统(LIS)源码C# + MVC + SQLserver + Redis 云LIS系统源码 区域医疗云LIS系统源码

JavaScript全套检验系统&#xff08;LIS&#xff09;源码C# MVC SQLserver Redis 云LIS系统源码 区域医疗云LIS系统源码 实验室信息系统&#xff08;Laboratory Information System&#xff0c;缩写LIS&#xff09;是一类用来处理实验室过程信息的软件。这套系统通常与其他信…

Ansible playbook之变量引用

1.Ansible facts facts是一个用于采集被管理机器设备信息的一个组件&#xff0c;我们可以使用setup模块查机器的所有facts信息&#xff0c;可以使用filter来查看指定信息。 [rootansible01 ~]# ansible 11.0.1.19 -m setup 11.0.1.19 | SUCCESS > {"ansible_facts&quo…

【大前端】ECharts 绘制立体柱状图

立体柱状图分为&#xff1a; 纯色立体柱状图渐变立体柱状图 常用实现方式 纯色立体柱状图 纯色立体柱状图&#xff0c;使用MarkPoint和颜色渐变就实现&#xff0c;如下代码 import * as echarts from "echarts";var chartDom document.getElementById("main&…

【docker】Docker开启远程访问

将构建的镜像自动上传到服务器。 需要开放 Docker 的端口&#xff0c;让我们在本地能连接上服务器的 Docker&#xff0c;这样&#xff0c;才能上传构建的镜像给 Docker。 开启远程访问 首先在服务器打开 Docker 的服务文件 vim /usr/lib/systemd/system/docker.service修改…

在 Python 中使用 PyPDF2 向 PDF 文件批量添加水印

目录&#xff1a; 使用 PyPDF2 添加水印到 PDF 文件批量添加水印到 PDF 文件所有页 PDF 文件广泛用于不同的设备和平台上&#xff0c;在某些情况下&#xff0c;可能需要在 PDF 文件中申明版权&#xff0c;需要将水印、条形码、二维码等添加到 PDF 中。PyPDF2 提供了一种将另一个…

面试笔记——多线程使用场景

线程池使用场景&#xff08;CountDownLatch&#xff0c; Future&#xff09; CountDownLatch CountDownLatch&#xff08;闭锁/倒计时锁&#xff09;用来进行线程同步协作&#xff0c;等待所有线程完成倒计时&#xff08;一个或者多个线程&#xff0c;等待其他多个线程完成某件…

k8s中deployment和StatefulSet构建的pod的区别

在Kubernetes中&#xff0c;Deployment和StatefulSet都是控制器对象&#xff0c;用于管理和扩展应用程序的Pod。它们之间的主要区别在于它们处理Pod的方式和适用的应用程序类型。 以下是Deployment和StatefulSet之间的主要区别&#xff1a; 有状态应用程序 vs 无状态应用程序&…