(BSP) how is a large project file built?

Posted by LAEinc. Creations on Fri, 03 Dec 2021 21:56:14 +0100

How is a big project file built? (BSP)

Introduction to key contents:

  1. Project directory framework?
  2. What kind of files should be included in each directory?
  3. How to write a makefile for a project with multiple folders?

1. What is BSP?

Board level support package (BSP) is a layer between the main board hardware and the driver layer program in the operating system. It is generally considered to be a part of the operating system. It is mainly to support the operating system and provide the upper driver with a function package to access the hardware device register, so that it can run better on the hardware main board.

BSP function:

  1. Board hardware initialization is mainly CPU initialization, which provides bottom hardware support for the whole software system
  2. Provide device drivers and system interrupt service programs for the operating system
  3. Customize the functions of the operating system to provide a real-time multi task running environment for the software system
  4. Initialize the operating system to prepare for the normal operation of the operating system.

Does it feel like a bootloader? In fact, according to the data I checked, the BSP in a broad sense can be regarded as bootloader + kernel + rootfs.

The content of pure BSP is generally related to system drivers and programs, such as network drivers related to network protocols in the system, serial drivers related to system download and debugging, and so on.

Therefore, an example I give here, s is based on bare metal and directly drives led, which includes files such as activating CPU, configuring running environment, running main program, etc.

2. A simple BSP framework

1) First there is a imx6ul folder:

Some header files will be placed in this folder. These header files are transplanted to the official SDK. There are some register configurations and some function interfaces provided by the official.

2) There is also a non-standard Function Library folder:

This folder can also be divided into different directories according to different functions. For example, delay function, clock enable function, led lighting function, etc.

Generally, a C file, and then encapsulate the functions inside into a header file to provide the interface.

3) Of course, there are project folders:

There are main functions. If it is bare metal, it can also include some assembly files to build a good C environment.

4) And the last destination folder:

Put the compiled target file.

5) There are also makefile s and connection script files in the home directory

3. How to write a general makefile file?

This has a large internal capacity. First put the code here, and then say when you have time next time (the tutor will urge you to work, and the little partners of the postgraduate entrance examination must not choose too many teachers!!!)

CROSS_COMPILE ?= arm-linux-gnueabihf-#This line can be changed for different compilers
TARGET		  ?= bsp#The name of the target should also be changed for different processes

CC			  := $(CROSS_COMPILE)gcc
LD			  := $(CROSS_COMPILE)ld
OBJCOPY		  := $(CROSS_COMPILE)objcopy
OBJDUMP		  := $(CROSS_COMPILE)objdump
#The variable INCDIRS contains the. h header file directory of the whole project. All header file directories in the file should be added to the variable INCDIRS
INCDIRS		  := imx6ul \
				bsp/clk \
				bsp/led \
				bsp/delay
#SRCDIRS contains all. c and. S file directories of the whole project
SRCDIRS 	  := project \
			  := bsp/clk \
			  := bsp/led \
			  := bsp/delay
#The variable INCLUDE uses the function patsubst. Add a "- I" to the variable incdir through the function patsubst, because the Makefile syntax requires that "- I" be added when indicating the header file directory
INCLUDE		  := $(patsubst %, -I %, $(INCDIRS))

#The variable SFILES saves all. S assembly files (including absolute paths) in the project. The variable SRCDIRS has stored all. c and. S files in the project, so we only need to pick out all. S assembly files from it
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))

#The variable CFILES is the same as the variable SFILES, except that CFILES saves all. c files (including absolute paths) in the project
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

#Use the function notdir to remove the paths in SFILES and CFILES
SFILENDIR := $(notdir $(SFILES))
CFILENDIR := $(notdir $(CFILES))

#By default, all compiled. o files and source files are in the same directory
SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))

#The variable OBJS is a collection of variables SOBJS and COBJS
OBJS := $(SOBJS) $(COBJS)

#VPATH specifies the search directory. The search element directory specified here is the directory saved by the variable SRCDIRS, so that the required. S and. c files will be found in the directory specified in SRCDIRS when compiling
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)

Topics: Linux