ARM裸机开发:BSP工程管理
Posted JeckXu666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARM裸机开发:BSP工程管理相关的知识,希望对你有一定的参考价值。
ARM裸机开发:BSP工程管理
一、BSP工程管理
如果所有的源码放在一个文件夹目录下,在工程规模较大时会严重影响文档质量,不便于修改和定位文件,所以要对文件进行管理,便于用户开发与使用!
二、文件树
我们按照下面的目录创建四个文件夹
创建后如下:
将上一节的文件整理后按照四个部分放入,同时在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 = .;
}
到这工程管理基本完成,编译一下,通过
以上是关于ARM裸机开发:BSP工程管理的主要内容,如果未能解决你的问题,请参考以下文章