Linux OTA升级,yocto上平台不提供,是需要客户自己集成的,目前yocto上有swupdate、Mender.io、RAUC,swupdate是免费的使用的相对多一些。不过要是有钱的话最好还是用mender.io,mender根据数量不同收费价格不一样。现在介绍一下swupdate的使用。
1.根据当前基线版本,下载相应的swupdate软件。比如我目前用的是morty的基线,下载方法:
git clone https://github.com/sbabic/meta-swupdate.git -b morty
2.将swupdate meta数据添加到layer层
echo "BBLAYERS += \" \${BSPDIR}/sources/meta-swupdate \"" >> $BUILD_DIR/conf/bblayers.conf
3.编译
bitbake swupdate
由于ota升级会涉及到修改uboot环境变量,所以还需要添加 u-boot-fw-utils软件
bitbake u-boot-fw-utils
根据swupdate官网的说明,uboot需要至少2016.05以上的版本,因为我之前用的分支krogoth对应的uboot版本是2016.03,所以后来我就升级了基线,将uboot版本升级到2017.03版本,否则的话编译swupdate时会报错。
cxt@ubuntu:~/code/nxp/imx6ull_morty/imx6ullevk_build/tmp/work/cortexa7hf-neon-poky-linux-gnueabi/swupdate/2017.01-r0/git$ ls
archival corelib handlers Kconfig Makefile.flags parser scripts swupdate_unstripped tags
COPYING doc include Makefile Makefile.help progress_client suricatta swupdate_unstripped.map www
core examples ipc Makefile.deps mongoose README.md swupdate swupdate_unstripped.out
成功编译之后 会生成swupdate的bin文件,对编译结果打包放进rootfs文件系统。
IMAGE_INSTALL_append += "cmake python3 python3-pip swupdate swupdate-www u-boot-fw-utils”
配置完成开机会默认启动swupdate,启动信息:
Starting swupdate ...
Swupdate v2017.1.0Licensed under GPLv2. See source distribution for detailed copyright notices.
Searching for custom LUA handlers :[string "require ("swupdate_handlers")"]:1: module 'swupdate_handlers' not found:
no field package.preload['swupdate_handlers']
no file '/usr/share/lua/5.3/swupdate_handlers.lua'
no file '/usr/share/lua/5.3/swupdate_handlers/init.lua'
no file '/usr/lib/lua/5.3/swupdate_handlers.lua'
no file '/usr/lib/lua/5.3/swupdate_handlers/init.lua'
no file './swupdate_handlers.lua'
no file './swupdate_handlers/init.lua'
no file '/usr/lib/lua/5.3/swupdate_handlers.so'
no file '/usr/lib/lua/5.3/loadall.so'
no file './swupdate_handlers.so'
Custom handlers not found, no error, skipping...Registered handlers:
flash
raw
rawfile
lua
shellscript
preinstall
postinstall
uboot
Main loop Daemon
Mongoose web server v. 3.8 with pid 350 started on port(s) 8080 with web root [/www]
先确认设备的ip地址,比如我的192.168.0.108,然后可以在网页输入:http://192.168.0.103:8080/
弹出如上界面表示服务端已经启动,可以点击需要更新的固件了。
4. 升级固件制作
ota升级固件需要符合固定的格式,否则升级会失败。固件制作需要包含一个描述文件还有需要升级的固件
固件定制脚本swu_create.sh
IMG_FILES="sw-description rootfs.ext4.gz"
for f in ${IMG_FILES} ; do
echo ${f}
done | cpio -ovL -H crc > buildroot.swu
~
描述说明文件sw-description
software =
{
version = "1.0.1";
imx6ull14x14evk: {
hardware-compatibility: [ "1.0" ];
images: (
{
filename = "rootfs.ext4.gz";
device = "/dev/mmcblk1p3";
compressed = true;
type = "raw";
}
);
uboot: (
{
name = "testbootargs";
value = "12345";
},
{
name = "bootargs";
value = "console=ttymxc0,115200 root=/dev/mmcblk1p3 rootwait rw";
}
);
};
}
这个具体的参数说明可以参考swupdate官网 https://sbabic.github.io/swupdate/swupdate-ipc.html
我的文件系统初始挂载在mmcblk1p2分区,现在需要将rootfs烧录到p3分区并从p3分区启动,uboot的环境的变量就需要做修改。
升级如果提示这个错误,可以看看uart输出信息,比如uart显示
Version 1.0.1
[NOTIFY] : SWUPDATE failed [0] ERROR parser/parser.c : parse_hw_compatibility : 163 : HW compatibility not found
[NOTIFY] : SWUPDATE failed [0] ERROR parser/parser.c : parser : 509 : Found nothing to install
[NOTIFY] : SWUPDATE failed [0] ERROR parser/parser.c : parse_json : 598 : JSON File corrupted
说明我的设备端的compatibility参数没有设置,
设备端执行:echo "imx6ull14x14evk 1.0" > /etc/hwrevision
然后在升级就成功了。
还有一点需要注意,烧录的升级固件rootfs.ext4.gz,必须是ext4 的gz后缀压缩文件,否则升级也会失败。
5.suricatta 服务器多设备升级
这种升级方式只是验证单个设备,针对多个设备升级,swupdate支持suricatta模式,这个需要在defconfig文件打开一下开关
recipes-support/swupdate/swupdate/defconfig
--- a/recipes-support/swupdate/swupdate/defconfig
+++ b/recipes-support/swupdate/swupdate/defconfig
@@ -38,6 +38,13 @@ CONFIG_EXTRA_LDLIBS=""
# CONFIG_DOWNLOAD is not set
CONFIG_WEBSERVER=y
+
+CONFIG_HAVE_LIBCURL=y
+CONFIG_CURL=y
+CONFIG_JSON=y
+CONFIG_SURICATTA=y
+CONFIG_SURICATTA_HAWKBIT=y
+
#
# Webserver Features
#
(END)
板端配置完成了,还有服务器后台需要配置。
pc 主机端安装docke 模拟器的方式:
参考:https://juejin.im/post/5e1d4778e51d451c7a435bfb
sudo docker run -p 8080:8080 hawkbit/hawkbit-update-server:latest \
--hawkbit.dmf.rabbitmq.enabled=false \
--hawkbit.server.ddi.security.authentication.anonymous.enabled=true
服务器配置完成之后,确认服务器的ip地址,比如我的192.168.0.104,然后在设备端执行
swupdate -l 5 -u '-t default -u http://192.168.0.104:8080 -i 27'
然后就可以在服务器的网页界面看到我的设备了,我的服务端只能检测到有设备连接,但是如何对设备进行固件升级一直没有成功,这个涉及到服务器后台配置,实在是不擅长,就没有继续研究了。
swupdate的服务器用的是开源hawkbit服务器,有关资料可以参考:https://www.eclipse.org/hawkbit/
swupdate的整体流程大概是这样的。