架构描述
客制化部分的跨平台实现的意义:对于使用linux方案的公司而言,在boot的客制化过程中,由于管控松懈,需求不稳定。导致客制化部分与原厂(芯片原厂与u-boot)的代码耦合性较高,也造成了切换新的平台(尤其是新的厂家)的时候,boot中有不少适配工作,极易漏掉曾经的patch、feature等,且极不方便前期方案评估的时候快速完成demo看效果。在后期也会形成维护多个平台的uboot,导致维护量繁重。究其原因,主要有二:1,客制化部分与原厂嵌套,混杂。2,底层接口(GPIO、IIC、PWM、ADC、FS等)需要重新适配,每个模块都是直接调用原厂接口,故都需要更改。以上问题也就造成了新平台来的时候,代码搬过去会有大量报错,也会有嵌套进原厂的部分遗漏。
为了在boot中降低和原厂的耦合,将不同底层接口区分出来形成platform层,提供一套API给不同模块使用,再使用统一定义的数据类型,即可以让客制化部分限制于我们提供的platform层之上。而在原厂中添加我们的客制化流程则通过命令将其抽为功能命令插入。即在新平台上,只需要添加客制化的命令插入和底层HAL层的驱动适配即可完成我们客制化功能的在新的boot上的适配。整体如下图所示
即通过上图所示方案进行对原生代码和客制化形成Platform API的隔离,在不同的平台上面通过适配底层驱动来完成跨平台的实现。而在代码的插入上,个人比较倾向于将Platform以上以Customer.a 将Platform以下以 CustomerPlatform.a的形式插入到原生代码中。这样也方便与原厂联调的时候给对方我们的环境(只提供.a,不用泄露代码文件)。
即在客制化部分上可以分为:功能命令、设备驱动、porting对接层、系统信息层(ENV、INI)
而command、drivers、SysInfo编译为libcustomer.a porting编译为 libplatform.a
而porting层则是分为平台适配层和API接口,平台适配根据配置文件进行选择性的编译。从而实现跨平台的实现。
customer.a makefile如下:
#####################################################################
##文件名: Makefile
##功能描述:
##Copyright:locke
##函数列表:
##作者:locke
##日期:2019-10-8
##版本历史:
#####################################################################
include $(TOPDIR)/config.mk
LIB = $(obj)liblocke.a
#AOBJS =
COBJS =
include ./command/Makefile
include ./SysInfo/Makefile
include ./drivers/Makefile
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix ( o b j ) , (obj), (obj),(AOBJS) $(COBJS))
all: $(LIB)
$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
#defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################
platform.a的makefile如下
#####################################################################
##文件名: Makefile
##功能描述:
##Copyright:locke
##函数列表:
##作者:locke
##日期:2019-10-9
##版本历史:
#####################################################################
include $(TOPDIR)/config.mk
LIB = $(obj)libplatform.a
#AOBJS =
COBJS =
#portingApi ###
CFLAGS += -I./portingApi/inc/
CFLAGS += -I./portingApi/src/
CPPFLAGS += -I./portingApi/inc/
CPPFLAGS += -I./portingApi/src/
COBJS += ./portingApi/src/PortingGPIO.o
COBJS += ./portingApi/src/PortingIIC.o
COBJS += ./portingApi/src/PortingSAR.o
COBJS += ./portingApi/src/PortingPWM.o
COBJS += ./portingApi/src/PortingVFS.o
COBJS += ./portingApi/src/PortingCRI.o
COBJS += ./portingApi/src/PortingINI.o
ifeq ( ( C O N F I G O R I G I N A L P L A T F O R M ) , " m s t a r " ) i n c l u d e . / p o r t i n g m s t a r . m k e l s e i f e q ( (CONFIG_ORIGINAL_PLATFORM), "mstar") include ./porting_mstar.mk else ifeq ( (CONFIGORIGINALPLATFORM),"mstar")include./portingmstar.mkelseifeq((CONFIG_ORIGINAL_PLATFORM), “amlogic”)
include ./porting_amlogic.mk
else
include ./porting_mstar.mk
endif
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix ( o b j ) , (obj), (obj),(AOBJS) $(COBJS))
all: $(LIB)
$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
#defines $(obj).depend target
( w a r n i n g ∗ ∗ ∗ (warning *** (warning∗∗∗(CFLAGS) $(SRCS)*****locke)
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################
接口层的抽象