• 正文
  • 相关推荐
申请入驻 产业图谱

ZLG嵌入式笔记(连载29) | Linux固件烧写中的陷阱:文件系统异步写入引发的问题

03/09 09:55
843
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在工业生产中,固件烧写是确保产品正常运行的关键环节。本文通过一个实际案例,揭示了Linux系统下因文件写入异步性导致的固件烧写不完全问题。

客户案例

客户产线上批量生产时,用SD卡进行固件烧写,烧写完成后蜂鸣器提示,产线工人听到蜂鸣器鸣叫后就直接断电重启,进入测试环节,结果在测试中发现有部分产品启动就出现异常。客户用解压方式烧写系统固件,解压命令执行完后,再运行一个二进制可执行程序,然后鸣叫蜂鸣器。乍一看逻辑非常正确,没有任何问题。

可问题却较高概率出现,问题出在哪里呢?

后来经过反复排查,发现客户解压脚本里的可执行程序里面还有二次解压操作,而且用system()调用了Linux的Shell命令。

System()调用Shell命令会生成一个新的子进程,这样蜂鸣器鸣叫和二次解压分别在不同进程中,两者没有同步,解压完成和蜂鸣器鸣叫没有必然的先后顺序。按照蜂鸣器鸣叫就断电重启,这样就不可避免的出现了解压尚未完成就被断电的情况,从而引起文件烧写不完全,系统启动异常。下面围绕该问题,对Linux文件系统写文件操作进行一些说明。

原理说明

由于Linux系统存在页高速缓存,对写入的内容起到了缓存作用,用户的写操作实际上会被延迟。当页高速缓存中的数据比后台存储的数据新的时候,这些数据就被称作脏数据。发生以下三种情况时,脏页才会被写回磁盘:

    当空闲内存低于一个特定的阈值时,内核必须将脏页写回磁盘以释放内存。当脏页在内存中驻留时间超过一个特定的阈值时,内核必须将超时的脏页写回磁盘,以确保脏页不会无限期地驻留在内存中。当用户进程调用 sync() 和 fsync() 系统调用时,内核会按照要求执行回写操作。

应对方案

如果更新脚本在解压命令后没有sync指令,或者程序更新代码在执行解压或者写操作后没有调用fsync()函数执行写操作,Linux系统就会按照默认机制来实现写操作;如果没有达到如上前2个条件,发生了断电操作,则会导致写入数据不完整。

在程序更新脚本里,解压后必须执行sync指令完成写入同步,或者应用程序代码在写操作后调用fsync()函数完成写同步操作,确保数据写入存储器

国产芯嵌入式高性能RISC-V核心板MR6450/6750
• 15路串口

• 4路CANFD

• 2路千兆

 

致远电子

致远电子

广州致远电子股份有限公司成立于2001年,注册资金5000万元,国家级高新技术认证企业,广州市高端工控测量仪器工程技术研究开发中心,Intel ECA全球合作伙伴和微软嵌入式系统金牌合作伙伴。

广州致远电子股份有限公司成立于2001年,注册资金5000万元,国家级高新技术认证企业,广州市高端工控测量仪器工程技术研究开发中心,Intel ECA全球合作伙伴和微软嵌入式系统金牌合作伙伴。收起

查看更多
点赞
收藏
评论
分享
加入交流群
举报

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录