Alpha lighting LED lamp (V) BSP project management

Tip: after the article is written, the directory can be generated automatically. Please refer to the help document on the right for how to generate it

preface

This is mainly to optimize the previous project, classify different files, learn how to sort out the project, create the folder classification of the project just like learning STM32, and realize the classification and modularization of project files, which is convenient for management

In depth study of Makefile, learn the advanced skills of Makefile, and learn to write a general makefile

Tip: the following is the main content of this article. The following cases can be used for reference

1, Engineering optimization

Put the source files of different functions in different directories. In addition, we also need to extract all the code that completes the same function from the source file and put it in a separate file, that is, the program is managed by function

Create a new project and create four folders: bsp, imx6ul, obj and project

bsp: store driver files
imx6ul: store chip related files, such as SDK library files
obj: store the compiled. o file
project: application files, that is, start.S and main.c files

Create three subfolders under the driver bsp folder: clk, delay and led, which are used to store clock driver files, delay driver files and LED driver files respectively

It is roughly shown in the figure below:

2, Path addition

Set the vscode header file path, first create the. vscode directory, and then open the c/c + + configurator to generate a file called C in the. vscode directory_ cpp_ Properties.json, and then add the path under includePath as follows

3, Written by 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 		:= imx6ul \
				   bsp/clk \
				   bsp/led \
				   bsp/delay 
				   			   
SRCDIRS			:= project \
				   bsp/clk \
				   bsp/led \
				   bsp/delay 
				   
				   
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)


Note: makefile is really a little uncomfortable. I don't know what it means to report an error. The error here is either the wrong makefile or the wrong link script.

1. Some variables are defined in the previous lines. Incdir contains the directory of. h files of the whole project, and all header file directories should be added to incdir; '' Yes line feed: indicates that this line and the next line belong to the same line= SRCDIRS contains the. c and. s file directories of the whole project file;

2.patsubst (pattern string replacement) is a Makefile function
Function prototype

$(patsubst < pattern>,< replacement>,< text>)

Find whether the words in < text > separated by "space", "Tab" or "carriage return" and "line feed" are correct
Match the pattern < pattern >, and if it matches, replace it with < replacement >. Here, < pattern > can include a wildcard "%", representing a string of any length.

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

Add a "- I" to the variable incdir through the function patsubst, because Makefile specifies the header file path, which requires - I
The original path becomes

INCLUDE := -I imx6ul -I bsp/clk -I bsp/led -I bsp/delay

3. Variable SFILES saves all. S assembly files (including absolute paths) in the project. Variable SRCDIRS has stored all. c and. S files in the project, so you only need to select all. S assembly files from it

foreach function, function: used for looping
Function prototype:

$(foreach < var>,< list>,< text>)

Take out the words in the parameter one by one, put them into the variable specified by the parameter, and then execute The contained expression. every time A string will be returned. During the loop, Each string returned by is separated by a space. Finally, when the whole loop ends, The entire string (separated by spaces) of each returned string will be the return value of the foreach function

Wildcard function is used to explicitly represent wildcards. In Makefile rules, wildcards will be automatically expanded, but wildcards will become invalid in variable definition and function reference. In this case, if you want the wildcard to be valid, you need to use the function wildcard
For example, $(wildcard *.c) "to get the list of all. c files in the working directory

SFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:= $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

Here SFILES will be expanded to:

SFILES = project/start.S
CFILES = project/main.c bsp/clk/bsp_clk.c bsp/led/bsp_led.c bsp/delay/bsp_delay.c

4. The variables SFILENDIR and CFILENDIR contain all. S assembly files and. c files. Compared with the variables SFILES and CFILES, SFILENDIR and CFILENDIR are only file names and do not contain the absolute path of the file. Use the function notdir to remove the path in SFILES and CFILES

Function prototype

$(notdir < names...>)

Take the directory part from the file name sequence < Names >. The directory part refers to the part before the last backslash ("/"), that is, the function under the directory in advance

SFILENDIR		:= $(notdir  $(SFILES))
CFILENDIR		:= $(notdir  $(CFILES))

It becomes as follows

SFILENDIR = start.S
CFILENDIR = main.c bsp_clk.c bsp_led.c bsp_delay.c

5. Variables SOBJS and COBJS are the corresponding. o file directories after compiling. S and. c files. By default, all compiled. o files and source files are in the same directory. Here we put all. o files in the obj folder. Variable OBJS is the collection of variables SOBJS and COBJS
The contents are as follows

SOBJS = obj/start.o
COBJS = obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o

OBJS = obj/start.o obj/main.o obj/bsp_clk.o obj/bsp_led.o obj/bsp_delay.o

==6.VPATH function: specify the search directory==

VPATH			:= $(SRCDIRS)

The search directory specified here is the directory saved by the variable SRCDIRS. When compiling, the required. S and. c files will be found in the directory specified in SRCDIRS

7. (. PHONY) is used to indicate that the target is a pseudo target
There is a "target" to clear them for complete recompilation, but the clean file is not generated. This is a pseudo target

"Pseudo target" is not a file, but a label. Because "pseudo target" is not a file, make cannot generate its dependencies and decide whether to execute it. Only by indicating this "target" can it take effect, and the name of "pseudo target" cannot be the same as the file name

In order to avoid the situation of duplicate file names, we can use a special tag ". PHONY" to indicate that a target is a "pseudo target" and explain to make that the target is a "pseudo target" whether there is a file or not

8.Makefile static mode, which makes it easier to define multi-objective rules and makes our rules more flexible and flexible
< targets ...>: < target-pattern>: < prereq-patterns ...>

Targets: defines a series of target files, which can have wildcards. It is a collection of targets
Target parrtern: indicates the mode of targets, that is, the target set mode
Prereq parrterns: the dependency pattern of the target. It defines the dependency target again for the pattern formed by the target parrtern

$(OBJS): obj/%.o : %.S  

Means that all. S files are compiled into. o and stored in the obj directory

The latter are familiar with compilation, linking and disassembly

4, Link scripts and Downloads

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

This is mainly to add the start.o file path

Finally, you can download the program

summary

Tip: here is a summary of the article:

Tags: C++ Linux Makefile Ubuntu

Posted on Mon, 29 Nov 2021 00:24:23 -0500 by dreams4000