九、C语言版LED试验工程管理

工程管理主要是在 Makefile 中会对一些源文件的地址引用和输出文件地址定位,按照学习指南的给出的公共结构如图,对于该目录结构的工程,编写Makefile如下。

LED工程结构

CROSS_COMPILE             ?= arm-linux-gnueabihf-       # ?= 如果没有定义,则定义为
TARGET                    ?= bsp

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

# \ 是换行符,表示下一行与这一行为同一行。INCDIRS 是所有头文件的文件夹
INCDIRS         := imx6ul \                     
                   bsp/clk \
                   bsp/led \
                   bsp/delay 
#  SRCDIRS 源代码所在的文件夹                                  
SRCDIRS            := project \
               bsp/clk \
               bsp/led \
               bsp/delay 
                   

#  使用 patsubst 函数把    INCDIRS 中的每一个文件夹替换成 -I $(folder) 的格式,因为Makefile 指明头文件目录时 需要在前面加上 -I       
INCLUDE            := $(patsubst %, -I %, $(INCDIRS))

#  先使用 foreach 函数取出SRCDIRS每个文件,然后用wildcard 函数匹配出.S结尾的文件,匹配出的文件带目录路径
SFILES            := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES            := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

#  先使用 notdir  函数去除路径
SFILENDIR        := $(notdir  $(SFILES))
CFILENDIR        := $(notdir  $(CFILES))

#  先使用变量替换,把SFILENDIR里面的.S文件替换成.o文件,然后用patsubst 给这些文件带上路径 obj/
SOBJS            := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS            := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS            := $(SOBJS) $(COBJS)

# 指定搜索目录VPATH,使用 VPATH 指明源文件路径,如果不指明,make只会在当前的目录中去找寻依赖文件和目标文件
VPATH            := $(SRCDIRS)

.PHONY: clean

# bsp.bin 依赖 obj/ 目录下的 .o 文件,因为当前obj/目录下还为空,会执行下面的依赖    
$(TARGET).bin : $(OBJS)
    $(LD) -Timx6ul.lds -o $(TARGET).elf $^
    $(OBJCOPY) -O binary -S $(TARGET).elf $@
    $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

# obj/ 目录下面的 .o 文件依赖于 .S 文件
$(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)

这里的链接脚本与之前的基本一致,就是要注意 .text 里面的 文件要加路径 obj/start.o

十、U-Boot 使用试验

(1)Linux 移植介绍

Linux 的移植较,在移植 Linux之前我们需要先移植一个 bootloader 代码,这个 bootloader 代码用于启动 Linux 内核, bootloader有很多,常用的就是 U-Boot。移植好 U-Boot 以后再移植 Linux 内核,移植完 Linux 内核以后Linux 还不能正常启动,还需要再移植一个根文件系统(rootfs),根文件系统里面包含了一些最常用的命令和文件。所以 U-Boot、 Linux kernel 和 rootfs 这三者一起构成了一个完整的 Linux 系统,一个可以正常使用、功能完善的 Linux 系统。

(2)编译U-boot

用正点原子给出的Uboot,放到文件夹下后,先解压缩 tar -vxjf uboot-imx-2016.03-2.1.0-ge468cdc-v1.5.tar.bz2 。本来很简单,没想到在编译的过程中,出现了 cp: write error: No space left on device,后面用命令 df -h 一查,原来是虚拟机的存储空间满了。删了一些东西后,转念一想不如直接建一个软连接,直接可以在Linux虚拟机里方便的用Windows里面的文件,于是使用命令 ln -s /media/sf_Share ~/share.soft 建了一个软连接。接着就是开始编译发现又失败了,这此的原因又是下面的提示,再一看,应该是创建的软链接跨了磁盘,然后在mkae里面又尝试创建ln硬链接,注意到硬链接不能跨分区。试了试不在软连接里面使用 ln,发现还是不行,应该是在加载的盘符中无法创建硬链接吧,后面查到,建立硬链接时,链接文件和被链接文件必须位于同一个文件系统中,并且不能建立指向目录的硬链接,于是只能等明天再试试了。

ln -fsn $dest arch/arm/include/asm/arch
ln: failed to create symbolic link 'arch/arm/include/asm/arch': Operation not permitted

果然第二次尝试,把整个目录拷贝到了home目录下,然后编译,就编译成功了。用到的指令如下,因为我只有四个核,所以最后一行的 j12 改成了 j4
编译用到的指令

编译成功后的提示如下:
image.png


cheney
7 声望0 粉丝

引用和评论

0 条评论