对比嵌入式文件系统损耗平衡算法

FLASH均衡磨损 EEPROM仿真算法参数应根据应用需要进行配置;NB_OF_VARIABLES (default 1000, 100 for STM32C0 Series(a)): 非易失性元素,每个元素值为8位、16位、32位或96位。START_PAGE_ADDRESS:用于EEPROM仿真的第一个Flash页的地址。GUARD_PAGES_NUMBER (default 2):用于减少Flash内存压力的保护页面数。这个数必须是偶数。 阅读详情
引言
为什么要损耗平衡(wear-leveling)?
Flash 上的每一位(bit)可以被写操作置成逻辑0。 可是把逻辑 0 置成逻辑 1 却不能按位(bit)来操作,而只能按擦写块(erase block)为单位进行擦写操作。一般来说,“NOR flash擦写块的大小是128K,Nand flash擦写块的大小是8K”【2】。从上层来看,擦写所完成的功能就是把擦写块内的每一位都重设置(reset)成逻辑 1。
Flash 的使用寿命是有限的。“具体来说,flash的使用寿命由擦写块的最大可擦写次数决定。超过了最大可擦写次数,这个擦写块就成为坏块(bad block)了。因此为了避免某个擦写块被过度擦写,以至于它先于其他的擦写块达到最大可擦写次数,我们应该在尽量小的影响性能的前提下,擦写操作均匀的 分布在每个擦写块上。这个过程叫做损耗平衡(wear leveling)”【1】。按照现在的技术水平,一般来说NOR flash擦写块的最大可擦写次数在十万次左右,NAND flash擦写块的最大可擦写次数在百万次左右。
而传统文件系统对于损耗平衡,以及嵌入式系统的掉电保护都没有很好的考虑,所以需要专门的文件系统来读写FLASH。
现有的嵌入式文件系统主要有哪些?
JFFS2 (The Journaling Flash File System 2), YAFFS2 (Yet Another Flash File System 2)等,对于其文件系统的具体分析,不再过多叙述,有兴趣的话可以看看我的参考文献,上面均有详细的分析。本文也就这两种算法的损耗算法进行分析。
                                                                                      
 
正文
JFFS2的损耗平衡算法:
 
在JFFS2 中,Flash被分成一个个擦写块。NOR flash 读/写操作的基本单位是字节;而 NAND flash 又把擦写块分成页(page), 页是写操作的基本单位,一般一个页的大小是 512 或 2K 字节,另外每一页还有16 字节的备用空间(SpareData, OOB)。
JFFS2 维护了几个链表来管理擦写块,根据擦写块上内容的不同情况,擦写块会在不同的链表上。具体来说,当一个擦写块上都是合法(valid)的节点时,它会在 clean_list 上;当一个擦写块包含至少一个过时(obsolete)的节点时,它会在 dirty_list 上;当一个擦写块被擦写完毕,并被写入 CLEANMARKER 节点后,它会在 free_list 上。下表表示了具体链表名:
表1 JFFS2的链表中擦除块名称一览表【3】
链表
链表中擦除块的性质
clean_list
只包含有效数据结点
very_dirty_list
所含数据结点大部分都已过时
dirty_list
至少含有一个过时数据结点
erasable_list
所有的数据结点都过时需要擦除。但尚未“调度”到erase_pending_list
erasable_pending_wbuf_list
同erase_pending_list,但擦除必须等待wbuf冲刷后
erasing_list
当前正在擦除
erase_pending_list
当前正等待擦除
erase_complete_list
擦除已完成,但尚未写入CLEANMARKER
free_list
擦除完成,且已经写入CLEANMARKER
bad_list
含有损坏单元
bad_used_list
含有损坏单元,但含有数据
 
       现在开始分析具体源代码,源程序文件路径为:uClinux-dist/linux-2.6.x/fs/jffs2
>jffs2/fs.c
在挂载jffs2文件系统时,在jffs2_do_fill_super函数的最后创建并启动GC内核线程,相关代码如下:
if (!(sb->s_flags & MS_RDONLY))
              jffs2_start_garbage_collect_thread(c);
       return 0;
如 果jffs2文件系统不是以只读方式挂载的,就会有新的数据实体写入flash。而且jffs2文件系统的特点是在写入新的数据实体时并不修改flash 上原有数据实体,而只是将其内核描述符标记为“过时”。系统运行一段时间后若空白flash擦除块的数量小于一定阈值,则GC被唤醒用于释放所有过时的数 据实体【3】。
为了尽量均衡地使用flash分区上的所有擦除块,在选择有效数据实体的副本所写入的擦除块时需要考虑Wear Leveling算法,jffs2_find_gc_block()即Wear Leveling算法的关键函数:
>jffs2/gc.c
static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
{
        struct jffs2_eraseblock *ret;
        struct list_head *nextlist = NULL;
        int n = jiffies % 128; //0~127的随机数
        /* Pick an eraseblock to garbage collect next. This is where we'll
           put the clever wear-levelling algorithms. Eventually. */
        /* We possibly want to favour the dirtier blocks more when the
           number of free blocks is low. */
        if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
                D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next/n"));
                nextlist = &c->bad_used_list; //含有损坏单元,但含有数据的块中先回收
        } else if (n < 50 && !list_empty(&c->erasable_list)) {
                /* Note that most of them will have gone directly to be erased.
                   So don't favour the erasable_list _too_ much. */
                D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next/n"));
                nextlist = &c->erasable_list;// 如果有已过时,但尚未擦除的块,50/128的概率回收         } else if (n < 110 && !list_empty(&c->very_dirty_list)) {
                /* Most of the time, pick one off the very_dirty list */
                D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next/n"));
                nextlist = &c->very_dirty_list;//如果有大部分数据已经过时的块,110/128的概率回收         } else if (n < 126 && !list_empty(&c->dirty_list)) {
                D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next/n"));
                nextlist = &c->dirty_list;//如果有部分数据已经过时的块,126/128的概率回收
        } else if (!list_empty(&c->clean_list)) {
                D1(printk(KERN_DEBUG "Picking block from clean_list to GC next/n"));
                nextlist = &c->clean_list;//回收只含有有效数据的块
        } else if (!list_empty(&c->dirty_list)) {
                D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)/n"));                        
                nextlist = &c->dirty_list;//回收有部分数据已经过时的块
        } else if (!list_empty(&c->very_dirty_list)) {
                D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)/n"));
                nextlist = &c->very_dirty_list;//回收大部分数据已经过时的块
        } else if (!list_empty(&c->erasable_list)) {
                D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)/n")
);                nextlist = &c->erasable_list;//回收已过时,但尚未擦除的块
        } else {
                /* Eep. All were empty */
                D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?/n"));
                return NULL;//已经无可调度的块
        }      
 
        ret = list_entry(nextlist->next, struct jffs2_eraseblock, list);
        list_del(&ret->list);
        c->gcblock = ret;        
        ret->gc_node = ret->first_node;
        if (!ret->gc_node) {
                printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL/n", ret->offset);
                BUG();
        }      
               
        /* Have we accidentally picked a clean block with wasted space ? */
        if (ret->wasted_size) {
                D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size/n", ret->wasted_size));
                ret->dirty_size += ret->wasted_size;
                c->wasted_size -= ret->wasted_size;
                c->dirty_size += ret->wasted_size;
                ret->wasted_size = 0;
        }            
 
        D1(jffs2_dump_block_lists(c));
        return ret;
}
 
由 上可见,JFFS2的处理方式是以 50/128的概率回收erasable_list,以110/128概率回收 very_dirty_list,以126/128概率回收 dirty_list,剩下概率回收 clean_list。当然从程序中也可以看出,回收后一条链表块,是要在一定概率以及前面的块链表为空的情况下。
JFFS2 对损耗平衡是用概率的方法来解决的,这很难保证损耗平衡的确定性。在某些情况下,可能造成对擦写块不必要的擦写操作;在某些情况下,又会引起对损耗平衡调整的不及时。
“据 说后来,JFFS2有改进的损耗平衡补丁程序,这个补丁程序的基本思想是,记录每个擦写块的擦写次数,当flash上各个擦写块的擦写次数的差距超过某个 预定的阀值,开始进行损耗平衡的调整。调整的策略是,在垃圾回收时将擦写次数小的擦写块上的数据迁移到擦写次数大的擦写块上。这样一来我们提高了损耗平衡 的确定性,我们可以知道什么时候开始损耗平衡的调整,也可以知道选取哪些擦写块进行损耗平衡的调整”【1】。
现 在,JFFS3也正在开发中,在垃圾回收一章中,作者有这样的话:“JFFS3 Garbage Collection is currently under development and this chapter may be changed. Any suggestions and ideas are welcome.”【4】,还没有发布具体的设计(05年写得啊。。。)。我期待Artem B. Bityutskiy能设计出更加巧妙而高效的平衡算法。
 
YAFFS2的损耗平衡算法:
 
YAFFS是专门针对Nand flash的文件系统,YAFFS1只能支持每页为512B。而YAFFS2则另外也支持2K的页面, 其他方面变化见网页介绍:www.aleph1.co.uk/node/38。
YAFFS 对文件系统上的所有内容(比如正常文件,目录,链接,设备文件等等)都统一当作文件来处理,每个文件都有一个页面专门存放文件头,文件头保存了文件的模 式、所有者id、组id、长度、文件名、Parent Object ID 等信息。因为需要在一页内放下这些内容,所以对文件名的长度,符号链接对象的路径名等长度都有限制。    
前 面说到对于Nand flash上的每一页数据,都有额外的空间用来存储附加信息,通常Nand flash 驱动只使用了这些空间的一部分,YAFFS正是利用了这部分空间中剩余的部分来存储文件系统相关的内容。以512+16B为一个PAGE 的Nand flash芯片为例, YAFFS 文件系统数据的存储布局如下所示:
表2  YAFFS的存储布局【5】
0-511
Data
512-515
YAFFS TAG
516
Data status byte
517
Block status byte
518-519
YAFFS TAG
520-522
后256字节的ECC
523-524
YAFFS TAG
525-527
前256字节的ECC
可以看到在这里YAFFS 一共使用8个BYTE 用来存放文件系统相关的信息(yaffs_Tags)。这8 个Byte 的具体使用情况按顺序如下:    
表3  yaffs_Tags的具体使用情况【5】
位
属性
20
ChunkID,该page 在一个文件内的索引号
2
2 bits serial number
10
ByteCount 该page 内的有效字节数
18
ObjectID 对象ID 号,用来唯一标示一个文件
12
Ecc, Yaffs_Tags 本身的ECC 校验和
2
保留
 
其中Serial Number 在文件系统创建时都为0,以后每次写具有同一ObjectID 和ChunkID 的page 的时候都      加1, 因为YAFFS 在更新一个PAGE 的时候总是在一个新的物理Page 上写入数据,再将原先的物理Page 删除,所以该serial number 可以在断电等特殊情况下,当新的page 已经写入但老的page 还没有被删除的时候用来识别正确的Page,保证数据的正确性。这对保存数据的完整性是很有用的。
YAFFS 按顺序分配当前块中的页。当该块中所有的页都用光后,另外一个干净的块将会被选择分配。至少保留2到3个块用于垃圾块收集。当没有足够的干净块的时候,脏 块(比如只包含丢弃数据)将会被擦除成干净块。如果没有脏块,那些特别脏的块(含有丢弃数据特别多的块)也会被垃圾块回收算法选中。
作 者也指出,YAFFS的损耗平衡是块分配策略的副产品,数据总是被写在下一个空闲块中,所有的块都是被平等对待的。但是包含那些永久数据的块却不会再回收 到空闲块中,所以他所说的损耗平衡也仅仅指那些已经空闲或者有可能变空闲的块。假设在一块8M的NAND器件上,有2M空间用来存放相对固定,不经常修改 的数据文件,则经常修改的文件只能在剩下的6M空间上重复擦写。只在这6M空间上做到均匀损耗,而没有包括剩余的2M。“对整个器件来说,系统并没有合适 的搬移策略对固定文件进行搬移,整个器件做不到均匀损耗,在实时记录信息量比较大的应用环境中,应编写相应的搬移策略函数,对固定文件进行定期的搬移,以 确保整个NAND器件的均匀损耗”【7】。
下面开始分析源代码,其公司的主页上可以下到最新源代码:www.aleph1.co.uk/node/
可以看下它回收算法的关键函数yaffs_CheckGarbageCollection():
>fs/yaffs/yaffs_guts.c
/*
如果可用的擦除块很少,我们就采用“主动模式”来收集垃圾块,否则我们就采用“被动模式”。“主动模式”中将会查看整个Flash的块,就算只有少量过时数据的块也会被回收。“被动模式”只会查收少量区域,然后回收那些过时数据特别多的块。
 */
static int yaffs_CheckGarbageCollection(yaffs_Device * dev)
{
       int block;
       int aggressive;
       int gcOk = YAFFS_OK;
       int maxTries = 0;   
       int checkpointBlockAdjust;
       if (dev->isDoingGC) {
              return YAFFS_OK;
       }    
      
       do {
              maxTries++;         
              checkpointBlockAdjust = (dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint);
              if(checkpointBlockAdjust < 0)
                     checkpointBlockAdjust = 0;
 
              if (dev->nErasedBlocks < (dev->nReservedBlocks + checkpointBlockAdjust)) {
/* 跟需要保留的块数和自定义校准块的和作比较,如果少于这个值,就直接选择主动模式*/
                     aggressive = 1;
              } else {
                     /* 否则,选择被动模式 */
                     aggressive = 0;
              }
/*根据模式查找,回收相应的块*/
              block = yaffs_FindBlockForGarbageCollection(dev, aggressive);
              if (block > 0) {
                     dev->garbageCollections++;
                     if (!aggressive) {
                            dev->passiveGarbageCollections++;
                     }
 
                     T(YAFFS_TRACE_GC,
                      (TSTR
                        ("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR),
                        dev->nErasedBlocks, aggressive));
 
                     gcOk = yaffs_GarbageCollectBlock(dev, block);
              }
              if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) {
                     T(YAFFS_TRACE_GC,
                      (TSTR
                        ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d"
                         TENDSTR), dev->nErasedBlocks, maxTries, block));
              }
       } while ((dev->nErasedBlocks < dev->nReservedBlocks) && (block > 0)
               && (maxTries < 2));
 
       return aggressive ? gcOk : YAFFS_OK;
}
 
 
从上面的算法也可以看出,其实YAFFS的损耗平衡算法也没什么可讲的,主要是由于设计的原因,导致其平等地回收每一个空闲块。如果空闲块比较少,就加紧回收稍微有空闲的块。因为设计简单,所以效率还是不错的,下表是其测试结果,结果还是相当不错:
表4 Times for 1MB of garbage collection at 50% dirty (单位1uS).【6】
Operation
YAFFS1
YAFFS2(512b pages)
YAFFS2 (2kB pages)
YAFFS2(2kB pages, x16)
Delete 1MB
558080
128000
16000
16000
Write 0.5MB
337920
337920
168960
112640
Total
896000
465920
184960
128640
MB/s
1.1
2.1
5.4
7.7
Relative speed
1
1.9
4.9
7
 
总结及展望:
通 过阅读JFFS2和YAFFS的文献的代码,我觉得谁优谁劣很难讲。JFFS的文件系统开发要比YAFFS要早得多,现在应用范围也比YAFFS广。可以 说YAFFS就是相当于JFFS的“另一种文件系统”,所以YAFFS一开始就是从借鉴JFFS开始的,避免了JFFS启动速度过慢和损耗不平衡等明显的 缺点,当然后来JFFS2也进行了改进,如把数据移动到页的末尾(而YAFFS是放在页的前面),而不再是链表式在页中随便乱放,导致装载速度巨慢。在 YAFFS公司网页的开发内容中也可以看到,YAFFS和JFSS2的开发人员经常进行交流。从我个人的角度来看,YAFFS2要比JFFS2好些,当然 这是仅限于Nand flash来说。在阅读YAFFS2的源代码时我发现,最新的更新日期是07年3月,而就我所看到的JFFS2代码是04年5月,而JFFS3的设计草案 【4】的发布日期也是05年11月。两种文件系统的维护速度可见一斑。
以上的分析我也只能定性得说下,如果有Flash芯片可以测试,那就可以定量的分析了。如果有时间,我想再深入看下两类文件系统的源代码,顺便推荐下,参考文献【3】确实写得很认真,值得一看。
 
参考文献:
【1】、JFFS2文件系统及新特性介绍: www.sqlus.com/Columns/LinuxSkill/012108669.html
【2】、David Woodhouse,   JFFS : The Journalling Flash File System
【3】、shrek2( www.linuxforum.net的一个ID),《JFFS2源代码情景分析(Beta2)》
【4】、Artem B. Bityutskiy,   JFFS3 design issues(Version 0.32 (draft))
【5】、Raymond( skyflame@hotmail.com),《Yaffs文件系统结构及应用》
【6】、YAFFS Development Notes: http://www.aleph1.co.uk/node/39
【7】、胡一飞,徐中伟,谢世环,《NAND flash上均匀损耗与掉电恢复在线测试》
 
 

Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=2056695

 
三大通信协议(3)SPI——flash擦除实验 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 一、知识储备 在编写完Verilog程序后,需要将程序下载到硬件FPGA中进行上板验证,通常有两种下载方式:1.直接生成.sof文件,通过JTAG接口下载到FPGA中,这种方式下载速度较快,操作简单,但是由于它是将程序直接烧录到FPGA内部的SRAM中,因此,断电后程序自动丢失。2.通过转换,将生成的.so... 阅读详情

相关推荐

《LangChain技术原理剖析:OpenAI Function Calling的实践与应用》

,"unit": {},name:函数的唯一标识符:自然语言描述,决定LLM如何选择该函数parameters:定义输入参数的完整Schema。

qq_62223405的博客 980

STM32内部Flash模拟EEPROM磨损均衡算法

目录前言一、为什么需要使用磨损均衡算法二、算法均衡说明1、最小数据存储结构2、读写方案三、算法实现代码1.头文件2.源文件总结 前言 许多场合下我们需要掉电保存一些参数,使用EEPROM会增加成本且开发麻烦。利用内部FLASH模拟EEPROM可在节约硬件成本的情况下通过简单的算法很方便地实现同样的功能。 一、为什么需要使用磨损均衡算法 1、EEPROM按字节擦写数据,内部FLASH只能按页擦除,按半字写入; 2、FLASH 单个存储位只能从1变为0,而不能从0变成1; 3、擦除过程就是把所有的存储位都写

DaveDing888的博客 9498

【FPGA】定点数运算中的位宽优化与截取策略

本文深入探讨了FPGA定点数运算中的核心挑战——数据位宽优化与截取策略。针对定点数在加法、乘法等运算中位宽膨胀的问题,文章详细分析了位宽变化规律,并对比了直接截断、四舍五入和收敛舍入三大截取策略的优缺点及硬件实现方法。通过实战指南与避坑经验,旨在帮助开发者在保证计算精度的同时,高效利用FPGA资源,实现性能与面积的平衡。

weixin_29181861的博客 117

Nand Flash均衡算法

Nand Flash由于有擦除次数的限制,因此在对其进行写操作时需要使用写均衡算法使得nand flash上各块的擦写次数均衡,从而提高nand flash的使用寿命。2         FTL实现方案2.1        FTL整体框架图2-1 FTL整体框架图2-1所示为FTL的整体框架示意图,途中的虚线框中模块即为FTL模块。从图中可知,FTL模块是Nand Flash应用层与Nand Fl...

三块石头的博客 3891

车载以太网抓包实战:100BASE-T1/1000BASE-T1高效监控方案解析

本文深入解析了车载以太网100BASE-T1/1000BASE-T1的高效抓包监控方案。针对智能汽车开发中的故障排查与性能测试需求,详细对比了交换机镜像、TAP分流和捕获模块三大主流方案的原理、核心优势与适用场景,并提供了基于实战经验的选型指南与操作避坑要点,帮助工程师精准定位网络问题。

desk3的博客 428

SAP_SD模块信用管理-最早未清项判断逾期

在 SAP SD 模块的信用管理(Credit Management) 中,系统可以通过 最早未清项(Oldest Open Item) 来判断客户是否存在逾期,从而影响订单的信用检查结果。例如: 定义最大未清项目%为1%,未清天数为1天,即允许客户“逾期1天的未清应收帐款/该客户的应收帐款余额”最大比例为1%,若超过1%则将被信用冻结。的信用检查功能,用于判断客户是否有账龄过长的未清款项,并据此决定是否允许新的销售订单继续处理。然后在查看客户的信贷信息可以看到,最早的未清信息显示在系统中。

我小时候很黑的博客 863

【FLASH】STM32内部Flash模拟EEPROM磨损均衡算法--存储设备擦写均衡自带掉电保护接口-如何在同等存储空间下增加FLASH寿命呢?往下看-STM32F334实现FLASH擦写均衡

erase_flash:这里的长度其实无效,这里需要提供的是擦除一页的接口,这里也许会有人说NAND Flash,最小擦除单位为1块,也就是64页,怎么办呢?ReadAddr:读地址,由于查找最后一块有效数据地址随着分区的大小,查找时间会相应的变长,所以在系统上电初始化的时候将最后一块有效数据块首地址记录,之后就不用再从子分区0查找了,提高系统执行效率,这个保留在这,暂未实现,后面的版本会加入。打个比方:周一到周五的菜单,每天固定三个菜,要进行存储的话,就需要提供五组数据,那么日期就是ID,用来区分周几。

qq_53828053的博客 4618

1、电路分析知识全解析:从基础到实践应用

本博客全面解析电路分析知识体系,涵盖从基础的电压、电流、电阻概念到复杂的交流电路、瞬态分析和高级应用如滤波器与变压器等内容。适合电子技术专业学生和技术爱好者学习,提供详细的知识结构、学习路径、实践示例以及丰富的学习资源,包括计算机模拟工具Multisim和PSpice的使用指导。通过理论与实践结合,帮助学习者掌握电路分析的核心技能,为电子工程和电力系统等相关领域打下坚实基础。

iii12的专栏 159

嵌入式文件系统损耗平衡算法

为什么要损耗平衡(wear-leveling)? Flash上的每一位(bit)可以被写操作置成逻辑0。 可是把逻辑 0 置成逻辑 1 却不能按位(bit)来操作,而只能按擦写块(erase block)为单位进行擦写操作。一般来说,“NOR flash擦写块的大小是128K,Nand flash擦写块的大小是8K”【2】。从上层来看,擦写所完成的功能就是把擦写块内的每一位都重设置(rese...

weixin_33835690的博客 555

【数据分析八步法】将模糊需求转化为可验证的分析问题

国内访问Huggingface官方源常遇网络问题,可通过切换国内镜像提升下载速度。三种配置方式:1)设置HF_ENDPOINT环境变量;2)在from_pretrained中直接指定镜像参数;3)修改本地Huggingface配置文件。常用镜像包括hf-mirror.com、阿里云ModelScope和清华镜像源。注意镜像同步延迟、私有模型限制,建议配合huggingface-cli工具使用,必要时取消代理设置。合理配置镜像源可显著改善Huggingface生态使用体验。

Mr数据杨 858

【WRF数据介绍第一期】静态地理数据介绍及下载

WRF数据介绍第一期:静态地理数据介绍及下载

WW、forever的博客 4813

嵌入式文件系统详解

在嵌入式领域,FLASH是一种常用的存储设备,Flash闪存作为嵌入式系统的主要存储设备有其自身的特性。Fash的写入操作只能把对应位置的1修改成0,而不能把0修改为1,而擦除Fash就是把对应存储块的内容恢复为1。因此,一般情况下,向Fash写入内容时,需要先擦除对应的存储区间,这种擦除是以块(Bock)为单位进行的。闪存主要有NOR和NAND两种技术。因为Flash存储器的擦写次数是有............

Biao 1万+

YOLOv8-Pose 姿态识别 RK3588 实战:从模型训练到 RKNN 部署,精度与推理速度双提升

本教程从YOLOv8-pose模型的姿态识别训练,到RK3588的边缘量化部署,为你打造了一套“高精度+高实时性+低成本”的人体姿态分析解决方案。无论是健身动作纠正、智能安防行为检测,还是工业人员姿态监控,这套技术都能直接复用——你只需替换数据集与业务逻辑,即可快速落地专属的边缘AI姿态识别系统。如果你在实践中遇到任何卡点,欢迎随时交流。记住,人体姿态识别的价值在于“关键点准、推理快、部署易”,而这三者的平衡,正是你通过本教程能掌握的核心能力。

FJN110的博客 364

嵌入式常用的文件系统特点

嵌入式常用的文件系统特点 文章目录嵌入式常用的文件系统特点常用的文件系统1、cramfs2、JFFS23、yaffs24、initrd5、squashfs ps:此文为本人在学习了“Hi3518EV20X/Hi3516CV200 Linux开发环境用户指南.pdf”文档后,总结记录下各常用文件系统的特点,以加深印象。 常用的文件系统 嵌入式系统中比较常用的文件系统有:cramfs、JFFS2、NFS、initrd、yaffs2、Ext4、squashfs以及others… 他们的特点如下: cramfs和

weixin_39888281的博客 3679

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

YAFFS文件系统在嵌入式Linux上的实现

 引言       随着嵌入式技术在各种电子产品中的广泛应用,嵌入式系统中的数据存储和管理已经成为一个重要的研究课题。Flash存储器具有速度快、容量大、成本低等很多优点,因此在嵌入式系统中被广泛用做外存储器件。Flash主要有NOR和NAND两种类型。目前,针对NOR Flash设计的文件系统JFFS/JFFS2在嵌入式系统中已得到广泛的应用;随着NAND作为大容量存储介质的普及,基于NAND闪

DerekYao的专栏 3068

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

嵌入式文件系统详解_嵌入式 文件系统工作原理

即文件系统是针对于存储器分区而言的,而非存储芯片。Cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP方式运行,所有的应用程序要求被拷到RAM里去运行,但这并不代表比Ramfs需求的RAM空间要大一点,因为Cramfs是采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,只针对目前实际读取的部分分配内存,尚没有读取的部分不分配内存空间,当我们读取的档案不在内存时,Cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。

2401_87555332的博客 1205

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

嵌入式linux系统中常用的文件系统

原文:https://blog.youkuaiyun.com/li_wen01/article/details/80090624 嵌入式linux系统中常用的文件系统: 闪存主要有NOR和NAND两种技术;因为Flash存储器的擦写次数是有限的,NAND闪存还有特殊的硬件接口和读写时序,于是就出现了专门针对FLASH的文件系统。比较常用的有jffs2,yaffs2,logfs,ubifs。传统的文件...

qq_35480064的博客 1628

嵌入式文件系统

嵌入式文件系统 背景 Flash是目前嵌入式系统的主要存储设备,Flash闪存主要有NOR和NAND两种技术。因为Flash存储器的擦写次数是有限的, NAND闪存还有特殊的硬件接口和读写时序,于是就出现了专门针对FLASH的文件系统。比较常用的有jffs2,yaffs2,logfs,ubifs. 传统的文件系统如ext2、ext3、ntfs等都是针对机械式硬盘设计的,用作Flash文件系统会很多的弊端. 分区特点 一块Flash芯片可以被划分为多个分区,各分区可以采用不同的文件系统;两块Flash

玩命的狙击手 1064

嵌入式文件系统YAFFS简介

YAFFS(Yet Another Flash File System)是第一个专门为NAND Flash存储器设计的嵌入式文件系统,适用于大容量的存储设备;并且是在GPL(General Public License)协议下发布的,可在其网站免费获得源代码。 YAFFS 是基于日志的文件系统,提供磨损平衡和掉电恢复的健壮性。它还为大容量的Flash 芯片做了很好的调整,针对启动时间和RAM 的使用做了优化。它适用于大容量的存储设备,已经在Linux 和WinCE 商业产品中使用。...

嵌入式之斋 914

LittleFS - 一个高度完整的嵌入式文件系统

LittleFS - 一个高度完整的嵌入式文件系统   拥有小巧灵活的文件系统对许多物联网设备至关重要。使用文件系统并将其与正确的存储技术(如外部闪存或SD卡)配对可能很困难。Mbed操作系统使文件系统的组合变得简单。Mbed OS 5.7既支持FAT文件系统,又引入了高度集成的嵌入式文件系统。这包括对没有自己的磨损平衡控制器的闪存芯片的磨损平衡支持。 LittleFS  - 一个高度完整的...

yi412的专栏 4940

2024年物联网嵌入式最新嵌入式文件系统详解_嵌入式 文件系统工作原理,2024年最新我阿里P7了解到的物联网嵌入式开发面试的一些小内幕

即文件系统是针对于存储器分区而言的,而非存储芯片。Cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP方式运行,所有的应用程序要求被拷到RAM里去运行,但这并不代表比Ramfs需求的RAM空间要大一点,因为Cramfs是采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,只针对目前实际读取的部分分配内存,尚没有读取的部分不分配内存空间,当我们读取的档案不在内存时,Cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。

2401_85013604的博客 1137

嵌入式Linux 文件系统简介

1 文件系统简介 Linux 目录结构的最顶层是一个被称为“/”的根目录。系统加载Linux 内核之后,会挂载一个设备到根目录上。存在这个设备中的文件系统被称为根文件系统。所有的系统命令、系统配置以及其他文件系统的挂载点都位于这个根文件系统中。根文件系统通常存放于内存和Flash 中。根文件系统中存放了嵌入式系统使用的所有应用程序、库以及其他需要用到的服务。嵌入式系统中常用文件系统包括...

227
上一篇: 从NAND闪存中启动U-BOOT的设计
下一篇: 嵌入式linux下常见的文件系统
menuconfig
博客等级 码龄19年 713粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值