ARM裸机开发:BSP工程管理

本文介绍了ARM裸机开发中BSP工程的管理方法,包括文件树结构的建立和驱动文件的组织,强调了良好的文件管理对于代码维护的重要性。此外,还详细展示了如何编写Makefile进行编译脚本,包括变量定义、源文件路径处理和编译规则,以实现项目的自动化构建。通过这个过程,开发者可以更高效地管理自己的代码,并且理解Linux环境下裸机程序的构建流程。
摘要由CSDN通过智能技术生成

ARM裸机开发:BSP工程管理

一、BSP工程管理

如果所有的源码放在一个文件夹目录下,在工程规模较大时会严重影响文档质量,不便于修改和定位文件,所以要对文件进行管理,便于用户开发与使用!

二、文件树

我们按照下面的目录创建四个文件夹

BSP工程管理

创建后如下:

20211030111443

将上一节的文件整理后按照四个部分放入,同时在bsp下按如下目录新建三个驱动文件夹和对应的驱动文件,文件目树如下:

.
├── bsp
│   ├── bsp_clk
│   │   ├── bsp_clk.c
│   │   └── bsp_clk.h
│   ├── bsp_delay
│   │   ├── bsp_delay.c
│   │   └── bsp_delay.h
│   └── bsp_led
│       ├── bsp_led.c
│       └── bsp_led.h
├── imx6ul
│   ├── fsl_common.h
│   ├── fsl_iomuxc.h
│   ├── MCIMX6Y2.h
│   └── new_type.h
├── imx6ul.lds
├── imxdownload
├── Makefile
├── obj
└── project
    └── main.c
    └── main.h

上一节我们的 main 文件中,把各个外设的初始化以及中间调用函数都写在了一起,不便于维护,此处我们进行优化,将每部分功能都单独写到不同的文件中去,比如 bsp_led.c 和 .h 文件就分别写入如下内容:

bsp_led.h

#ifndef __BSP_LED_H
#define __BSP_LED_H

void LED_INIT(void);

#endif

bsp_led.c

#include "bsp_led.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"

#define LED_ON() (GPIO1->DR &= ~(1<<3))
#define LED_OFF() (GPIO1->DR |= (1<<3))

void LED_INIT(void)
{
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0x10b0);

    GPIO1->GDIR |= (1 << 3);
    GPIO1->DR &= ~(1 << 3);
}

其他文件类似编写,之后我们就可以在主函数中进行调用

#include "main.h"
#include "bsp_led.h"
#include "bsp_clk.h"
#include "bsp_delay.h"

int main(void)
{
    CLK_INIT();
    LED_INIT();
    while (1)
    {
        /* code */
        LED_ON();
        delay(10000);
        LED_OFF();
        delay(10000);
    }
    return 0;   
}

到上面工程管理基本完成,没事什么难度,参考 STM32 工程创建就很容易理解

三、Makefile 编写

Linux 因为我们没用使用集成编译器,使用需要我们自己编写编译脚本,编译脚本如下,关于脚本每一行的意思,我以注释的形式写在构建脚本中:

# 赋值变量,与编译器相关
CROSS_COMPILE 	?= arm-linux-gnueabihf-
# 赋值变量,目标文件名称
TARGET		  	?= bsp_led
# 赋值变量,与编译器相关
CC 				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY 		:= $(CROSS_COMPILE)objcopy
OBJDUMP 		:= $(CROSS_COMPILE)objdump
#头文件包含路径 '\'为换行符号
INCDIRS 		:= imx6ul  \
				   project \
				   bsp/bsp_clk \
				   bsp/bsp_led \
				   bsp/bsp_delay 
#源文件包含的路径
SRCDIRS			:= project \
				   bsp/bsp_clk \
				   bsp/bsp_led \
				   bsp/bsp_delay 
# 通过函数 patsubst 给变量 INCDIRS 开头添加一个 "-I"
# 因为 Makefile 语法要求指明头文件目录的时候需要加上 "-I"
INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))
# 获得.s和.c结尾文件名变量路径
# 使用 foreach 函数,依次取出 SRC 到 dir,再执行后面的指令
SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
# notdir 函数去掉路径,获得文件名称
SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))
# 变量 SOBJS 和 COBJS 是.S 和.c 文件编译以后对应的 .o 文件目录,这里添加到 obj 目录下
SOBJS			:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS			:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
# 所有 obj目录下.o文件变量集合
OBJS			:= $(SOBJS) $(COBJS)

VPATH			:= $(SRCDIRS)

.PHONY: clean

#链接,o文件,转elf为二进制文件,同时生成反汇编文件
$(TARGET).bin : $(OBJS)
	$(LD) -Timx6ul.lds -o $(TARGET).elf $^
	$(OBJCOPY) -O binary -S $(TARGET).elf $@
	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
#编译.s文件
$(SOBJS) : obj/%.o : %.S
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<
#编译.c文件
$(COBJS) : obj/%.o : %.c
	$(CC) -Wall -nostdlib -c -O2  $(INCLUDE) -o $@ $<
#清除生成文件
clean:
	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)

这里的链接文件规则如下

SECTIONS{
	. = 0X87800000;
	.text :
	{

		obj/start.o 
		*(.text)
	}
	.rodata ALIGN(4) : {*(.rodata*)}     
	.data ALIGN(4)   : { *(.data) }    
	__bss_start = .;    
	.bss ALIGN(4)  : { *(.bss)  *(COMMON) }    
	__bss_end = .;
}

到这工程管理基本完成,编译一下,通过

20211030134130

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Top嵌入式

投喂个鸡腿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值