凡亿教育-可可
凡事用心,一起进步
打开APP
公司名片
凡亿专栏 | SoC固件升级中的文件写入异步性问题及应对方案
SoC固件升级中的文件写入异步性问题及应对方案

然而,在实际应用中,由于Linux系统文件写入的异步性,可能导致固件烧写不完全,从而影响设备的正常启动和运行。


本文将通过一个实际案例,揭示Linux系统下因文件写入异步性导致的固件烧写问题,并探讨相应的解决方案。


在某客户产线的批量生产过程中,采用SD卡进行固件烧写。


烧写完成后,蜂鸣器提示产线工人可以进行下一步操作,工人听到蜂鸣器鸣叫后立即断电重启设备并进入测试环节。


然而,在后续测试中发现部分产品在启动时出现异常。


进一步分析发现,客户采用解压方式烧写系统固件:

  • 解压命令执行完毕。

  • 运行一个二进制可执行程序。

  • 蜂鸣器鸣叫,提示烧写完成。


从逻辑上看,该流程似乎没有问题。然而,问题仍然高概率出现。经过深入排查,发现可执行程序内部还存在二次解压操作,并且使用 system() 调用了 Linux Shell 命令。


system() 产生一个新的子进程,使得蜂鸣器鸣叫与二次解压分别在不同进程中执行,两者没有严格的先后顺序。


按照蜂鸣器鸣叫即断电重启的操作逻辑,就可能导致解压尚未完成时设备被重启,最终引发文件烧写不完整,导致系统启动异常。


Linux系统采用页高速缓存(Page Cache)机制,对写入的内容进行缓存。用户的写入操作实际上会被延迟提交,称为“脏数据(Dirty Data)”。


脏页数据回写磁盘的情况包括:

  • 当空闲内存低于特定阈值时,内核必须将脏页写回磁盘以释放内存。

  • 当脏页在内存中驻留时间超过特定阈值时,内核执行回写操作,防止脏页无限期驻留。

  • 当用户进程调用 sync() 或 fsync() 系统调用时,内核按照指令强制回写数据。


如果解压脚本未包含 sync 指令,或程序未在解压或写入后调用 fsync(),系统会依赖上述默认回写机制。


如果在脏页尚未回写到存储设备时发生断电,则文件内容可能不完整,导致启动异常。


针对上述问题,可采取以下措施确保数据完整性:


在更新脚本中增加同步操作

在解压固件后立即执行 sync 命令,确保数据写入磁盘。


在应用程序代码中使用 fsync()

在执行文件写入操作后,显式调用 fsync(fd) 确保数据同步写入存储设备。


避免 system() 方式调用关键操作

system() 可能导致并发执行,建议使用 execv() 等更可控的方式执行命令,确保任务执行的顺序。


采用日志型文件系统(如ext4带journaling)

使用支持日志功能的文件系统,可降低异常断电导致的数据损坏风险。


优化断电策略

生产流程可改为在系统自检完成后再发出蜂鸣器提示,避免人为误操作。


通过以上优化,可有效减少因文件写入异步性带来的固件烧写问题,提高工业生产的可靠性。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论