一、概述
工程源码较多时,将工程源码都放在同一目录下,会使工程目录混乱不堪。因此,需要将不通功能的工程源码文件放在不同的目录中,同时也方便程序分功能管理。
二、工程目录设计
三、工程配置
在 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
*(.text)
}
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : { *(.data) }
__bss_start = .;
.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
*(.text)
}
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : { *(.data) }
__bss_start = .;
.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 灯可以正常闪烁。
|