Algoritmo di registro circolare leggero (simile al filesystem) per l'archiviazione basata su flash


8

Attualmente sto lavorando a un progetto che prevede una registrazione rapida e continua di una metrica piuttosto specifica per l'applicazione nel corso di una lunga vita. Per fare ciò ho finito per usare un NXP M0 e un chip flash SPI 32MiB. La registrazione è continua e deve durare molti anni sul campo (10+), ed è periodicamente controllata da un essere umano per individuare le tendenze. Alla fine il buffer si riempie e inizia a sovrascrivere i vecchi dati, il che è perfettamente a posto. Mi è venuto in mente un semplice algoritmo per guidare l'intero dispositivo flash per trovare la testina corrente dopo l'accensione (il dispositivo si spegne piuttosto frequentemente al di fuori del mio controllo) in modo che la registrazione possa continuare da dove era stata interrotta. Posso solo forzare la forza attraverso questa camminata e farlo con ~ 4s come scenario peggiore.

Questo mi ha fatto pensare, ci sono dei filesystem strutturati in log adatti a dispositivi flash e microcontrollori? JFFS e tutti gli altri FS ben strutturati Log immaginati sarebbero un po 'pesanti per un semplice microcontrollore (dipende ovviamente dall'applicazione). Per essere più specifici, vorrei conoscere eventuali algoritmi progettati per essere specificamente un registro circolare con tempo di ricerca rapido della testa e / o qualsiasi altro progettato per un filesystem "tradizionale" su un dispositivo flash che può essere eseguito su un microcontrollore. Tradizionale in questo senso essere alla pari con qualcosa come JFFS in cui esiste una struttura di dati che rappresenta una raccolta di file mutabili ad accesso casuale in uno spazio dei nomi gerarchico.


FAT32 o FAT16 su una scheda SD sono troppo lenti?
Vicatcu,

2
Questa domanda è interamente in argomento qui, ma se non ottieni grandi risposte StackOverflow può probabilmente aiutarti. Speriamo che possiamo ottenere alcune buone risposte qui!
Kellenjb,

@vicatcu Non è che sia troppo lento, per la mia applicazione il connettore SD card plus è più costoso e le schede SD possono essere meno affidabili. Kellenjb Non ero sicuro di dove metterlo. Come molte domande sul design incorporato, questo tipo di problemi cade nel mezzo. Se qui non va bene lo sposterei volentieri.
Kris Bahnsen,

È un chip flash grezzo? In tal caso, come gestite i blocchi morti? Una parte considerevole dell'implementazione flash di FS riguarda blocchi morti. Se ritieni che JFFS / JFFS2 sia troppo pesante, potresti provare YAFFS. Sembra almeno un file system molto semplice, quindi dovrebbe essere abbastanza leggero.
Leone

Sì. I blocchi danneggiati non sono terribili in questa particolare applicazione poiché sono così a lungo termine che i dati estratti sono solo una tendenza approssimativa, e nella maggior parte dei casi dubito che la registrazione verrà utilizzata affatto.
Kris Bahnsen,

Risposte:


2

struttura dei dati della fune

Sono affascinato dalla struttura dei dati della fune . Ho un progetto hobby che cerca di adattarlo a un microcontrollore con solo pochi byte di RAM agganciati a un'enorme memoria Flash, in modo da poter inserire ed eliminare e altrimenti modificare arbitrariamente testo a lunghezza variabile in enormi file di testo. File di testo troppo grandi per adattarsi alla RAM. Cancellare l'ultima metà del file e riscriverlo in flash, spostato di un byte, ogni volta che inserisco o cancello un carattere nel mezzo di un file di testo multi-megabyte, sarebbe troppo lento, ma la struttura dei dati della corda può farlo molto più velocemente. Poiché la struttura dei dati della fune può rappresentare file di lunghezza variabile ad accesso casuale mutevoli come pezzi immutabili di lunghezza fissa, sembra essere una buona corrispondenza per la memoria flash: tutte le modifiche sono scritte in modo circolare. Purtroppo, tutti i bug non sono ancora stati risolti nel mio codice. :-(

tronchi cronologici a lunghezza fissa

Ho avuto un sistema di registro circolare simile funzionante, per un prodotto che ho aiutato a sviluppare.

Ho semplicemente scritto dischi a lunghezza fissa uno dopo l'altro, riempiendo il flash come un array circolare.

(Con un flash completamente vuoto, ho iniziato a scrivere record a circa 3 blocchi prima della fine dell'array, in modo da poter testare l'avvolgimento circolare dopo che erano stati memorizzati solo pochi record di dati, anziché iniziare dal record zero e attendere un mese di dati da scrivere prima di scoprire che c'era un bug nel mio codice avvolgente).

Mi sono assicurato che c'erano sempre almeno 2 "cancelli blocchi" cancellati pronti per essere scritti. Dopo aver scritto un record, se dopo che c'erano solo 2 "blocchi cancellati" che erano vuoti, ho incondizionatamente cancellato il blocco di dati più vecchio, il terzo blocco di dati più vecchi dopo i 2 "blocchi cancellati". (Verso la fine della memoria flash, "dopo" significa "avvolgere all'inizio della memoria flash). (Forse un singolo blocco cancellato sarebbe stato adeguato - Dimentico perché pensavo di aver bisogno di almeno 2 e talvolta 3) .

Dimentico esattamente quanti record ho inserito in ogni "blocco di cancellazione", ma mi sono assicurato di non avere mai un record a cavallo di due blocchi di cancellazione - i primi 2 byte di ogni blocco di cancellazione del flash erano il valore "cancellato" 0xFFFF, oppure i primi due byte di un checksum Fletcher-16 (che non è mai 0xFFFF) nell'intestazione di ciascun record.

Ciò ha reso veloce la scansione la volta successiva che si è accesa e ha trovato la testa del registro circolare: ho dovuto solo guardare i primi due byte di ciascun blocco di cancellazione per distinguere tra blocchi "cancellati" e "dati". (Ero un po 'preoccupato per "interruzione di corrente nel mezzo della cancellazione di un blocco" causando la cancellazione dei primi due byte a 0xFFFF ma lasciando byte non cancellati nel mezzo del blocco, quindi ho scritto il codice per il controllo del microcontrollore per questo e riavviare il processo "cancella un blocco").

Per favore, dimmi se trovi altre strutture di dati o file system compatibili con Flash.


Il tuo approccio sembra in qualche modo simile al mio. Suggerirei di aggiungere un'altra leggera svolta, però: riservare un paio di byte in ciascun blocco per indicare che è stato "avviato" e che è "pieno". Tutti i blocchi tranne i blocchi cancellati devono avere i bit "avviati" programmati. Quando è il momento di cancellare un blocco, imposta il byte "completo" sull'ultimo byte di dati, quindi cancella il blocco, quindi imposta immediatamente il bit "avviato" del blocco cancellato più vecchio. All'avvio, se vedi che "l'ultimo" blocco è "pieno", anziché "avviato", ripeti la cancellazione.
supercat

Un tale approccio può sembrare eccessivo, ma se un blocco flash viene parzialmente cancellato, è possibile che i byte decidano arbitrariamente di leggere FF o qualcos'altro. Il fatto che un blocco appaia vuoto non garantisce che i bit "spontaneamente" non appaiano lì. Se si perde energia mentre è in corso una cancellazione, attendere un po 'all'avvio successivo e quindi ripetere la cancellazione anche se il blocco appare vuoto .
supercat

Grazie per le informazioni, esaminerò un po 'più a fondo quando in realtà premo il codice per l'archiviazione flash e ti faccio sapere cosa succede.
Kris Bahnsen,

@supercat: Grazie, sembra un'ottima idea.
David

@davidcary: Non so di aver mai avuto un blocco che sembrava totalmente vuoto e non lo era, ma ho avuto un blocco che avrebbe prodotto risultati diversi su letture consecutive. È possibile che il blocco sia stato erroneamente letto come vuoto, il mio codice ha comunque tentato di programmarlo, causando una strana mistura di nuovi dati programmati e di vecchie immondizie interrotte. In ogni caso, uno scenario in cui un blocco a volte appare vuoto non è quasi irrealistico.
supercat

0

It's been quite a few years but I wanted to follow up on this in case anyone else wandered by. It looks like there are a few projects these days, which are actively maintained (as of Jan 2020) that are filesystems intended for microcontrollers targetted at NOR SPI flash.

Note that I've not tested these in any capacity, but they do exactly what the original question was looking for: "...data structure that represents a collection of mutable random-access files..."

https://github.com/ARMmbed/littlefs - Created by ARM, BSD licensed

https://github.com/joembedded/JesFs - Doesn't really appear to be licensed, but was very specifically designed for SPI NOR flash.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.