朋友给介绍的小说,这本小说的特点在于故事线,分三个部分,分别从同一事件的三个不同人物(角色)来围绕故事展开。
故事的背景是辛亥革命,主角 1 是其中的保皇派,主角 2 是其中的光复会成员(刚开始留日的时候是带着小辫子,之后逐渐转向了革命),主角 3 是神父,三个不同角色用不同的叙述、表现方式,展开了故事。
故事还可以,最特别的是三个角色,三种不同的叙述方式,以及三条时间线,值得一看吧。
不过,故事叙述比较宏大,像我,得花不少时间才能理清其中的故事线了。
比如录像文件循环覆盖的逻辑,按照日分割建立文件夹,之后需要考虑如果存储空间不够,需要删除文件或目录,以及按照时间戳可以快速定位文件。
目前了解到的是都只有纯目录、文件的遍历操作,以及没有空间之后,删除日目录下,某个二级目录,作为存储空间的释放(获取)逻辑。
纯目录、文件的遍历操作,因为是嵌入式,nand 访问 IO 口速率比较低,以及 cpu 较差,所以时间上很慢,接口上为了适应这个限制,限制为 255 个文件后一次返回,之后客户端再次请求,传递进去的参数,是上一次返回的最后一个节点的结束时间。
如果类似 windows thumbs 或者 mac os DS_Store 的缓存文件索引策略,我觉得可以改善这个问题。
创建资源文件前,先创建(更新)索引文件,标记为待完成,资源文件完成后 ,再标记为已完成(open 接口,bit 反转),删除文件目录释放存储空间的时候,也同样更新相关标记就行。
若索引文件损坏或者不可用,逻辑上可以回退到纯目录、文件的遍历操作。
特别是文件查找,如果定义索引文件在日目录一级,日目录里面的文件可以根据二分查找,是相当快的,应该比目录遍历快得多,毕竟只需要读取一个索引文件。
索引文件的更新可能导致损坏,因此我才建议用 open 接口,bit 翻转,用先、后标记来保证,如果没有后标记,更精细的做法是校验相关资源文件,若文件是完整的,则可以更新后标记。
同样的,删除也可以用先、后标记来做,这个都没什么问题。
我觉得这样的操作是安全的,以及通过索引文件来定位、遍历资源文件内容是高效的。
目前公司产品(一款嵌入式产品)的固件更新,是使用刷固件(实际上是写固定大小的 jffs2 分区)来做的,大概了解到其更新逻辑是,校验下载后的固件压缩包,校验解压后的固件文件系统包,重启更新(其实还需要教研一次固件文件系统包),刷固件到固定大小的 nand flash 分区(这个时候还需要校验一次),之后再次重启,挂载相关的 jffs2 分区。
实话说,相对于后端 go 这样 static linked 的程序更新(shipping),固件程序的更新实在是太麻烦了,一方面 nand 存储不可靠(虽然 SD 卡等 nand 存储,主控本身保证了数据安全),另外一方面,文件系统挂载为只读处理也是问题,以及刷机,多次重启,很耗费时间,从最开始的 5 分钟慢慢成了现在的 10 分钟。
所以,我想能否改成这样的逻辑:
比如类似 nginx -r 重启加载某个进程(假设都是 linux 的系统),一个 master 进程,下面多个 app 进程(看业务需求),更新逻辑是:
这样,用多进程的方式来进行热更新,其效率会比目前冷启动的效率高得多,当然这里面有不少细节需要确认
这样 HOST 仍能随时更新固件里面的业务进程,这要比单纯仅只读 jffs2 挂载的业务分区,更新的效率高得多。
当然,上述的想法,是基于一些我对固件更新的业务逻辑的了解上,做出的一些改进。
距离我上次在福建做类似的固件开发(linux 嵌入式业务开发),已经超过了 13 年,之前的两个不同产品的更新,一个是完全依赖网络(网卡的 IPXE),一个是 EEPROM,然后再带 nand flash(忘记多大了),跟现在的应该是有差别。
大概思路是这样,如果有可能的话,我觉得改进的效率是很高的,应该要比现在 10 分钟起步的更新快得多得多,但是要求是 linux 的多进程管理,以及同步的能力吧。