本發(fā)明涉及一種基于NandFlash的數(shù)據(jù)存儲(chǔ)方法,屬于
技術(shù)領(lǐng)域:
。
背景技術(shù):
:在嵌入式系統(tǒng)中,對(duì)數(shù)據(jù)庫(kù)的操作具有定時(shí)限制的特性,這里把應(yīng)用于嵌入式系統(tǒng)的數(shù)據(jù)庫(kù)系統(tǒng)稱為嵌入式數(shù)據(jù)庫(kù)系統(tǒng)或嵌入式實(shí)時(shí)數(shù)據(jù)庫(kù)系統(tǒng)(ERTDBS)。目前嵌入式軟件系統(tǒng)開(kāi)發(fā)的挑戰(zhàn)之一,體現(xiàn)在對(duì)各種數(shù)據(jù)的管理能否建立一套可靠、高效、穩(wěn)定的管理模式,嵌入式數(shù)據(jù)庫(kù)可謂應(yīng)運(yùn)而生。嵌入式數(shù)據(jù)庫(kù)的名稱來(lái)自其獨(dú)特的運(yùn)行模式。這種數(shù)據(jù)庫(kù)嵌入到了應(yīng)用程序進(jìn)程中,消除了與客戶機(jī)服務(wù)器配置相關(guān)的開(kāi)銷。嵌入式數(shù)據(jù)庫(kù)實(shí)際上是輕量級(jí)的,在運(yùn)行時(shí),它們需要較少的內(nèi)存。它們是使用精簡(jiǎn)代碼編寫(xiě)的,對(duì)于嵌入式設(shè)備,其速度更快,效果更理想。嵌入式運(yùn)行模式允許嵌入式數(shù)據(jù)庫(kù)通過(guò)SQL來(lái)輕松管理應(yīng)用程序數(shù)據(jù),而不依靠原始的文本文件。嵌入式數(shù)據(jù)庫(kù)還提供零配置運(yùn)行模式,這樣可以啟用其中一個(gè)并運(yùn)行一個(gè)快照。嵌入式系統(tǒng)必須能夠在沒(méi)有人工干預(yù)的情況下,長(zhǎng)時(shí)間不間斷地運(yùn)行,必須充分保證其可靠性。同時(shí)要求數(shù)據(jù)庫(kù)操作具備可預(yù)知性,而且系統(tǒng)的大小和性能也都必須是可預(yù)知的,這樣才能保證系統(tǒng)的性能。嵌入式系統(tǒng)中會(huì)不可避免地與底層硬件打交道,因此在數(shù)據(jù)管理時(shí),也要有底層控制的能力,如什么時(shí)候會(huì)發(fā)生磁盤操作,磁盤操作的次數(shù),如何控制等。底層控制的能力是決定數(shù)據(jù)庫(kù)管理操作的關(guān)鍵。嵌入式數(shù)據(jù)庫(kù)是嵌入式系統(tǒng)的重要組成部分,也成為對(duì)越來(lái)越多的個(gè)性化應(yīng)用開(kāi)發(fā)和管理而采用的一種必不可少的有效手段。嵌入式數(shù)據(jù)庫(kù)用途廣泛,如用于消費(fèi)電子產(chǎn)品、移動(dòng)計(jì)算設(shè)備、企業(yè)實(shí)時(shí)管理應(yīng)用、網(wǎng)絡(luò)存儲(chǔ)與管理以及各種專用設(shè)備,這一市場(chǎng)目前正處于高速增長(zhǎng)之中。目前常用的嵌入式數(shù)據(jù)庫(kù)有BerkeleyDB、SQLite、Empress、eXtremeDB、Firebird嵌入服務(wù)器版、mSQL,然而這些嵌入式數(shù)據(jù)庫(kù)都需要嵌入式系統(tǒng)與文件系統(tǒng)的支持,并且對(duì)系統(tǒng)的程序存儲(chǔ)器以及內(nèi)存都有比較高的要求,不適合在中小型的嵌入式系統(tǒng)進(jìn)行應(yīng)用。NandFlash內(nèi)存是flash內(nèi)存的一種,其內(nèi)部采用非線性宏單元模式,為固態(tài)大容量?jī)?nèi)存的實(shí)現(xiàn)提供了廉價(jià)有效的解決方案。Nand-flash存儲(chǔ)器具有容量較大,改寫(xiě)速度快等優(yōu)點(diǎn),適用于大量數(shù)據(jù)的存儲(chǔ),因而在業(yè)界得到了越來(lái)越廣泛的應(yīng)用,如嵌入式產(chǎn)品中包括數(shù)碼相機(jī)、MP3隨身聽(tīng)記憶卡、體積小巧的U盤等。NandFlash由于生產(chǎn)工藝的問(wèn)題,其在出廠時(shí)可能存在一定的壞塊。這些固有壞塊不能用于存儲(chǔ)數(shù)據(jù),已被產(chǎn)家標(biāo)識(shí)好。另外,使用過(guò)程中由于讀寫(xiě)次數(shù)增多,好塊也會(huì)變得不穩(wěn)定或失效,成為壞塊,這就是出廠后產(chǎn)生的壞塊,從而導(dǎo)致存儲(chǔ)的數(shù)據(jù)時(shí)效。技術(shù)實(shí)現(xiàn)要素:本發(fā)明所要解決的技術(shù)問(wèn)題是克服現(xiàn)有技術(shù)的缺陷,提供一種基于NandFlash的數(shù)據(jù)存儲(chǔ)方法,基于大容量的NandFlash芯片,使用數(shù)據(jù)冗余技術(shù),能夠在運(yùn)行中更新NandFlash的壞塊映射表與存儲(chǔ)信息表,避免了數(shù)據(jù)的丟失。為解決上述技術(shù)問(wèn)題,本發(fā)明提供一種基于NandFlash的數(shù)據(jù)存儲(chǔ)方法,包括以下步驟:1)設(shè)計(jì)數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu);所述數(shù)據(jù)結(jié)構(gòu)為:WritePtr——下一條數(shù)據(jù)記錄的寫(xiě)指針;ValidFlag——數(shù)據(jù)有效標(biāo)志;UserData——用戶數(shù)據(jù);CRC——CRC16校驗(yàn);左側(cè)為字段,右側(cè)為字段所指代的含義;2)對(duì)Nandflash的壞塊進(jìn)行檢測(cè);3)設(shè)計(jì)數(shù)據(jù)存儲(chǔ)映射;數(shù)據(jù)存儲(chǔ)映射具體為:檢測(cè)NandFlash的壞塊,建立壞塊映射表,將NandFlash的可用塊劃分為兩個(gè)相同大小的數(shù)據(jù)存儲(chǔ)區(qū)與一個(gè)備用數(shù)據(jù)區(qū),建立兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)映射表與一個(gè)備用數(shù)據(jù)區(qū)映射表;4)進(jìn)行數(shù)據(jù)存儲(chǔ),具體如下:4-1)分配每一種數(shù)據(jù)的存儲(chǔ)空間,存儲(chǔ)空間在兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)同時(shí)分配,兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)定義為數(shù)據(jù)存儲(chǔ)區(qū)1與數(shù)據(jù)存儲(chǔ)區(qū)2,為此每種數(shù)據(jù)配置一條索引表,索引表的數(shù)據(jù)結(jié)構(gòu)為:InitFlag——索引表初始化標(biāo)識(shí);StartBlock——起始?jí)K號(hào);EndBlock——結(jié)束塊號(hào);BlockSize——塊大?。籖ecordLen——一條數(shù)據(jù)記錄大?。籇ataLength——有效數(shù)據(jù)總長(zhǎng)度;WritePtr1——寫(xiě)指針1;WritePtr2——寫(xiě)指針2;左側(cè)為字段,右側(cè)為字段所指代的含義;4-2)讀取數(shù)據(jù)索引表,然后判斷索引表的有效性,如果索引表無(wú)效,則進(jìn)行索引表初始化,如果索引表的有效,然后判斷是否數(shù)據(jù)存儲(chǔ)同步;4-3)如果是,則判斷數(shù)據(jù)寫(xiě)指針是否為塊首地址,如果為塊首地址則先進(jìn)行擦除,然后將用戶數(shù)據(jù)及校驗(yàn)寫(xiě)入兩個(gè)緩沖區(qū);4-4)如果NandFlash進(jìn)行數(shù)據(jù)寫(xiě)入失敗,則標(biāo)記當(dāng)前塊為壞塊,然后更新壞塊映射表,從備用數(shù)據(jù)區(qū)分配一個(gè)緩沖區(qū)到數(shù)據(jù)存儲(chǔ)區(qū),再更新備用數(shù)據(jù)區(qū)映射表與數(shù)據(jù)存儲(chǔ)區(qū)映射表,然后重新寫(xiě)入;4-5)每個(gè)數(shù)據(jù)存儲(chǔ)區(qū)寫(xiě)入成功后更新數(shù)據(jù)索引表的寫(xiě)指針。前述的對(duì)Nandflash的壞塊進(jìn)行檢測(cè)包括對(duì)先天性壞塊進(jìn)行檢測(cè)和對(duì)后天性壞塊進(jìn)行檢測(cè);對(duì)先天性壞塊進(jìn)行檢測(cè)方法為:調(diào)用擦除程序,將NandFlash全部擦除一遍,然后執(zhí)行如下檢測(cè)操作:如果頁(yè)大于512字節(jié),badblockpos=0;badblockbytes=2;如果頁(yè)小于512字節(jié),badblockpos=5;badblockbytes=1;讀取每個(gè)block的前兩頁(yè)OOB區(qū)域的第badblockpos開(kāi)始的后badblockbytes字節(jié)是否為全0xff,如果是,那么說(shuō)明該block是好的,否則該block是壞塊;對(duì)后天性壞塊進(jìn)行檢測(cè)方法為:如果BlockErase或者PageProgram錯(cuò)誤,則為壞塊,則將壞塊的第一個(gè)page的sparearea的前6個(gè)Byte都標(biāo)記為非0xff的值。前述的步驟4)中,寫(xiě)入時(shí)序?yàn)橄葘?xiě)數(shù)據(jù)存儲(chǔ)區(qū)1,然后更新寫(xiě)指針1,再數(shù)據(jù)存儲(chǔ)區(qū)2,最后更新寫(xiě)指針2。前述的步驟4)中,對(duì)存儲(chǔ)數(shù)據(jù)的總長(zhǎng)度進(jìn)行了限制,當(dāng)存儲(chǔ)的數(shù)據(jù)達(dá)到設(shè)定的長(zhǎng)度時(shí),則進(jìn)行循環(huán)寫(xiě)入,將最早的數(shù)據(jù)覆蓋。當(dāng)出現(xiàn)兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)的數(shù)據(jù)不同步時(shí),需要進(jìn)行數(shù)據(jù)同步,具體過(guò)程如下:寫(xiě)指針1與寫(xiě)指針2一致時(shí),數(shù)據(jù)存儲(chǔ)區(qū)1讀取寫(xiě)指針1開(kāi)始的RecordLen長(zhǎng)度數(shù)據(jù),判斷數(shù)據(jù)的有效性,數(shù)據(jù)有效則更新寫(xiě)指針1,再將數(shù)據(jù)寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)2,更新寫(xiě)指針2;寫(xiě)指針1與寫(xiě)指針2不一致時(shí),對(duì)于數(shù)據(jù)存儲(chǔ)了而寫(xiě)指針2未更新的情況,判斷數(shù)據(jù)的有效性,數(shù)據(jù)有效則更新寫(xiě)指針2,再將數(shù)據(jù)寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)2;對(duì)于數(shù)據(jù)存儲(chǔ)區(qū)2還沒(méi)開(kāi)始寫(xiě)入的情況,只需要將數(shù)據(jù)存儲(chǔ)區(qū)2中缺失的數(shù)據(jù)從數(shù)據(jù)存儲(chǔ)區(qū)1讀取再寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)2,再將寫(xiě)指針2更新。當(dāng)需要進(jìn)行數(shù)據(jù)檢索時(shí),過(guò)程如下:6-1)、首先讀取索引表,然后判斷索引表的有效性,索引表無(wú)效則重新初始化索引表;6-2)、判斷數(shù)據(jù)是否發(fā)生了循環(huán)寫(xiě)入,如果發(fā)生了循環(huán)寫(xiě)入,則將數(shù)據(jù)存儲(chǔ)區(qū)分為兩個(gè)區(qū)來(lái)進(jìn)行查找,一個(gè)是寫(xiě)指針前的區(qū)域,還有一個(gè)是寫(xiě)指針之后的區(qū)域,然后轉(zhuǎn)入步驟6-3);如果沒(méi)有發(fā)生循環(huán)寫(xiě)入,則轉(zhuǎn)入步驟6-4)6-3)、對(duì)寫(xiě)指針前的區(qū)域使用二分法查詢第一個(gè)符合檢索條件的數(shù)據(jù)記錄,寫(xiě)入查詢緩沖區(qū),使用二分法可以迅速定位到需要查詢的數(shù)據(jù),然后從第一條記錄往后依次尋找,直至不再符合查詢條件或者查詢緩沖區(qū)滿,檢索結(jié)束;如果在寫(xiě)指針前的區(qū)域沒(méi)有查詢到數(shù)據(jù),則在寫(xiě)指針后的區(qū)域查詢第一個(gè)符合檢索條件的數(shù)據(jù)記錄,寫(xiě)入查詢緩沖區(qū),直至不再符合查詢條件或者查詢緩沖區(qū)滿,檢索結(jié)束;6-4)、對(duì)數(shù)據(jù)存儲(chǔ)區(qū)使用二分法查詢第一個(gè)符合檢索條件的數(shù)據(jù)記錄,寫(xiě)入查詢緩沖區(qū),然后從第一條記錄往后依次尋找,直至不再符合查詢條件或者查詢緩沖區(qū)滿,檢索結(jié)束。當(dāng)需要數(shù)據(jù)刪除時(shí),使用數(shù)據(jù)檢索流程定位需要?jiǎng)h除的數(shù)據(jù),寫(xiě)入該數(shù)據(jù)記錄的無(wú)效標(biāo)記,既可從數(shù)據(jù)庫(kù)刪除數(shù)據(jù)。當(dāng)需要進(jìn)行數(shù)據(jù)更新時(shí),過(guò)程如下:8-1),定位需要更新的數(shù)據(jù)所在的數(shù)據(jù)塊A以及在數(shù)據(jù)塊內(nèi)的偏移地址Offset;8-2),從備用數(shù)據(jù)區(qū)中選取一個(gè)數(shù)據(jù)塊B并進(jìn)行擦除;8-3),將數(shù)據(jù)塊A中從地址0到偏移地址Offset的數(shù)據(jù)寫(xiě)入數(shù)據(jù)塊B;8-4),將數(shù)據(jù)更新后,寫(xiě)入數(shù)據(jù)塊B中偏移地址Offset之后RecordLen長(zhǎng)度數(shù)據(jù);8-5),將數(shù)據(jù)塊A中剩余的數(shù)據(jù)寫(xiě)入數(shù)據(jù)塊B中同樣位置;8-6),將數(shù)據(jù)塊A分配到備用數(shù)據(jù)區(qū),更新數(shù)據(jù)存儲(chǔ)區(qū)映射表與備用數(shù)據(jù)區(qū)映射表。本發(fā)明所達(dá)到的有益效果:1、本發(fā)明提供的NandFlash的分區(qū)方法通過(guò)維護(hù)數(shù)據(jù)存儲(chǔ)區(qū)映射表、壞區(qū)映射表、備用數(shù)據(jù)區(qū)映射表的辦法進(jìn)行,即隔離了NandFlash的壞塊,又實(shí)現(xiàn)了數(shù)據(jù)的冗余存儲(chǔ)。2、本發(fā)明提供的數(shù)據(jù)記錄的數(shù)據(jù)結(jié)構(gòu)可以迅速定位到下一條數(shù)據(jù)記錄,保證數(shù)據(jù)存儲(chǔ)的可靠性,并且對(duì)數(shù)據(jù)的操作可以通過(guò)重寫(xiě)標(biāo)志位的方法進(jìn)行數(shù)據(jù)刪除操作。3、本發(fā)明提供的數(shù)據(jù)記錄的寫(xiě)入時(shí)序,在發(fā)生強(qiáng)干擾或掉電導(dǎo)致系統(tǒng)復(fù)位時(shí)能夠保證索引表不發(fā)生混亂,保證了系統(tǒng)運(yùn)行的穩(wěn)定性。4、本發(fā)明可以廣泛地用于中小型嵌入式系統(tǒng)中需要進(jìn)行數(shù)據(jù)存儲(chǔ)與數(shù)據(jù)檢索的場(chǎng)合,具有訪問(wèn)速度塊,存儲(chǔ)效率高,可靠性好的特點(diǎn),并且無(wú)需文件系統(tǒng)的支持,非常適合中小型嵌入式系統(tǒng)的工業(yè)應(yīng)用。附圖說(shuō)明圖1是NandFlash分區(qū)及映射表;圖2是數(shù)據(jù)寫(xiě)入流程;圖3是數(shù)據(jù)同步流程;圖4是數(shù)據(jù)檢索流程。具體實(shí)施方式下面結(jié)合附圖對(duì)本發(fā)明作進(jìn)一步描述。以下實(shí)施例僅用于更加清楚地說(shuō)明本發(fā)明的技術(shù)方案,而不能以此來(lái)限制本發(fā)明的保護(hù)范圍。本發(fā)明的基于NandFlash的數(shù)據(jù)存儲(chǔ)方法,包括以下幾個(gè)部分:1、設(shè)計(jì)數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)在存儲(chǔ)用戶數(shù)據(jù)時(shí),當(dāng)嵌入式系統(tǒng)遭遇強(qiáng)干擾或掉電時(shí),寫(xiě)入的數(shù)據(jù)會(huì)丟失并導(dǎo)致索引信息被破壞,為提高數(shù)據(jù)存儲(chǔ)的可靠性,設(shè)計(jì)了如下的數(shù)據(jù)結(jié)構(gòu):其中,WritePtr為4字節(jié)的下一條數(shù)據(jù)記錄的寫(xiě)指針,ValidFlag為2字節(jié)的數(shù)據(jù)有效標(biāo)志,UserData為用戶數(shù)據(jù),CRC為2字節(jié)的用戶數(shù)據(jù)的CRC16校驗(yàn)。2、對(duì)Nandflash的壞塊進(jìn)行檢測(cè)2.1先天性壞塊檢測(cè)這種壞塊是在生產(chǎn)過(guò)程中產(chǎn)生的,一般芯片原廠都會(huì)在出廠時(shí)都會(huì)根據(jù)頁(yè)面大小將壞塊第一個(gè)page的sparearea的1~2個(gè)字節(jié)標(biāo)記為不等于0xff的值。調(diào)用擦除程序,將NandFlash全部擦除一遍,然后執(zhí)行如下檢測(cè)操作:如果頁(yè)大于512字節(jié),badblockpos=0;badblockbytes=2;如果頁(yè)小于512字節(jié),badblockpos=5;badblockbytes=1;讀取每個(gè)block的前兩頁(yè)OOB區(qū)域的第badblockpos開(kāi)始的后badblockbytes字節(jié)是否為全0xff,如果是,那么說(shuō)明該block是好的,否則該block是壞塊。2.2后天性壞塊檢測(cè)NandFlash使用過(guò)程中產(chǎn)生的壞塊稱之為后天性壞塊,如果BlockErase或者PageProgram錯(cuò)誤,就可以簡(jiǎn)單地將這個(gè)塊作為壞塊來(lái)處理,這個(gè)時(shí)候需要把壞塊標(biāo)記起來(lái)。為了和先天性壞塊信息保持一致,將新發(fā)現(xiàn)的壞塊的第一個(gè)page的sparearea的前6個(gè)Byte都標(biāo)記為非0xff的值。3、設(shè)計(jì)數(shù)據(jù)存儲(chǔ)映射為保證數(shù)據(jù)的可靠存儲(chǔ),首先檢測(cè)NandFlash的壞塊,建立壞塊映射表,將NandFlash的可用塊劃分為兩個(gè)相同大小的數(shù)據(jù)存儲(chǔ)區(qū)與一個(gè)備用數(shù)據(jù)區(qū),建立兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)映射表與一個(gè)備用數(shù)據(jù)區(qū)映射表,NandFlash分區(qū)及映射表如圖1所示。當(dāng)運(yùn)行時(shí)出現(xiàn)壞塊后,標(biāo)記壞塊,再更新壞區(qū)映射表,然后使用備用數(shù)據(jù)區(qū)的一個(gè)存儲(chǔ)塊替代壞塊,將另一個(gè)數(shù)據(jù)存儲(chǔ)區(qū)相應(yīng)塊的數(shù)據(jù)備份新數(shù)據(jù)塊,然后更新數(shù)據(jù)存儲(chǔ)區(qū)映射表與備用數(shù)據(jù)區(qū)映射表。4、進(jìn)行數(shù)據(jù)存儲(chǔ)首先按照設(shè)置分配每一種數(shù)據(jù)的存儲(chǔ)空間,存儲(chǔ)空間在兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)(定義為數(shù)據(jù)存儲(chǔ)區(qū)1與數(shù)據(jù)存儲(chǔ)區(qū)2)同時(shí)分配,為此每種數(shù)據(jù)配置一條索引表,索引表的數(shù)據(jù)結(jié)構(gòu)如下。索引表的每個(gè)字段的含義如表1所示。表1索引表的字段定義序號(hào)字段含義1InitFlag索引表初始化標(biāo)識(shí)2StartBlock起始?jí)K號(hào)3EndBlock結(jié)束塊號(hào)4BlockSize塊大小5RecordLen一條數(shù)據(jù)記錄大小6DataLength有效數(shù)據(jù)總長(zhǎng)度7WritePtr1寫(xiě)指針18WritePtr2寫(xiě)指針2其中,InitFlag為0x55AA表示索引表已經(jīng)初始化,起始?jí)K號(hào)與結(jié)束塊號(hào)為數(shù)據(jù)存儲(chǔ)區(qū)映射表中的序號(hào),而非Nandflash物理塊的序號(hào),不同的NandFlash芯片對(duì)應(yīng)不同的塊大小BlockSize,因?yàn)閿?shù)據(jù)在兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū)都存儲(chǔ),為防止意外干擾,索引中使用兩個(gè)寫(xiě)指針,當(dāng)出現(xiàn)不匹配進(jìn)行數(shù)據(jù)同步以保證數(shù)據(jù)的雙備份。數(shù)據(jù)記錄的寫(xiě)入流程如圖2所示,首先讀取數(shù)據(jù)索引表,然后判斷索引表的有效性,如果索引表無(wú)效,則進(jìn)行索引表初始化,如果索引表的有效,然后判斷是否數(shù)據(jù)存儲(chǔ)同步;如果是,則判斷數(shù)據(jù)寫(xiě)指針是否為塊首地址,如果為塊首地址則先進(jìn)行擦除,然后先將用戶數(shù)據(jù)及校驗(yàn)寫(xiě)入兩個(gè)緩沖區(qū)。當(dāng)NandFlash進(jìn)行數(shù)據(jù)寫(xiě)入失敗,則標(biāo)記當(dāng)前塊為壞塊,然后更新壞塊映射表,從備用數(shù)據(jù)區(qū)分配一個(gè)緩沖區(qū)到數(shù)據(jù)存儲(chǔ)區(qū),再更新備用數(shù)據(jù)區(qū)映射表與數(shù)據(jù)存儲(chǔ)區(qū)映射表,然后重新寫(xiě)入。在每個(gè)數(shù)據(jù)存儲(chǔ)區(qū)寫(xiě)入成功后更新數(shù)據(jù)索引表的寫(xiě)指針。寫(xiě)入時(shí)序?yàn)橄葘?xiě)數(shù)據(jù)存儲(chǔ)區(qū)1,然后更新寫(xiě)指針1,再數(shù)據(jù)存儲(chǔ)區(qū)2,最后更新寫(xiě)指針2,這樣的寫(xiě)入時(shí)序可以保證遇強(qiáng)干擾或掉電時(shí),數(shù)據(jù)索引與數(shù)據(jù)記錄能夠自動(dòng)按照流程進(jìn)行追溯并自動(dòng)恢復(fù)。為了避免數(shù)據(jù)無(wú)限制膨脹,對(duì)數(shù)據(jù)的總長(zhǎng)度進(jìn)行了限制,當(dāng)存儲(chǔ)的數(shù)據(jù)達(dá)到設(shè)定的長(zhǎng)度時(shí),則進(jìn)行循環(huán)寫(xiě)入,將最早的數(shù)據(jù)覆蓋。5、同步存儲(chǔ)數(shù)據(jù)數(shù)據(jù)存儲(chǔ)在兩個(gè)數(shù)據(jù)存儲(chǔ)區(qū),必須保證數(shù)據(jù)在兩個(gè)位置同時(shí)保存正確才能避免一個(gè)數(shù)據(jù)塊損壞的情況下數(shù)據(jù)丟失,在遇到異常情況如掉電、雷擊時(shí),存儲(chǔ)的數(shù)據(jù)將會(huì)出現(xiàn)不同步,具體體現(xiàn)在寫(xiě)指針1與寫(xiě)指針2的不一致。此時(shí)需要進(jìn)行數(shù)據(jù)同步,同步的具體流程圖如圖3所示。寫(xiě)指針1與寫(xiě)指針2一致時(shí),存在極端情形,就是數(shù)據(jù)存儲(chǔ)區(qū)1的數(shù)據(jù)已經(jīng)寫(xiě)入了而寫(xiě)指針1沒(méi)有寫(xiě)入,這時(shí)可以讀取寫(xiě)指針1開(kāi)始的RecordLen長(zhǎng)度數(shù)據(jù),判斷數(shù)據(jù)的有效性,數(shù)據(jù)有效則更新寫(xiě)指針1,再將數(shù)據(jù)寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)2,更新寫(xiě)指針2。寫(xiě)指針1與寫(xiě)指針2不一致時(shí),由于存儲(chǔ)數(shù)據(jù)都是先寫(xiě)數(shù)據(jù)存儲(chǔ)區(qū)1,再寫(xiě)數(shù)據(jù)存儲(chǔ)區(qū)2,必然是寫(xiě)數(shù)據(jù)存儲(chǔ)區(qū)2的過(guò)程中發(fā)生了中斷,有可能是數(shù)據(jù)存儲(chǔ)了而寫(xiě)指針2未更新,還有就是數(shù)據(jù)存儲(chǔ)區(qū)2還沒(méi)開(kāi)始寫(xiě)入。對(duì)于前者,處理流程與數(shù)據(jù)存儲(chǔ)區(qū)1的極端情形一樣,即判斷數(shù)據(jù)的有效性,數(shù)據(jù)有效則更新寫(xiě)指針2,再將數(shù)據(jù)寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)2。對(duì)于后者,只需要將數(shù)據(jù)存儲(chǔ)區(qū)2中缺失的數(shù)據(jù)從數(shù)據(jù)存儲(chǔ)區(qū)1讀取再寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)2,再將寫(xiě)指針2更新。6、進(jìn)行數(shù)據(jù)檢索在工業(yè)應(yīng)用場(chǎng)合,數(shù)據(jù)的寫(xiě)入是以時(shí)間為順序的,數(shù)據(jù)的檢索同樣是以時(shí)間為順序的,為方便數(shù)據(jù)檢索,每條數(shù)據(jù)均編列了時(shí)標(biāo),數(shù)據(jù)檢索的流程如圖4所示。6-1、首先讀取索引表,然后判斷索引表的有效性,索引表無(wú)效的需要重新初始化索引表。6-2、判斷數(shù)據(jù)是否發(fā)生了循環(huán)寫(xiě)入,如果發(fā)生了循環(huán)寫(xiě)入,則將數(shù)據(jù)存儲(chǔ)區(qū)分為兩個(gè)區(qū)來(lái)進(jìn)行查找,一個(gè)是寫(xiě)指針前的區(qū)域,還有一個(gè)是寫(xiě)指針之后的區(qū)域,然后轉(zhuǎn)入步驟6-3);如果沒(méi)有發(fā)生循環(huán)寫(xiě)入,則,轉(zhuǎn)入步驟6-4)6-3、對(duì)寫(xiě)指針前的區(qū)域使用二分法查詢第一個(gè)符合檢索條件的數(shù)據(jù)記錄,寫(xiě)入查詢緩沖區(qū),使用二分法可以迅速定位到需要查詢的數(shù)據(jù),然后從第一條記錄往后依次尋找,直至不再符合查詢條件或者查詢緩沖區(qū)滿,檢索結(jié)束。如果在寫(xiě)指針前的區(qū)域沒(méi)有查詢到數(shù)據(jù),則在寫(xiě)指針后的區(qū)域查詢第一個(gè)符合檢索條件的數(shù)據(jù)記錄,寫(xiě)入查詢緩沖區(qū),直至不再符合查詢條件或者查詢緩沖區(qū)滿,檢索結(jié)束。6-4)、對(duì)數(shù)據(jù)存儲(chǔ)區(qū)使用二分法查詢第一個(gè)符合檢索條件的數(shù)據(jù)記錄,寫(xiě)入查詢緩沖區(qū),然后從第一條記錄往后依次尋找,直至不再符合查詢條件或者查詢緩沖區(qū)滿,檢索結(jié)束。7、對(duì)數(shù)據(jù)進(jìn)行刪除數(shù)據(jù)記錄的刪除方法如下:使用數(shù)據(jù)檢索流程定位需要?jiǎng)h除的數(shù)據(jù),寫(xiě)入該數(shù)據(jù)記錄的無(wú)效標(biāo)記,既可達(dá)到從數(shù)據(jù)庫(kù)刪除的目的。8、數(shù)據(jù)記錄的更新當(dāng)需要對(duì)某一條數(shù)據(jù)記錄進(jìn)行更新時(shí),由于NandFlash的扇區(qū)必須擦除后才能再次寫(xiě)入,而擦除操作必須是對(duì)NandFlash的一個(gè)快,由于設(shè)計(jì)了備用數(shù)據(jù)區(qū),可以使用備用數(shù)據(jù)區(qū)的一個(gè)塊來(lái)進(jìn)行中轉(zhuǎn),具體的數(shù)據(jù)更新記錄流程如下:第一步,定位需要更新的數(shù)據(jù)所在的數(shù)據(jù)塊A以及在數(shù)據(jù)塊內(nèi)的偏移地址Offset;第二步,從備用數(shù)據(jù)區(qū)中選取一個(gè)數(shù)據(jù)塊B并進(jìn)行擦除;第三步,將數(shù)據(jù)塊A中從地址0到偏移地址Offset的數(shù)據(jù)寫(xiě)入數(shù)據(jù)塊B;第四步,將數(shù)據(jù)更新后,寫(xiě)入數(shù)據(jù)塊B中偏移地址Offset之后RecordLen長(zhǎng)度數(shù)據(jù);第五步,將數(shù)據(jù)塊A中剩余的數(shù)據(jù)寫(xiě)入數(shù)據(jù)塊B中同樣位置;第六步,將數(shù)據(jù)塊A分配到備用數(shù)據(jù)區(qū),更新數(shù)據(jù)存儲(chǔ)區(qū)映射表與備用數(shù)據(jù)區(qū)映射表。以上所述僅是本發(fā)明的優(yōu)選實(shí)施方式,應(yīng)當(dāng)指出,對(duì)于本
技術(shù)領(lǐng)域:
的普通技術(shù)人員來(lái)說(shuō),在不脫離本發(fā)明技術(shù)原理的前提下,還可以做出若干改進(jìn)和變形,這些改進(jìn)和變形也應(yīng)視為本發(fā)明的保護(hù)范圍。當(dāng)前第1頁(yè)1 2 3