i.MX6ULL裸机开发 四:BSP 工程管理

一、概述

工程源码较多时,将工程源码都放在同一目录下,会使工程目录混乱不堪。因此,需要将不通功能的工程源码文件放在不同的目录中,同时也方便程序分功能管理

二、工程目录设计

  • bsp:用于存放驱动文件。

  • imx6ull:存放芯片相关文件。

  • obj:存放编译生成的文件。

  • user:存放 main.cstart.s

  • project:存放工程相关文件。

  • 顶层目录中存放 Makefileimx6ul.lds

三、工程配置

vscode 中进行开发,根据 vscode 相关规则进行配置。

打开 VSCode,按下 “Crtl+Shift+P” 打开 VSCode 的控制台,然后输入 “C/C++: Edit configurations(JSON) ”,打开 C/C++ 编辑配置文件。
在这里插入图片描述
打开以后会自动.vscode 目录下生成一个名为 c_cpp_properties.json 的文件,此文件默认内容如下所示:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

includePath 表示头文件路径,需要将包含头文件的目录都列举出来。修改后 c_cpp_properties.json 的文件内容如下:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "${workspaceFolder}/imx6ull",
                "${workspaceFolder}/user",
                "${workspaceFolder}/bsp/clock",
                "${workspaceFolder}/bsp/delay",
                "${workspaceFolder}/bsp/led"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

四、工程文件

1、imx6ul.lds

SECTIONS{
    . = 0X87800000;     /* 设置定位计数器(链接起始地址) */
    .text :
    {
        start.o         /* 开始位置的文件为start.o, start.o 里面包含着第一个要执行的指令 */
        *(.text)
    }
    .rodata ALIGN(4) : {*(.rodata*)}
    .data ALIGN(4) : { *(.data) }
    __bss_start = .;    /* '.' 为定位符, __bss_start 标志方便对 .bss 段清零 */
    .bss ALIGN(4) : { *(.bss) *(COMMON) }
    __bss_end = .;
}

2、Makefile

CROSS_COMPILE	?= arm-linux-gnueabihf-
TARGET			?= bsp

CC				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY			:= $(CROSS_COMPILE)objcopy
OBJDUMP			:= $(CROSS_COMPILE)objdump

INCDIRS			:= imx6ull \
				   bsp/clock \
				   bsp/delay \
				   bsp/led \
				   user

SRCDIRS			:= bsp/clock \
				   bsp/delay \
				   bsp/led \
				   user

INCLUDE			:= $(patsubst %, -I %, $(INCDIRS))

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 $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)

1、指定编译工具

CROSS_COMPILE	?= arm-linux-gnueabihf-
TARGET			?= bsp

CC				:= $(CROSS_COMPILE)gcc
LD				:= $(CROSS_COMPILE)ld
OBJCOPY			:= $(CROSS_COMPILE)objcopy
OBJDUMP			:= $(CROSS_COMPILE)objdump

2、patsubst

名称:模式字符串替换函数 - patsubst

格式$(patsubst pattern,replacement,text)

功能:查找 text 中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式 pattern,如果匹配的话,则以 replacement 替换。pattern 可以包括通配符 “%”,表示任意长度字串。如果 replacement 中也包含 “%”,那么,replacement 中的这个 “%” 将是 pattern 中的那个 “%” 所代表的字串。

:% - 匹配符(详细讲解见:(15条消息) Makefile中的匹配符%_随波一落叶-CSDN博客_makefile中的%

示例
$(patsubst %.c,%.o, a.c b.c)

把字串 “a.c b.c” 符合模式 [%.c] 的单词替换成 [%.o],返回结果是 “a.o b.o”

3、foreach

名称:循环函数 - foreach

格式$(foreach var text commond)

  • var:局部变量
  • text:文件列表
  • commond:对var变量进行操作(一般会使用var变量,不然没意义),每次操作结果都会以空格隔开,最后返回空格隔开的列表。

功能:循环处理文件列表

举例

names := a b c d
files := $(foreach n,$(names),$(n).o)

$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”

4、wildcard

名称:扩展通配符函数 - wildcard

格式$(wildcard PATTERN...)

功能:在Makefile规则中,通配符会被自动展开。但在变量的定义函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard"。在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空

举例$(wildcard \*.c)来获取工作目录下的所有的.c文件列表。

5、notdir

名称:取文件名函数 - notdir

格式$(notdir NAMES…)

功能:剥离文件的绝对路径,只保留文件名。

举例$(notdir src/foo.c hacks) ,返回值为:“foo.c hacks”

6、SFILENDIR:.s=.o

所有的 .s 文件后缀变为.o 的文件。

3、编译

make 以后报如下错误:

onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$ make
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/start.o user/start.s
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/clock.o bsp/clock/clock.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/delay.o bsp/delay/delay.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/led.o bsp/led/led.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/main.o user/main.c
arm-linux-gnueabihf-ld -Timx6ul.lds -o bsp.elf obj/start.o obj/clock.o obj/delay.o obj/led.o obj/main.o
arm-linux-gnueabihf-ld: cannot find start.o
make: *** [Makefile:37: bsp.bin] Error 1
onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$

查看 obj 目录,发现 start.o 成功生成。

onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp/obj$ ls -l
total 20
-rw-rw-r-- 1 onlylove onlylove  843 Dec  7 08:14 clock.o
-rw-rw-r-- 1 onlylove onlylove  846 Dec  7 08:14 delay.o
-rw-rw-r-- 1 onlylove onlylove  950 Dec  7 08:14 led.o
-rw-rw-r-- 1 onlylove onlylove 1128 Dec  7 08:14 main.o
-rw-rw-r-- 1 onlylove onlylove  708 Dec  7 08:14 start.o
onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp/obj$

通过以上分析,确定找不到 start.o 文件,因此调整 imx6ul.lds 链接脚本。

4、调整 imx6ul.lds

SECTIONS{
    . = 0X87800000;     /* 设置定位计数器(链接起始地址) */
    .text :
    {
        obj/start.o         /* 开始位置的文件为start.o, start.o 里面包含着第一个要执行的指令 */
        *(.text)
    }
    .rodata ALIGN(4) : {*(.rodata*)}
    .data ALIGN(4) : { *(.data) }
    __bss_start = .;    /* '.' 为定位符, __bss_start 标志方便对 .bss 段清零 */
    .bss ALIGN(4) : { *(.bss) *(COMMON) }
    __bss_end = .;
}

调整 start.o 路径。

5、再次编译

onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$ ls -l
total 28
drwxrwxr-x 5 onlylove onlylove 4096 Dec  7 07:06 bsp
drwxrwxr-x 2 onlylove onlylove 4096 Dec  7 07:49 imx6ull
-rw-rw-r-- 1 onlylove onlylove  465 Dec  7 08:19 imx6ul.lds
-rw-rw-r-- 1 onlylove onlylove 1151 Dec  7 08:12 Makefile
drwxrwxr-x 2 onlylove onlylove 4096 Dec  7 08:20 obj
drwxrwxr-x 2 onlylove onlylove 4096 Dec  7 07:04 project
drwxrwxr-x 2 onlylove onlylove 4096 Dec  7 07:15 user
onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$ make
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/start.o user/start.s
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/clock.o bsp/clock/clock.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/delay.o bsp/delay/delay.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/led.o bsp/led/led.c
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2  -I imx6ull  -I bsp/clock  -I bsp/delay  -I bsp/led  -I user -o obj/main.o user/main.c
arm-linux-gnueabihf-ld -Timx6ul.lds -o bsp.elf obj/start.o obj/clock.o obj/delay.o obj/led.o obj/main.o
arm-linux-gnueabihf-objcopy -O binary -S bsp.elf bsp.bin
arm-linux-gnueabihf-objdump -D -m arm bsp.elf > bsp.dis
onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$ ls -l
total 48
drwxrwxr-x 5 onlylove onlylove  4096 Dec  7 07:06 bsp
-rwxrwxr-x 1 onlylove onlylove   276 Dec  7 08:20 bsp.bin
-rw-rw-r-- 1 onlylove onlylove  5081 Dec  7 08:20 bsp.dis
-rwxrwxr-x 1 onlylove onlylove 66915 Dec  7 08:20 bsp.elf
drwxrwxr-x 2 onlylove onlylove  4096 Dec  7 07:49 imx6ull
-rw-rw-r-- 1 onlylove onlylove   465 Dec  7 08:19 imx6ul.lds
-rw-rw-r-- 1 onlylove onlylove  1151 Dec  7 08:12 Makefile
drwxrwxr-x 2 onlylove onlylove  4096 Dec  7 08:20 obj
drwxrwxr-x 2 onlylove onlylove  4096 Dec  7 07:04 project
drwxrwxr-x 2 onlylove onlylove  4096 Dec  7 07:15 user
onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$

通过以上日志可以看到,编译成功。

五、验证

onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$ ./imxdownload bsp.bin /dev/sdb
I.MX6ULL bin download software
Edit by:zuozhongkai
Date:2019/6/10
Version:V1.1
log:V1.0 initial version,just support 512MB DDR3
    V1.1 and support 256MB DDR3
file bsp.bin size = 276Bytes
Board DDR SIZE: 512MB
Delete Old load.imx
Create New load.imx
Download load.imx to /dev/sdb  ......
[sudo] password for onlylove: 
6+1 records in
6+1 records out
3348 bytes (3.3 kB, 3.3 KiB) copied, 0.0147718 s, 227 kB/s
onlylove@ubuntu:~/linux/driver/board_driver/4_ledbsp$

通过开发板验证,led 灯可以正常闪烁。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值