1. 合并的背景
项目A和B都是采用同一个处理器和操作系统,B项目的外围设备基本上是A项目下的一个子集,GPIO口的分配也基本一样,不同的是显示屏采用的接口不一样,A项目用I80接口,而B项目采用RGB接口,在我来公司之前,可能是因为各自开发方便,A和B项目就维护独立的BSP包,但这样的方式的缺点就是,假如你解决了A项目和B项目中共同的bug的时候,就要把相应的代码分别移植到这两个BSP包中,这不仅增加没必要的工作量,而且有可能会出错。
随着项目A和项目B的推进,发现之前采用的MLC flash不是很稳定,偶尔会出现丢固件的现象,就决定了换为SLC flash,所以A项目就有MLC和SLC这两个BSP,B项目也会有自己的MLC和SLC这两个BSP,这样就需要开发和维护4个BSP包,这肯定会浪费很多时间做没有效益的维护,为了节省时间及便于后续的维护和开发,我决定把这4个BSP包合并为一个BSP包,下面就合并过程中遇到的问题和解决的方式总结一下。
2. 不通的项目通过设置环境变量指定需要编译的文件夹
这部分涉及到dirs文件和 smdk2451.bat文件,因为项目A比项目B多了dirvierC和dirverD驱动文件夹,在编译B项目的系统时间,不需要编译dirvierC和dirverD,那该怎么处理呢?首先在smdk2451.bat文件做如下定义
Set BSP_PROJECT_A=1
Set BSP_PROJECT_B=
set BUILD_OPTIONS=
if /i "% BSP_PROJECT_A %"=="" set BUILD_OPTIONS=%BUILD_OPTIONS% dirvierC dirverD
再结合smdk2451\SRC\DRIVERS文件夹下dirs文件下面的内容就可以实现:
DIRS=\
drvlib \
……
BACKLIGHT\
OPTIONAL_DIRS=dirvierC\
dirverD\
DIRS后面指定项目A和项目B共有的需要编译的驱动文件夹,OPTIONAL_DIRS指定可以选择编译的目录。比如:OPTIONAL_DIRS=proj1,如果想编译proj1目录,可以设置BUILD_OPTIONS=proj1,然后运行build命令就可以了。这里是指如果要编译A项目,在dirvers驱动文件夹下就需要多编译dirverC和dirverD这两个目录下的源代码。
我们的项目A又因为需要支持MLC和SLC,而MLC和SLC需要支持的源代码是不一样的,在bootloader文件夹下有MLC和SLC共用的文件夹有NBL1.IROM_SD和Eboot,而MLC还有NBL1.LSB和NBL2,,SLC有STEPLDR,对于MLC系统,我只想编译共用的和NBL1.LSB和NBL2文件夹,对于SLC系统来说,我只想编译共用的和STEPLDR文件夹,那么该如何处理呢?见bootloader\dirs中的内容:
OPTIONAL_DIRS=STEPLDR\
NBL1.LSB\
NBL2\
这是SLC和MLC分别独有的代码,由smdk2451.bat部分来控制编译
DIRS= \
NBL1.IROM_SD \
Eboot
DIRS这部分是MLC和SLC共有的源代码文件夹,如果我当前要编译MLC的系统,在下smdk2451.bat中的处理部分如下:
set BSP_MLC=1
set BSP_SLC=
if /i "%BSP_MLC%"=="1" set BUILD_OPTIONS=%BUILD_OPTIONS% NBL1.LSB NBL2
if /i "%BSP_SLC%"=="1" set BUILD_OPTIONS= %BUILD_OPTIONS% STEPLDR
其他部分的源代码文件夹在那个项目哪个配置下是否需要编译,有了上面这些介绍,应该就很容易控制了。
3. 不同的项目通过环境变量编译不同的源代码文件等
这部分主要涉及smdk2451.bat和sources的控制,比如bootloader\eboot\sources下的一部分内容如下:
!IF "$(BSP_MLC)" == "1"
INCLUDES=$(INCLUDES);$(_TARGETPLATROOT)\src\inc;$(_TARGETPLATROOT)\src\Whimory\Inc;$(_TARGETPLATROOT)\src\Whimory\Core\VFL;$(_TARGETPLATROOT)\src\Whimory\OAM\OSLess;
!ENDIF
!IF "$(BSP_SLC)" == "1"
INCLUDES=$(INCLUDES);$(_TARGETPLATROOT)\Src\Common\Smartmedia\Fmd
!ENDIF
其中INCLUDES指定额外的要搜索的头文件的路径,这里的重点是通过判断是否在smdk2451.bat中定义BSP_MLC还是BSP_SLC来决定是否包含要额外的要搜索的头文件的路径了。如此类推,sources文件中的其他部分,如TARGETLIBS、SOURCES部分也用这样的方式来控制,比如SOURCES部分,MLC需要多编译nand_mlc.cpp文件,而SLC需要多编译nand_slc.cpp,那么可以这样处理:
SOURCES= \
startup.s \
util.s \
main.c \
……
nand.s\
!IF "$(BSP_MLC)" == "1"
SOURCES=$(SOURCES) nand_mlc.cpp
!ENDIF
!IF "$(BSP_SLC)" == "1"
SOURCES=$(SOURCES) nand_slc.cpp
!ENDIF
这里很巧妙地用到了$(SOURCES),那么SOURCES=$(SOURCES) nand_mlc.cpp就可以把上面共用的部分和nand_mlc.cpp合并起来,告诉编译器此驱动文件夹需要编译的源代码文件。
另外学习一下sources文件下CDEFINES的定义
!IF "$(BSP_LCDTYPE)" == "LCD_HX"
CDEFINES=$(CDEFINES) -DLCD_HX
!ENDIF
表示如果在环境变量BSP_LCDTYPE的值为LCD_HX,就定义LCD_HX,其中它前面的-D相当于#define的意思,这样此sources文件中的文件都可以使用LCD_HX来做对应的处理了。