嵌入式系统应用部署与现场更新策略
在嵌入式系统的生命周期中,软件更新是一个不可避免的需求。无论是修复漏洞、添加新功能还是优化性能,都需要对设备上的软件进行更新。本文将探讨嵌入式系统应用部署和现场更新的相关策略和方法。
工厂首次现场更新的重要性
对于在正常运行过程中需要进行现场更新的设备,在工厂进行首次现场更新配置是确保该过程按预期工作的最佳方式。这样可以使系统处于适合下一次更新的状态,并且在更新过程中出现的任何问题都可以在工厂解决,相比在现场修复问题,成本更低。此外,在客户现场出现问题可能会影响其业务运营,并给客户留下对产品和公司不利的印象。
现场更新的必要性
软件总是需要不断变化和更新的。嵌入式设备具备了更多的连接性、存储和处理能力,使得在设备上安装新软件变得比以往更加可行。然而,公司在发货时所提供的软件可能无法完全满足客户的需求,或者在实际使用中出现问题。因此,对设备进行现场更新是必要的。
设备更新的常见方式及问题
一种常见的设备更新方式是将设备返回客户服务部门,由技术人员打开设备,连接串口线,并按照说明在板上加载新的内核和根文件系统。这种方式风险最低,但成本最高,且不具有可扩展性。
现场更新的可行方案
现场更新并不一定复杂,可以使用一些简单的 shell 脚本创建合理的解决方案。如果需要更复杂的解决方案,也可以使用与更新 Linux 桌面软件包相同的工具,这些工具可以在资源有限的设备上使用,提供了几乎无限的灵活性。
根文件系统更新
根文件系统更新是现场更新的一个重要方面,因为许多现场更新需求可以通过更新根文件系统来满足,而内核在产品的整个生命周期中可能保持不变。嵌入式设备的根文件系统通常存储在闪存设备上,并且实际的文件系统是只读的,这意味着需要替换整个根文件系统。
根文件系统更新的基本策略
更新根文件系统有几种基本策略,每种策略都有其适用场景,且都需要良好的通信机制来获取新的二进制文件,以及足够的临时存储空间:
1.
叉车式升级(Forklift upgrade)
:完全用新的内容替换旧的根文件系统。在嵌入式系统中,用新的闪存映像替换整个根文件系统。这源于早期电信设备软件只能通过更换现有设备来升级的方式。
2.
并行系统(Parallel systems)
:使用两个内核和两个根文件系统。一个根文件系统和内核对作为生产系统,另一个作为升级的暂存系统。先升级暂存系统,当暂存系统准备好后,更改引导加载程序指向暂存系统并重启设备。这种方式适用于设备有足够资源存储第二个根文件系统和内核的情况。
3.
自定义更新(Build your own)
:将软件更改作为 tar 或 cpio 存档与脚本或其他软件一起分发,然后更新系统。对于目标设备上软件变化较小的嵌入式系统,这是一个非常实用的选择。
4.
包管理器(Package manager)
:桌面系统常用的 RPM 和 Debian 包管理器也可用于嵌入式系统,嵌入式系统还使用更轻量级的 IPKG 包管理器,它更注重简单性而非功能。
叉车式升级
叉车式升级意味着创建一个新的根文件系统映像并烧录到闪存存储中。对于只读文件系统,这是必要的,因为文件系统驱动程序无法写入数据。要进行叉车式升级,需要满足以下条件:
-
MTD 实用工具
:闪存设备在写入前需要先进行擦除操作,对于带有 NAND 内存的板卡,标准的
/dev/mtdblockX
设备驱动程序无法正确处理坏块,需要特殊工具。
$ git clone git://git.infradead.org/mtd-utils.git
$ make CC=arm-linux-gcc \
LDFLAGS="-static" \
WITHOUT_XATTR=1
- 额外的存储空间和通信链接 :需要有访问外部存储设备的方式,或者在板上有额外的存储空间来保存新的根文件系统映像。不建议直接从网络复制新的根文件系统映像并覆盖原始文件系统,因为这样容易出错且难以恢复。但在受控环境下,如由技术人员进行升级,这种方式在大多数情况下是可行的。
- 操作系统工具 :需要一些额外的工具来执行复制过程并确保其正常工作,这些工具通常可以在桌面系统中找到,需要确保它们存在于目标系统中。
叉车式升级的设计优化
为了使叉车式升级更简单,可以调整设备的软件配置。例如,将应用程序存储在与核心操作系统分离的闪存段中,这样可以独立于操作系统升级应用程序。这样做虽然前期需要更多工作,但可以使后续过程更简单、更安全,因为应用程序文件系统升级失败不会影响其他操作系统部分。
叉车式升级示例
以下是一个升级只读根文件系统的示例脚本,假设设备有足够的 RAM 来存储文件系统:
#!/bin/sh
# create the files you need
FLASH_DEVICE=/dev/mtd2
FILELIST=”image md5”
APP_NAME=”your_app”
APP_MOUNT_POINT=/app
FIFO=/tmp/upgrade
mkdir /tmp/newrfs
mount -f tmpfs -o size=xxK nodev /tmp/newrfs
# fetch from the target the necessary files
for f in $FILELIST; do
if ! ftpget -u username -p secret \
hostname /tmp/newrfs/$f /remote/path/$f ; then
echo "failed to download file $f"
exit 1
done
# check that the file is what you wanted
if ! md5sum -c md5 > /dev/null ; then
echo "md5 sum did not match"
exit 2
fi;
mkfifo $FIFO
killall $APP_NAME
umount $APP_MOUNT_POINT
mtderase $FLASH_DEVICE
if ! mtdcopy /tmp/newrfs $FLASH_DEVICE ; then
echo "problem copying new rfs"
## notice, that you did not write to the fifo
exit 3
fi
mount -t cramfs $FLASH_DEVICE /app
umount /tmp/newrfs
echo go > $FIFO
rm $FIFO
# The script that runs the application needs to wait on the end of the FIFO
if [ -f $FIFO ] ; then
read l < $FIFO
# the environment variable l will have "go" from the prior code
fi
这个脚本的关键是只更新系统的一小部分,同时保持核心操作系统的运行。由于应用程序代码与操作系统的其他部分分离,启动应用程序的代码可以进行额外的检查,以确保包含应用程序的闪存分区处于正常状态,并在首次尝试升级失败时进入诊断模式或尝试重新启动升级过程。
并行系统
并行系统的工作方式与叉车式升级类似,但更改发生在当前使用的根文件系统之外的另一个文件系统上。这种方式具有以下优点:
-
更安全
:无论升级过程多么糟糕,所有更改都在暂存系统上进行,而不是正在使用的系统。如果重启到新系统失败,还有一个可用的根文件系统和内核作为后备。
-
更好的诊断
:由于升级的是第二个分区,执行升级的软件可以轻松跟踪过程,因为它仍然有一个完整的、可工作的文件系统。
-
更少的干扰
:由于暂存根文件系统未被使用,更新过程可以逐步进行,而不会造成干扰。相比之下,叉车式升级在升级过程中需要停止系统运行。
然而,并行系统需要足够的空间来存储三个副本的更改:生产根文件系统、暂存根文件系统以及在复制到暂存根文件系统之前存储在生产文件系统中的更新。为了节省空间,生产根文件系统副本不需要包含更新的所有数据,因为对暂存根文件系统的更改可以分小块进行。
并行系统示例
以下是一个并行系统更新的示例,通过下载根文件系统并将其放入闪存分区,然后更改引导加载程序的环境变量,使系统下次启动时使用新的根文件系统。示例中使用的引导加载程序是 U-Boot:
$ cd <u-boot sources>
$ make at91sam9263ek_config
$ make env
最后一步构建了工具
./tools/env/fw_printenv
,可以使用该工具打印环境状态,并在文件名是
fw_setenv
时写入环境变量。可以使用以下命令创建指向该文件的符号链接:
# 此处原文档未给出具体命令,可根据实际情况补充
综上所述,嵌入式系统的现场更新是一个复杂但重要的过程。选择合适的更新策略需要考虑设备的资源、更新频率和软件复杂度等因素。通过合理的设计和使用适当的工具,可以确保更新过程的顺利进行,并提高系统的可靠性和可用性。
嵌入式系统应用部署与现场更新策略
自定义更新策略
自定义更新策略是将软件更改打包成 tar 或 cpio 存档,并附带脚本或其他软件来更新系统。这种策略适用于目标设备上软件变化较小的嵌入式系统。以下是使用自定义更新策略的操作步骤:
1.
准备更新包
:将需要更新的文件和脚本打包成 tar 或 cpio 存档。例如,使用
tar
命令:
tar -cvf update.tar file1 file2 script.sh
- 传输更新包 :通过合适的通信机制(如网络、USB 等)将更新包传输到目标设备。
- 执行更新脚本 :在目标设备上解压更新包,并执行附带的脚本进行更新操作。
tar -xvf update.tar
sh script.sh
包管理器更新策略
包管理器是一种常见的软件更新方式,桌面系统常用的 RPM 和 Debian 包管理器也可用于嵌入式系统。此外,嵌入式系统还使用更轻量级的 IPKG 包管理器,它更注重简单性而非功能。以下是使用 IPKG 包管理器进行更新的操作步骤:
1.
安装 IPKG
:在目标设备上安装 IPKG 包管理器。
2.
配置软件源
:设置 IPKG 可以访问的软件源,以便获取更新包。
echo "src/gz myrepo http://example.com/repo" > /etc/opkg.conf
- 更新软件包列表 :使用 IPKG 命令更新软件包列表。
opkg update
- 安装或更新软件包 :使用 IPKG 命令安装或更新所需的软件包。
opkg install package_name
现场更新的故障处理
无论采用哪种更新策略,都需要考虑故障处理。如果更新过程失败,设备需要知道如何恢复到可以再次尝试升级的状态,或者恢复到原始状态。以下是常见的故障处理方法:
| 故障处理方法 | 说明 |
| — | — |
| 回滚机制 | 当更新失败时,设备自动恢复到更新前的状态。例如,在并行系统中,如果重启到新系统失败,可以通过引导加载程序重新指向旧的根文件系统。 |
| 错误日志记录 | 在更新过程中记录详细的错误信息,以便技术支持人员进行故障排查。可以使用系统日志工具(如
syslog
)来记录错误信息。 |
| 重试机制 | 当更新失败时,设备可以尝试重新执行更新过程一定次数。例如,在叉车式升级中,如果文件下载失败,可以重试下载操作。 |
现场更新的流程图
graph TD
A[开始更新] --> B{选择更新策略}
B --> |叉车式升级| C[准备新的根文件系统映像]
B --> |并行系统| D[下载新的根文件系统到暂存分区]
B --> |自定义更新| E[准备更新包]
B --> |包管理器| F[更新软件包列表]
C --> G[传输新的根文件系统到设备]
D --> H[更改引导加载程序环境变量]
E --> I[传输更新包到设备]
F --> J[安装或更新软件包]
G --> K[擦除旧的根文件系统]
H --> L[重启设备]
I --> M[解压更新包并执行脚本]
K --> N[写入新的根文件系统]
N --> O{更新是否成功}
L --> O
M --> O
J --> O
O --> |是| P[更新完成]
O --> |否| Q[执行故障处理]
Q --> R{是否重试}
R --> |是| B
R --> |否| S[联系技术支持]
总结
嵌入式系统的现场更新是确保系统功能和性能的重要环节。本文介绍了几种常见的现场更新策略,包括叉车式升级、并行系统、自定义更新和包管理器更新,并详细说明了每种策略的操作步骤和适用场景。同时,还强调了故障处理的重要性,并提供了常见的故障处理方法。在实际应用中,需要根据设备的资源、更新频率和软件复杂度等因素选择合适的更新策略,并合理设计故障处理机制,以确保更新过程的顺利进行,提高系统的可靠性和可用性。
未来展望
随着嵌入式系统的不断发展,现场更新技术也将不断进步。未来,可能会出现更高效、更安全的更新策略和工具,例如基于区块链技术的更新验证机制,以确保更新的完整性和安全性。同时,随着物联网的普及,嵌入式设备的数量将不断增加,现场更新的管理和协调也将成为一个重要的挑战。因此,需要进一步研究和开发更智能、更自动化的现场更新管理系统,以满足未来嵌入式系统的更新需求。
超级会员免费看
2952

被折叠的 条评论
为什么被折叠?



