上上一篇文章《图像识别DM8127开发攻略——开发环境搭建》介绍了DM8127的开发环境搭建,那么本篇开始描述整个IPNC RDK的架构,如果这个IPNC RDK都不熟悉,后面的移植工作基本无法进行下去,也无法深入学习和掌握DM8127的开发流程。要熟悉APPRO DM8127 软件架构,先看IPNC_RDK_InstallGuide.pdf,然后再去看看RDK包里Collaterals文件目录下的两个重要文件:IPNC_RDK_McFW_UserGuide.pdf和IPNC_RDK_Application_DesignGuide.pdf,我们下面的介绍会提到这些文件里面的内容。
IPNC_RDK里面的软件包Source文件夹内容,这里还是以截图的方式去了解DM8127的软件架构更合适。
上图是RDK软件包最核心的东西,ipnc_rdk和ti_tools。
其中ipnc_rdk主要有4个文件夹,以及最重要的总Makefile和总的Rules.make,那些build_xx_xx.sh脚本是本人自己加的。
而ti_tools目录下有很多TI 的工具包,见下图:
一、ti_tools介绍
我们先介绍ti_tools,这里面是TI 提供的很多编译工具包和LIB文件,
1、 其中:ipnc_psp_arago存放了我们需要移植的u-boot(u-boot-2010.06)和kernel(linux-2.6.37)源码。u-boot的编译和移植,kernel的编译和移植后面的文章再介绍。这个文件夹下面还有个docs的文件夹,里面有很多和驱动移植有关文档。
2、iss_03_80_00_00:也是需要移植的软件包,所有调试CMOS SENSOR驱动(比如添加一款新的SONY IMX、OV、ON等CMOS SENSOR)都需要在这个软件包里面去调试,包括LVDS接口采集RAW DATA,并行口驱动采集RAW DATA,BT656接口采集YUV422 DATA,BT1120接口采集YC DATA啊等等,还有CMOS 2A(自动白平衡,自动曝光)算法,降噪处理,都在这个iss_03_80_00_00目录下去移植调试,重点去看iss_03_80_00_00/packages/ti/psp/目录下的源码,这个和以前的DM6446啊,DM3730啊在内核添加的V4L2这些驱动做法完全不一样了。DM8127跟DM8147-8148-8168的差别就在这个iss模块,DM8127带有ISP功能,可以接RAW DATA格式的CMOS。
3、Linux_devkit是DM8127平台的ARM交叉编译工具,APPRO集成在这个ti_tools里面来了。
4、其他ti_tools软件包都是现成的LIB 或者DSP编译工具,两个ARM CORTEX-M3核的编译工具也在这里,这些工具不需要我们去移植开发,大家可以进到对应的文件夹里面去了解。
二、ipnc_rdk介绍
上图里面的都是最上层的linux app应用程序,其中ty_app是本人自己添加的,里面有自己写的gpio应用程序,rs232测试程序,rs485测试程序,等等,其他的APP介绍可以看看IPNC_RDK_Application_DesignGuide.pdf,里面有详细的描述。DM8127 RDK运行DEMO程序的时候,一般是先从sys_server源码开始运行的,我们不妨从NFS 文件系统即ipnc_rdk/target/filesys/etc/init.d/finish_ubifs.sh的脚本了解:
cd /opt/ipnc
./init.sh
./system_server
sleep 7
./autorun_ipnc.sh
执行system_server就是执行sys_server编译的应用程序。
其他的web服务器程序,network程序(包括大家非常熟悉的boa和live555)这种常用的应用程序就不要介绍了,一看就明白这些功能,运行system_server的时候也可以同时运行这些应用程序,就在autorun_ipnc.sh里面执行。
2、 target目录
这个目录下的filesys就是我们开发的时候使用的NFS文件系统,在上上一篇《图像识别DM8127——开发环境搭建》有介绍。
3、 tftp
这个文件我们没有用到,也可以当作一个临时保存BIN文件的文件夹。而我们的TFTP SERVER放在linux ubuntu主机/tftpboot目录下。
4、 最重点的ipnc_mcfw
Mcfw: Multi Channel Framework多通道帧同步工作机制,我们要配合IPNC_RDK_McFW_UserGuide.pdf一起分析这个mcfw,主要是掌握视频数据流是如何在VPSS CORTEX-M3, VIDEO CORTEX-M3, CORTEX-A8 还有C674X DSP四个核之间是如何同步工作的;
A、ipnc_mcfw/bin
ipnc_mcfw/bin/ti814x里面有编译mcfw模块出来的对应的一些可执行文件,LIB,驱动文件KO,另外scripts有对应的运行脚本,大家可以进去看看就明白了。这编译得到的可执行文件,LIB,驱动文件KO, scripts里面的运行脚本,还有init.sh脚本都会COPY到NFS文件系统target/filesys/opt/ipnc目录下,后面编译描述会提到。
B、ipnc_mcfw/build
这个文件夹存放了编译mcfw大部分的临时文件,.obj文件,还有一些LIB文件,驱动临时文件。4个核编译的临时文件都放在这个目录下,这样管理本人比较喜欢,不像UBOOT和KERNEL这些编译的临时文件都放在同样的文件下面,不好备份。
C、ipnc_mcfw/demos/
重点看mcfw_api_demos/ multich_usecase和stream文件夹下面的源码,这些都是IPNC DEMO的应用程序。
D、ipnc_mcfw/makerules/
四个核的编译规则级编译脚本,非常重要,本人花了一些时间去研究这4个核是如何编译的,还有在DSP端移植C++算法的时候,是如何支持.cpp源文件编译,都需要在这些脚本下面修改,怕修改错就先bk备份一下再修改,这些编译规则脚本有些参数看不懂,可以看看同一个目录下的docs文件夹的makerules_spec.doc。
整个DM8127 RDK 最有用的核心部分就是这个mcfw了。4个核配合工作的源码,其中M3 VPSS、M3 VIDEO和C674X DSP都是使用BIOS编译,所以他们的代码都放在src_bios6,而CORTEX-A8 放在src_linux里面。比如自己添加DSP算法可以放到links_c6xdsp/alg目录下,要在M3 VPSS做一些CMOS SENSOR前端采集的程序可以在links_m3vpss处理,要在H264压缩和解码之前做一些代码移植可以进到M3 VIDEO,即 links_m3video目录下去工作,比如我们在M3 VPSS核添加自己公司(ty)的任务:links_m3vpss/tyLink/tyLink_tsk.c和tyLink_priv.h,然后修改上一级目录的SRC_FILES.MK让tyLink_tsk.c被编译到。而links_common里面的源码是可以被DSP核,M3 VPSS核,M3 VIDEO核共用,这个需要注意。网上已经有一篇其他网友的文章如何在这个mcfw目录下去添加DSP 端运行算法的例子(http://blog.csdn.net/guo8113/article/details/20149191),那篇文章主要在DM8148/DM8168平台上实现的,其实和DM8127完全一样,可以直接借鉴。还有一种直接使用TI 现成的links_common/null/nullLink_tsk.c基础上去添加DSP接口,让nullLink_tsk.c被DSP 单独编译,而不是作为M3 的程序去编译,然后去src_linux/mcfw_api/usecases/xxxx.c去System_linkCreate()这个任务就可以了。
我们可以使用下面这个图更深入了解:
上图就是一个很经典的视频数据流的在4个核之间的通信,
A)、首先 从CMOS SENSOR采集到1080P的RAW DATA图像数据,在M3 VPSS这个核建立CAMERA LINK,去处理图像数据,先把RGB格式转换成YUV格式;
B)、然后ISS使用两个Resizer,即Resizer A和Resizer B,对YUV格式再进一步处理,Resizer-A把1080P的数据转换成YUV420SP(Y分量独立保存,UV交叉独立保存),统一保存到dup[0]这个缓存队列(其实就是一大块独立的内存空间);Resizer-B也在对初始的YUV格式进行Resizer缩小成720480这个标清图像,也是YUV420SP(Y分量独立保存,UV交叉独立保存),并且统一保存到dup[1]另外一个独立的缓存队列,和上面的dup[0]是分开的。也就是说,dup[0]的1080P 数据拿去M3 VIDEO 核去H264编码,dup[1]的720480数据拿去给DSP核 做视频分析。
C)、通过一种link机制,M3 VPSS 核输出数据给M3 VIDEO核,M3 VIDEO核拿到dup[0]的数据(其实就是一个指针队列,共享内存方式),再进行H264编码,与此同时也通过link机制,把dup[0]数据直接输出给HDMI接口。另外一条数据dup[1]通过link机制,把指针传给DSP TSK,比如我们使用nullLink_tsk.c这种接口去调用我们的算法,或者通过link机制把标清720*480输出到CVBS接口进行display,当然CVBS的格式是YUV422,这点需要注意。
D)、Dup[0]的数据经过H264 Enc编码后,以BIT流的方式,通过link机制,传给CORTEX-A8,那么A8运行的应用程序,比如live555就可以拿到这个bit流进行WEB播放。
有关上面提到的link机制,需要去看TI MCFW的用户手册,配合程序来分析。总之理解完上图的讲解,应该对DM8127 MCFW的架构有初步的了解,而不是满头雾水。本人能力一般,刚拿到APPRO 板子的时候,也不知如何去学习,即使看了很多遍那一大堆文档,还是没有掌握上图的精髓,然后就是去搞大客户的产品设计,这一块就暂停了。后来有时间,配合程序分析,经过高人蜻蜓点水讲解,才对这个MCFW的数据流有了很好的认识,特别是高薪招了一个做过DM385的项目经理,他对这个mcfw和相关link机制比较熟悉,帮本人解决了很多问题,我们相互配合,很快就把以前DM3730的视频分析算法移植过来了,而且跑得还比较稳定,算法运行效率当然比DM3730 定点DSP高多了,DM8127 浮点DSP就是好,很多浮点运算根本不要考虑优化,整个浮点DSP就专门跑视频分析算法,把分析出来的目标坐标和其他参数传出来给其他核就OK了,根本不用去做多余的任务。
三、总的Rules.make和Makefile介绍
ipnc_rdk/Rules.make和ipnc_rdk/Makefile是整个RDK软件包的最重要的编译脚本,必须要吃透。
1、我们先介绍Rules.make:
SYSTEM_PLATFORM := IPNC (APPRO IPNC_RDK是针对高清网络摄像机产品来设计的,而不是 DM8148那种TI 自己开发板的EVM开发包)
APP_BUILD_CFG := release (表示编译RDK的时候是编译的程序是产品release模式,可以去掉很多调试信息,如果使用debug则表示在编程编译调试运行的时候需要)
BINARY_MODE := nand (表示编译的uboot min是NAND FLASH模式,编译出来的uboot min和uboot是要烧写到NAND里面去的。如果是:=sd表示编译的uboot min是MLO文件,放到SD卡里面,用在工厂生产和NAND 无程序时候调试用)
IPNC_DEVICE := DM8127 (选择DM8127平台,这个RDK当然也支持DM385和DM388不带DSP的平台)
IPNC_CONFIG := FULL_FEATURE (我们使用DSP 而且是必须CORETEX-A8 跑1G频率,DSP 跑750MHz的模式)
MEMORY_CONFIG := 512MB (我们桐烨科技DM8127核心板使用512MB 字节的DDR3内存,256MB根本不够,因为我们带DSP)
MTD_UTILS_MODE := 32bit (这个针对ipnc_rdk / target/ mtd-utils的编译问题,如何你的linux开发主机是64bit的,则这里选择64bit,我们这里的虚拟机还是使用32bit,所以这里选择32bit,不要搞错)
IMGS_ID := IMGS_MICRON_AR0330 (这里打个比方,你如果使用便宜的AR0330 200万CMOS SENSOR,这里就定义这个宏定义,RDK里面的源码一些头文件需要加入这个宏定义,iss模块里面到时候会去编译iss_03_80_00_00/packages/ti/psp/devices/ ar0330相关驱动)
WDR_ON := YES (如果你的CMOS SENSOR支持宽动态,使能这个)
LOW_POWER_OPP100_MODE := NO (这个选择NO表示电源管理模式使用全速 ,非低功耗,和上面的FULL_FEATURE类似,如果选择YES,DM8127 CORTEX-A8 跑600M, DSP 跑500MHz)
AES_MODULE_MODE := OFF (表示编译的RDK包里面的各种程序模块是否需要采用AES加密方式发布)
BUILD_WARNINGS_AS_ERROR := NO(这里本公司选择NO,是因为编译RDK的时候,如果选择YES,有些定义的变量没有用到,编译器会把这种warning认为是错误,停止往下编译,很烦人)
CAPTURE_DISPLAY_MODE_ON := YES
RAMES_TO_A8 := NO
(这里就是用户要使用什么模式去用这个IPNC RDK的程序,这里的选择对应src_linux/mcfw_api/usecases/multich_capturedisplay.c这个例子,支持这个IPNC设备实现采集CMOS SENSOR 1080P和1080P HDMI显示输出的例子)
其他全局编译宏定义可以直接使用RDK默认的,另外需要注意的是那些路径宏定义,很重要比如:
BASE_INSTALL_DIR := $(shell pwd)/..
#Defining the install base directory for IPNC RDK
IPNC_INSTALL_DIR := $(BASE_INSTALL_DIR)/ipnc_rdk
TOOLS_INSTALL_DIR := $(BASE_INSTALL_DIR)/ti_tools
#The directory that points to the Linux Support Package
lsp_PATH := $(TOOLS_INSTALL_DIR)/ipnc_psp_arago
KERNELDIR := $(lsp_PATH)/kernel
UBOOTDIR := $(lsp_PATH)/u-boot
#The directory that points to where filesystem is mounted
FILESYS_INSTALL_DIR := $(IPNC_INSTALL_DIR)/target
TARGET_FS := $(FILESYS_INSTALL_DIR)/filesys //NFS 文件系统路径
TARGET_APP := $(FILESYS_INSTALL_DIR)/ipnc
TARGET_FS_DIR := $(TARGET_FS)
MTD_UTILS := $(FILESYS_INSTALL_DIR)/mtd-utils/$(MTD_UTILS_MODE)
#The directory that points IPNC RDK source code
MCFW_ROOT_PATH := $(IPNC_INSTALL_DIR)/ipnc_mcfw
IPNC_DIR := $(IPNC_INSTALL_DIR)/ipnc_app
#The directory to root file system
ROOT_FILE_SYS:= $(TARGET_FS)
#target filesystem.
EXEC_DIR:=$(TARGET_FS)/opt/ipnc //NFS 文件系统对应可执行文件保存路径
Rules.make后面的那些定义看看就明白了,比较好理解,定义一些全局变量的路径,和宏定义。
2、介绍总的Makefile
总的Makefile一开头就先include 上面介绍的总的Rules.make和ipnc_mcfw/makerules/下的脚本。
然后下面有很多编译模块(目标),4个核的程序编译都在这个总Makefile, 去定义编译。每个模块编译都是:
Xxxx:
Xxxx_clean:
Xxxx_all:
模式
如果对一些脚本定义不是很了解,可以在Makefile里面插入:
比如:echo "Hardware Platform : $(IPNC_DEVICE) $(SYSTEM_PLATFORM)"
这种方式去打印编译信息,注意echo前需要tab键。
总的Makefile 编译需要结合IPNC_RDK_InstallGuide.pdf 这个文件来看。
其实一个总的:make sysall,就可以编译完所要开发的各个模块,但是开发的时候不可能都去make sysall,这样太浪费时间了,根本不用去开发软件了。我们只好把make sysall涉及到的模块全部分开来编译,这样需要开发到哪个模块再去编译。make sysall 后面会把编译得到的应用程序啊,BIN文件啊,LIB等等COPY到NFS 文件系统对应的文件夹,见:
fsupdate:
cp -R $(TARGET_MCFW_DIR)/ $(EXEC_DIR)/.
chmod 755 $(EXEC_DIR)/.sh
这里需要提到一个APPRO自己做的一个脚本,在编译ipnc_app(即make app)的时候,会去执行inpc_app/ root_filesys/Makefile,我们第一可以让他执行这个Makefile,见下图,它会COPY对应的文件到我们NFS文件系统对应的文件夹。但是当我们调试NFS一些脚本的时候,做了修改,比如target/ filesys/etc/ init.d/ finish_ubifs.sh ,target/ filesys/opt/ipnc/init.sh等脚本修改,如果再执行make sysall,如果不备份,又把我们修改好的NFS 文件系统的脚本内容覆盖,很讨厌,这点要注意。我们是做了一次这个inpc_app/ root_filesys/Makefile,以后,直接把这个inpc_app/ root_filesys/Makefile里面的内容屏蔽,后面就不需要多次重复覆盖了,下图就是inpc_app/ root_filesys/Makefile,执行完一次就可以屏蔽里边的install操作。
四、SDK编译过程
上图是本人根据总的Makefile,自己单独做的编译脚本,把各个模块分离出来,这样便于各个模块开发编译,编译build加上1-2-3-4-5-6-7等数字,让大家一目了然,知道整个RDK软件要如何编译开发。在上一篇《图像识别DM8127开发攻略 ——板子启动过程》已经描述过DM8127的硬件启动流程,这里编译的流程也和那篇文章对应。所有的这些build的脚本,都必须在上图对应路径下编译,也就是:
/home/davinci/dm8127/v3.8.0/Source/ipnc_rdk/
包括自己手动使用make xxxxx,都是在这个路径下去执行编译。
build_1_uboot-min-nand.sh 脚本内容:make ubootmin
就是编译ubootmin,顾名思义,专门用来烧写到NAND FLASH上的BIN文件。
对应总的Makefile内容是:
ubootmin:
$(MAKE) ubootclean
$(MAKE) ubootbuild MAKE_TARGET=$(PLATFORMCFG)$(SYSTEM_CFG)min$(BINARY_MODE)
$(MAKE) ubootbuild MAKE_TARGET=u-boot.ti
ifeq ($(BINARY_MODE),sd)
cp $(UBOOTDIR)/u-boot.min.$(BINARY_MODE) $(TFTP_HOME)/MLO
cp $(UBOOTDIR)/u-boot.min.$(BINARY_MODE) $(UBOOTDIR)/MLO
else
cp -f $(UBOOTDIR)/u-boot.min.$(BINARY_MODE) $(TFTP_HOME)/u-boot.min.$(BINARY_MODE)
cp -f $(UBOOTDIR)/u-boot.min.$(BINARY_MODE) $(UBOOTDIR)/u-boot.min.$(BINARY_MODE).bk
cp -f $(UBOOTDIR)/u-boot.min.$(BINARY_MODE) /tftpboot/dm8127_min.bin
endif
build_1_uboot-min-sd.sh 脚本内容:make uboot_ty_sd
同时编译ubootmin和uboot,只不过是编译得到MLO和u-boot.bin文件,COPY 到SD卡里,使用SD卡BOOT板子。
对应总的Makefile内容是(自己添加修改的):
uboot_ty_sd:
$(MAKE) ubootclean
$(MAKE) ubootbuild MAKE_TARGET=$(PLATFORMCFG)$(SYSTEM_CFG)_min_sd
$(MAKE) ubootbuild MAKE_TARGET=u-boot.ti
cp -f $(UBOOTDIR)/u-boot.min.sd $(IPNC_INSTALL_DIR)/tftp/$(IPNC_DEVICE)/sd/MLO
cp -f $(UBOOTDIR)/u-boot.min.sd $(UBOOTDIR)/MLO
$(MAKE) ubootclean
$(MAKE) ubootbuild MAKE_TARGET=$(PLATFORMCFG)$(SYSTEM_CFG)_config_nand
$(MAKE) ubootbuild MAKE_TARGET=u-boot.ti
cp -f $(UBOOTDIR)/u-boot.bin $(IPNC_INSTALL_DIR)/tftp/$(IPNC_DEVICE)/sd/
build_2_uboot-all.sh 脚本内容:make ubootbin
编译uboot,得到dm8127_uboot.bin用于烧写到NAND FLASH。
ubootbin:
$(MAKE) ubootclean
$(MAKE) ubootbuild MAKE_TARGET=$(PLATFORMCFG)$(SYSTEM_CFG)config$(BINARY_MODE)
$(MAKE) ubootbuild MAKE_TARGET=u-boot.ti
cp -f $(UBOOTDIR)/u-boot.bin $(TFTP_HOME)/u-boot.bin
cp -f $(UBOOTDIR)/u-boot.bin $(UBOOTDIR)/dm8127_uboot.bin.bk
cp -f $(UBOOTDIR)/u-boot.bin /tftpboot/dm8127_uboot.bin
build_2_uboot-tmp.sh 脚本内容:make uboot_ty
也是编译uboot,得到dm8127_uboot.bin用于烧写到NAND FLASH。只不过用在移植开发UBOOT的时候,只修改某个.c或.h文件,这时编译的时候,就没必要再使用ubootclean把所有的OBJ清空再全部编译一次,太耗时间。
对应总的Makefile内容是:
uboot_ty:
$(MAKE) ubootbuild MAKE_TARGET=$(PLATFORMCFG)$(SYSTEM_CFG)config$(BINARY_MODE)
$(MAKE) ubootbuild MAKE_TARGET=u-boot.ti
cp -f $(UBOOTDIR)/u-boot.bin $(TFTP_HOME)/u-boot.bin
cp -f $(UBOOTDIR)/u-boot.bin $(UBOOTDIR)/dm8127_uboot.bin.bk
cp -f $(UBOOTDIR)/u-boot.bin /tftpboot/dm8127_uboot.bin
build_3_kernel-menuconfig.sh 脚本内容:make lspmenu
对应总的Makefile内容是:
lspbuild:
make -C$(KERNELDIR) ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX) $(MAKE_TARGET)
lspmenu:
make lspbuild MAKE_TARGET=menuconfig
这个熟悉的配置内核选项的界面就不多说了。选择某些功能和模块后,save 配置文件,会在kernel这个文件夹下面得到.config文件,本人喜欢备份:
cp -f $(KERNELDIR)/.config $(KERNELDIR)/dm8127_2017xxxxaaa.config
然后再把这个备份文件覆盖$(KERNELDIR)/arch/arm/configs/ti8148_ipnc_ubifs_defconfig这个文件:
cp -f $(KERNELDIR)/dm8127_2017xxxx.config $(KERNELDIR)/arch/arm/configs/ti8148_ipnc_ubifs_defconfig
后面的内核编译都是使用这个ti8148_ipnc_ubifs_defconfig配置文件。
build_3_kernel-all.sh 脚本内容:make lsp_ty
对应总的Makefile内容是:
cmem:
make -C$(linuxutils_PATH)/packages/ti/sdo/linuxutils/cmem/src/interface \
LINUXKERNEL_INSTALL_DIR=$(KERNELDIR) MVTOOL_PREFIX=$(BUILD_TOOL_PREFIX)
make -C$(linuxutils_PATH)/packages/ti/sdo/linuxutils/cmem/src/module \
LINUXKERNEL_INSTALL_DIR=$(KERNELDIR) MVTOOL_PREFIX=$(BUILD_TOOL_PREFIX)
cmemclean:
make -C$(linuxutils_PATH)/packages/ti/sdo/linuxutils/cmem/src/module clean
make -C$(linuxutils_PATH)/packages/ti/sdo/linuxutils/cmem/src/interface clean
lspcfg:
make lspbuild MAKE_TARGET=$(PLATFORMCFG)$(SYSTEMCFG)$(FS_CFG)_defconfig
lsp:
cp $(linuxutils_PATH)/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.o $(KERNELDIR)/drivers/char/
make lspcfg
make lspbuild MAKE_TARGET=uImage
make lspbuild MAKE_TARGET=modules
cp $(KERNELDIR)/arch/arm/boot/uImage $(TFTP_HOME)/uImage
cp $(KERNELDIR)/arch/arm/boot/uImage $(KERNELDIR)/dm8127_kernel.bin.bk(本人自己添加)
cp -f $(KERNELDIR)/arch/arm/boot/uImage /tftpboot/dm8127_kernel.bin(本人自己添加)
-mkdir -p $(TARGET_MCFW_DIR)/kermod
cp $(KERNELDIR)/drivers/video/ti81xx/vpss/vpss.ko $(TARGET_MCFW_DIR)/kermod/.
cp $(KERNELDIR)/drivers/video/ti81xx/ti81xxfb/ti81xxfb.ko $(TARGET_MCFW_DIR)/kermod/.
cp $(KERNELDIR)/drivers/video/ti81xx/ti81xxhdmi/ti81xxhdmi.ko $(TARGET_MCFW_DIR)/kermod/.
cp $(KERNELDIR)/drivers/usb/gadget/g_file_storage.ko $(EXEC_DIR)
cp $(KERNELDIR)/block/sbull/sbull.ko $(EXEC_DIR)
lspclean:
make lspbuild MAKE_TARGET=distclean
lsp_ty:
#make binariesclean
make cmemclean
make lspclean
make lspcfg
make -C $(KERNELDIR) ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX) prepare
make -C $(KERNELDIR) ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX) modules_prepare
make cmem
make lsp
从上面的脚本可以看出,编译内核之前,必须编译cmem模块(ARM+DSP最重要的共享内存机制),这个和DM6446-DM3730一样,只不过那些是独立编译的,内核编译也是独立的,现在DM8127把这个cmem整合在一起编译。还有内核那些选项为(M)的驱动模块,也整合在一个脚本编译,然后把对应的.ko文件COPY到对应的路径。还有注意一下,编译kernel之前,必须先编译好UBOOT,因为使用UBOOT里面一个image工具,如果uboot被clean完临时文件,到这里编译内核最后步骤会通不过的。
build_3_kernel-tmp.sh 脚本内容:make lsp
对应总的Makefile内容是:见上面描述。也就是编译某个源文件,没编译又把整个内核clean再重新编译,太浪费自己的生命时间。
build_4_syslink.sh 脚本内容:make syslinkall
对应总的Makefile内容是:
syslinkbuild:
cp $(MCFW_ROOT_PATH)/makerules/syslink_products.mak $(syslink_PATH)/products.mak
make -C$(syslink_PATH) $(TARGET)
syslink:
make syslinkbuild DEVICE=$(syslink_DEVICE) TARGET=syslink
-mkdir -p $(TARGET_MCFW_DIR)/kermod
cp $(syslink_OUT_DIR)/syslink.ko $(TARGET_MCFW_DIR)/kermod/.
syslinkclean:
make syslinkbuild DEVICE=$(syslink_DEVICE) TARGET=clean
syslinkall: syslinkclean syslink
DM8127 4个核之间需要link机制协调工作,这个模块就是底层的源码,只不过TI 屏蔽这些底层的东西,我们只需要编译好就可以了,不需要去修改这样复杂模块的源码。
build_5_ipncapp-all.sh 脚本内容:make all
对应总的Makefile内容是:
ipncapp: app hdvpss iss mcfw fsupdate
clean: appclean hdvpssclean issclean mcfwclean
all: clean ipncapp
applibs:
ifneq ($(MAKE_TARGET), depend)
$(MAKE) -C$(IPNC_DIR) ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX) $(MAKE_TARGET)
endif
appclean:
$(MAKE) applibs MAKE_TARGET=clean
appdepend:
$(MAKE) applibs MAKE_TARGET=depend
appinstall:
$(MAKE) applibs MAKE_TARGET=install
app: appdepend applibs appinstall
hdvpss:
$(MAKE) -C $(hdvpss_PATH)/packages/ti/psp/vps $(TARGET) CORE=m3vpss
$(MAKE) -C $(hdvpss_PATH)/packages/ti/psp/i2c $(TARGET) CORE=m3vpss
$(MAKE) -C $(hdvpss_PATH)/packages/ti/psp/devices $(TARGET) CORE=m3vpss
$(MAKE) -C $(hdvpss_PATH)/packages/ti/psp/platforms $(TARGET) CORE=m3vpss
$(MAKE) -C $(hdvpss_PATH)/packages/ti/psp/proxyServer $(TARGET) CORE=m3vpss
hdvpssclean:
$(MAKE) hdvpss TARGET=clean
hdvpssall: hdvpssclean hdvpss
iss:
$(MAKE) -C $(iss_PATH)/packages/ti/psp/iss $(TARGET) CORE=m3vpss
issclean:
$(MAKE) iss TARGET=clean
issall: issclean iss
mcfw_linux:
make -fMAKEFILE.MK -C $(MCFW_ROOT_PATH)/mcfw/src_linux
make -fMAKEFILE.MK -C $(MCFW_ROOT_PATH)/demos
mcfw_linux_clean:
make -fMAKEFILE.MK -C $(MCFW_ROOT_PATH)/mcfw/src_linux clean
make -fMAKEFILE.MK -C $(MCFW_ROOT_PATH)/demos clean
mcfw_linux_all: mcfw_linux_clean mcfw_linux
mcfw_bios6:
$(MAKE) -fMAKEFILE.MK -C $(MCFW_ROOT_PATH)/mcfw/src_bios6 $(TARGET)
mcfw_bios6_clean:
$(MAKE) -fMAKEFILE.MK -C $(MCFW_ROOT_PATH)/mcfw/src_bios6 clean
mcfw_bios6_all: mcfw_bios6_clean mcfw_bios6
mcfw: mcfw_linux mcfw_bios6
mcfwclean: mcfw_linux_clean mcfw_bios6_clean
mcfwall: mcfwclean mcfw
fsupdate:
cp -R $(TARGET_MCFW_DIR)/ $(EXEC_DIR)/.
chmod 755 $(EXEC_DIR)/.sh
ifeq ($(APP_BUILD_CFG),release)
$(STRIP470) $(TARGET_FS)/opt/ipnc/firmware/ipnc_rdk_fw_m3video.xem3
$(STRIP470) $(TARGET_FS)/opt/ipnc/firmware/ipnc_rdk_fw_m3vpss.xem3
ifeq ($(PLATFORM),ti814x-evm)
$(STRIP6x) $(TARGET_FS)/opt/ipnc/firmware/ipnc_rdk_fw_c6xdsp.xe674
endif
chmod 755 $(TARGET_FS)/opt/ipnc/firmware/.
endif
编译RDK 的MCFW模块涉及到APPRO 设计的app,hdvpss、iss、mcfw_linux、mcfw_bios6和最后把编译得到的可执行文件APP、BIN、LIB等COPY到文件系统路径。注意上面的mcfw_bios6除了编译我们熟悉的DSP算法外,还编译M3 VPSS和M3 VIDEO。Iss模块就是编译CMOS 接口驱动了。算法工程师只修改算法的时候,可以直接单独使用mcfw_bios6_clean和mcfw_bios6,其他模块可以到后面整合再编译。
build_5_ipncapp-tmp.sh 脚本内容:make ipncapp
对应总的Makefile内容是:
见上面build_5_ipncapp-all.sh同样内容。也是修改某个模块某个源文件,只需要编译对应的模块,没必要全部clean再编译,这个好的电脑全部编译一次都需要耗时40分钟以上。
build_6_ty_app.sh 脚本内容:make ty_app_all
对应总的Makefile内容是:
ty_app_clean:
$(MAKE) -C $(IPNC_DIR)/ty_app/ ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX) clean
ty_app_build:
$(MAKE) -C $(IPNC_DIR)/ty_app/ ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX)
ty_app_install:
$(MAKE) -C $(IPNC_DIR)/ty_app/ ARCH=arm CROSS_COMPILE=$(BUILD_TOOL_PREFIX) install
ty_app_all: ty_app_clean ty_app_build ty_app_install
编译ipnc_rdk/ipnc_app里面的各个应用程序。
build_7_ubifs.sh 脚本内容: make ubifs_ty
对应总的Makefile内容是:
ubifs_ty:
rm -f $(TFTP_HOME)/dm8127_ubifs.bin
mkdir -p $(IPNC_INSTALL_DIR)/tmp
$(MTD_UTILS)/mkfs.ubifs -r $(FILESYS_INSTALL_DIR)/ filesys -F -o ./tmp/ubifs.img -m 2048 -e 126976 -c 2047
$(MTD_UTILS)/ubinize -o $(TFTP_HOME)/dm8127_ubifs.bin -m 2048 -p 128KiB -s 2048 -O 2048 $(IPNC_INSTALL_DIR)/ubinize.cfg
rm -rf $(IPNC_INSTALL_DIR)/tmp
cp -f $(TFTP_HOME)/dm8127_ubifs.bin /tftpboot/dm8127_ubifs.bin
把调试好的NFS 文件系统,使用脚本制作ubifs bin文件烧写到板子NAND FLASH上。当然除了ubifs文件系统外,本公司也支持squashfs文件系统的移植,即build_7_squashfs.sh。
参加10月29日到11月1日深圳会展中心第16届安博会回来后,这些天都在忙公司网站改版,公司旧的网站已经停止运行,新的网站重新上线,原来的域名(网址不变)。安博会几乎每个展台的视频相关产品都要加上“智能”两个字,不带“智能”两个字都不好展出,可见现在市场竞争如此激烈。但实际上视频分析得出的效果和精确度良莠不齐。很多展台号称在嵌入式平台使用深度学习算法,估计有些也是忽悠人,毕竟能跑复杂深度学习算法的嵌入式平台不多,无外呼就是英伟达(NVIDIA)的 Jetson TX1 和 Jetson TX2(单个核心板2800元左右,这两年不适合嵌入式大规模生产),还有就是ARM+FPGA,两个成本都比较贵。至于TI 的DSP,有些公司也拿TDAx或者DM505M来做深度学习,但是这种深度学习复杂度还不是很高。想想2015年深圳安防展有好几个展台都使用我们桐烨生产的DM3730板子,到现在2017年深度学习概念疯狂展现,传统的视频分析产品不多了,我们感觉压力很大。TI TDAx和DM505M都带有多个C66X 浮点DSP+多个EYE(Embedded Vision Engine),这个EYE类似以色列自动驾驶汽车技术公司Mobileye EyeQ ,已经被Intel收购。TI 除了用这些平台做自动驾驶外,也可以用来做深度学习的。个别公司还用AM5728(CORTEX-A15+双C66X DSP)做简单的深度学习算法,但从算法的角度讲,AM5728 绝对不如TDAx和DM505M。TI 是打算在下一代的TDAx平台硬件升级支持深度学习算法(2018年?)。我们公司的DM8127平台只能用在传统的机器视觉算法,深度学习算法的平台公司现在比较纠结,因为还没发觉有性价比很好的嵌入式平台,太贵的太复杂的我们也做不来。买了一套NVIDIA Jetson TX2玩了一下就不玩了,核心板全部得跟NVIDIA进口,太贵。嵌入式前端没有好的平台运行复杂深度学习算法不要紧,其实可以通过传统机器视觉来分析出运动的人,然后抓拍通过有线和无线网络传回服务器后台去做深度学习也是一种非常可行的办法,后台大数据服务器这些超级CPU+GPU足以处理复杂的深度学习算法,在一些场合还是可以用这种思路去配合做。