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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
上一節我們的 main 文件中,把各個外設的初始化以及中間調用函數都寫在了一起,不便于維護,此處我們進行優化,將每部分功能都單獨寫到不同的文件中去,比如 bsp_led.c 和 .h 文件就分別寫入如下內容:
bsp_led.h
#ifndef __BSP_LED_H #define __BSP_LED_H void LED_INIT(void); #endif
1
2
3
4
5
6
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); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
其他文件類似編寫,之后我們就可以在主函數中進行調用
#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; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
到上面工程管理基本完成,沒事什么難度,參考 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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
這里的鏈接文件規則如下
SECTIONS{ . = 0X87800000; .text : { obj/start.o *(.text) } .rodata ALIGN(4) : {*(.rodata*)} .data ALIGN(4) : { *(.data) } __bss_start = .; .bss ALIGN(4) : { *(.bss) *(COMMON) } __bss_end = .; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
到這工程管理基本完成,編譯一下,通過
ARM
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。