本章会介绍如何客制化自己的产品底板和对应的DEY系统定制。
现代的嵌入式处理器通常非常强大,单颗处理器能提供多个各种不同的接口,但同时处理器的引脚又十分有限,也就是处理器核能提供的接口数量能力大于引脚数量。如果某个引脚只能固定配置成某种功能,势必造成资源的浪费。因此通常在处理器中引入IOMUX机制来解决引脚复用功能。 通过IOMUX处理器的引脚可以根据需求配置成不同功能的接口。Digi除了单板机开发套件提供的模板外,还可以利用smart IOMUX工具来加快定制自己的底板功能。当Digi的单板机底板满足不了您的需求,您通过IOMUX配置改变了接口的位置和数量定义时,您就需要进一步根据自己底板的布局和需求深度定制DEY系统。
CC6UL是带片上系统的核心模块,通常您可以根据CC6UL模块所支持的接口和功能设计产品的自定义底板。许多用户会设计不同的底板来满足不同市场或应用的需求。举例来说,您可能在一开始设计一个version 1.0版本的底板,只带有串口和以太网接口。接着您又按客户提出的需求重新设计了一个version 2的版本,添加了一些按钮和LED,并引入一个新的电源管理芯片。您可能还希望用同样的version 2版本的底板来满足高低端市场的要求,一个高配版的用底板ID=1表示,所有元件都贴上。另一个简配版的用ID=2表示,它用同样的底板,但只贴一部分的接口和元件。您还有可能进一步改进板子,修正一些bug并提高稳定性,这就变成version 3的底板,同样有高配和低配(ID=2和ID=2)两种板子。
一些底板上硬件的修改并不影响软件的使用,但另外一些板子硬件上的修改可能需要软件上有相应的变化。因此,如果能将板子的版本信息和用途ID存储在模块的OTP上将会极大方便软件的自动适配。您可以在Uboot或是Linux中添加条件语句代码,让相同的软件可以跑在不同的版本的底板上。
Digi的开发板/单板机在出厂时预置好了版本号和ID号,两种CC6UL单板机的Board ID如下:
Board ID | 单板机型号 | 无线 | 蓝牙 |
---|---|---|---|
129 | CC-WMX6UL-START | 有 | 有 |
135 | CC-WMX6UL-SBC | 有 | 有 |
在启动过程中UBoot会显示出版本和ID。
Board: ConnectCore 6UL SBC, version 3, ID 135
而对于核心模块出厂没预置底板版本号和ID,上电时就有提示这些信息未定义。
Board: ConnectCore 6UL SBC WARNING: Undefined board version! WARNING: Undefined board ID!
UBoot在上电启动时,会自动从OTP上读取这类信息生成board_id和board_version两个变量。Digi预编译的DEY和Android启动脚本使用board_id来确认是什么样的底板并选择合适的设备树文件。下面是个启动脚本实例:
if test -n "${board_id}"; then setenv fdt_file zImage-imx6ul-ccimx6ulsbc-id${board_id}.dtb else # # Set device tree filename depending on the hardware variant # if test "${module_variant}" = "0x02" || test "${module_variant}" = "0x04"; then setenv fdt_file zImage-imx6ul-ccimx6ulsbc-wb.dtb elif test "${module_variant}" = "0x03"; then setenv fdt_file zImage-imx6ul-ccimx6ulsbc.dtb else echo "------ Using default fdt_file: $fdt_file" fi fi
该脚本实现的功能是:
如果board_id存在,选择包含该id的设备树文件,如果不存在,选择匹配OTP里定义的该模块类型的设备树,并定模块运行在标准的开发套件底板上。如果模块类型也没定义,选择UBoot环境变量fdt_file定义的默认设备树文件。
烧写底板版本和ID号并不是必须的,另外这是一次性烧写,所以是不可逆的。您可以用board_version和board_id这两个uboot命令来烧写底板版本号和ID号。
相关的详细用法,包括如何利用底板版本号和ID号进行可选的软件行为,请参考官方文档
通常,如果您原样照抄Digi的开发套件或称单板机的开发底板,只做些适量的裁减,并没有硬件的大改动或调整,您是无需订制bsp来匹配自己的底板。DEY的编译选项中,支持的平台包括ccimx6plussbc,ccimx6sbc,ccimx6ulsbc,ccimx6ulstarter这几个开发板。如果您的底板功能和I/O变化不大,您也可以直接在现有的这几个平台做些修改,但更一般的做法是,当你根据开发底板做一些裁减和功能变换,添加或修改了默认的一些接口和功能时,这也意味着您需要添加一个新的机器平台到DEY中。这个过程包括:
通常地,您可以直接使用Digi核心板自带的u-boot。我们建议您采用和Digi的开发板一样的控制芯片(比如以太网和USB的PHY等),避免对u-boot进行开发。使用Digi原生自带的UBoot,您仍可以通过uboot的脚本来实现对板子进行一些定制行为。如果您确实需要进行一些代码级的定制开发,请参考下面内容。
Linux内核对特定硬件的支持是通过设备树文件实现的。设备树文件是描述硬件平台的文本文件,它是Linux内核源码树的一部分,但被单独编译成二进制文件。u-boot在启动过程会加载设备树到内存,并传递给内核。内核根据设备树中的硬件描述加载对应的设备驱动从而实现对特定硬件的支持。 CC6UL的设备树文件详细位置和参考: https://www.digi.com/resources/documentation/digidocs/90002285/reference/bsp/r_device_tree_files.htm
你可以复制现有的设备树文件来加以修改定制,也可以从头创建一个设备树文件。
在arch/arm/boot/dts/下创建一个新的设备树源码文件,比如命名为imx6ul-custom.dts,确保它包含以下内容:i.mx6ul的设备树头文件和和CC6UL模块类型的设备树头文件,用model定义平台名称,compatible参数设置为“digi,ccimx6ul”, “fsl,imx6ul”。例如:
imx6ul-custom.dts /dts-v1/; /* i.MX6UL CPU */ #include "imx6ul.dtsi" /* ConnectCore 6UL module */ #include "imx6ul-ccimx6ul-wb.dtsi" / { model = "My Company's ConnectCore 6UL based platform"; compatible = " mycc6ulboard, digi,ccimx6ul", "fsl,imx6ul"; digi,machine,name = " custom"; };
在设备树头文件中,大部分的接口是设置成关闭的(disabled), 对于每个您相用的接口,您需要:
如果您的底板是参考Digi单板机,您可以从相应的设备树复制接口和IOMUX配置。
你的底板可能包含额外的硬件组件,如果Linux内核中已有相关驱动,检查内核文档中的设备树绑定情况(Documentation/devicetree/bindings/)。
如果您希望编译您新创建的平台设备树文件,请在设备树的Makefile中添加imx6ul-custom设备树:
arch/arm/boot/dts/Makefile imx6ul-9x9-evk-ldo.dtb \ imx6ul-ccimx6ulsbc.dtb \ imx6ul-ccimx6ulsbc-id135.dtb \ imx6ul-ccimx6ulsbc-wb.dtb \ + imx6ul-custom.dtb \ imx6ul-ccimx6ulstarter.dtb \ imx6ul-ccimx6ulstarter-id129.dtb \ imx6ul-ccimx6ulstarter-wb.dtb \
最后一步是在DEY中创建自定义层,定义新机器平台,并指向刚刚创建的u-boot的内核分支。您可以参考meta-custom这个例子。
要使用它,拷贝到DEY安装目录下,在新建项目时用:
source /usr/local/dey-2.2/mkproject.sh -m meta-custom -p custom
注意,您必须拷贝Linux内核默认配置文件到meta-custom层,因为Yocto并不使用包含在内核树中的那个配置文件,关于Linux默认内核配置,请参考: Kernel development workflows。设备树文件也没在这一层中,DEY使用内核源码树中的设备树来编译。
上面假定您用patch的方式本地修改meta-custom,在下面这个中,修改的u-boot和内核分支在github上:
U-Boot recipes实例
recipes-bsp/u-boot/u-boot-dey_2015.04.bbappend FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}-${PV}:" UBOOT_GIT_URI = "git://github.com/<username>/u-boot.git;protocol=http" SRCBRANCH_custom = "2.2-r3/custom" COMPATIBLE_MACHINE = "(custom)"
Linux Recipes实例
recipes-kernel/linux/linux-dey_4.9.bbappend FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}-${PV}:" LINUX_GIT_URI = "git://github.com/<username>/linux-dey.git;protocol=http" SRCBRANCH = "2.2-r3/custom" COMPATIBLE_MACHINE = "(custom)"