Système de fichier en mémoire FLASH
Instructions
Utilisation
Exemple
Principe
La gestion d'un système de fichiers en mémoire
FLASH impose des contraintes plus sévères que celle
d'un système de fichiers dans un disque dur. Bien que les
mémoires FLASH ne possèdent pas de rouages mécaniques,
elles sont tout de même limitées en nombre d'écriture.
Ce nombre est en général garanti à 100000
minimum par les constructeurs. Si le disque dur est lui aussi
limité en nombre d'écritures, il est en général
facilement remplaçable dans un système alors que
les mémoires FLASH sont souvent soudées sur la même
carte que le processeur. Il est donc nécessaire d'optimiser
son utilisation afin d'obtenir le maximum de durée de vie
pour l'ensemble du système.
J'ai donc choisi d'implémenter un algorithme permettan
d'utiliser la mémoire FLASH comme une sorte de rouleau
de telle sorte qu'une nouvelle écriture se fasse toujours
dans une nouvelle zone de la mémoire en recommençan
au début de celle-ci lorsqu'elle est saturée (un
peu comme une pile de type premier entré/premier sorti
ou FIFO). Si la mémoire FLASH est réécrite
100000 fois, ce sera sur toute sa surface. Ceci implique la gestion
d'un index déplacé à chaque nouvelle écriture
de fichier. De plus, il faut ajouter une gestion d'effacemen
automatique des secteurs les plus anciens qui, pour compliquer
le tout, ont une taille supérieure (64 Kilo Octets pour
les mémoires FLASH associéees au coeur FORTH) par
rapport à la taille d'un bloc unitaire (512 octets).
Je ne vais pas trop m'étaler sur les détails
du principe que j'utilise mais il introduit un inconvénien
qui implique que s'il est toujours possible de lire plusieurs
fichiers simultannément, seul un fichier peut être
écrit à la fois. Mais l'écriture de plusieurs
fichiers peut être émulée à l'aide
du noyau temps réel et de l'allocation dynamique de la
mémoire vive.
Instructions
Voici l'ensemble des instructions FORTH nécessaires
à la gestion de la mémoire FLASH. Les premières
sont réservées au système, les dernières
sont optimisées pour les utilisateurs.
- FLASH_ORIGINE adresse
Constante donnant l'adresse de débu
de la zone de mémoire FLASH contenant le système
de fichiers
- MEMOIRE_FLASH adresse
Variable donnant l'adresse du contenu du
bloc initial en mémoire vive
- FICHIER_CHEMIN adresse
Variable donnant l'adresse de la chaine de
caractères contenant chemin courant en mémoire vive
- FLASH_OCCUPE adresse
Variable contenant l'état d'occupation
de la mémoire FLASH
- FLASH_ECRITURE adresse
Variable indiquant si un fichier est en cours
d'écriture
num_bloc,adr FLASH_BLOC_LIT erreur
Lecture du bloc de 512 octets numéro
num_bloc à l'adresse adr.
erreur est nul lorsque la lecture est correcte
adr,num_bloc FLASH_BLOC_ECRIT erreur
Ecriture du bloc de 512 octets numéro
num_bloc à partir de l'adresse adr.
erreur est nul lorsque l'écriture est correcte
num_sec FLASH_SECTEUR_EFFACE erreur
Effacement du secteur de 64 Kilo Octets numéro
num_sec.
erreur est nul lorsque l'effacement est correct
- FLASH_BLOC_ALLOUE numéro/erreur
Réquisition d'un bloc de 512 octets.
Si le numéro est nul, c'est qu'il n'y a plus de bloc disponible.
Si le numéro est négatif, il s'agit d'un code d'erreur
numéro FLASH_BLOC_LIBERE -
Restitution d'un bloc de 512 octets avec
son numéro.
numéro FLASH_BLOC_ETAT état
Retourne 0 si le bloc numéro est libre.
- FLASH_FORMATE -
Formatage du système de fichier en
mémoire FLASH
- FLASH_INSTALLE erreur
Installation du système de fichier
en mémoire FLASH.
erreur est nul si correcte, sinon:
-30 si le système de fichier est indéchiffrable
-31 si la mémoire est insuffisante pour formater
-32 si la mémoire est insuffisante pour l'installation
- BINAIRE_INDEX adresse
Variable contenant l'adresse de chargemen
du fichier "LANCE.BIN"
- S_BINAIRE adresse
Chaine de caractere contenant "./BINAIRES/LANCE.BIN"
- BINAIRE_CREE -
Création du fichier "LANCE.BIN"
- BINAIRE_CHARGE -
Chargement du fichier "LANCE.BIN"
- S_LANCE adresse
Chaine de caractere contenant "./LANCE"
- LANCE -
Chargement du fichier "LANCE" pour
démarrage du système
Comme déjà annoncé précédemment,
les instructions suivantes sont destinées aux utilisateurs.
adr_chemin/nom,lec/ecr FLASH_FICHIER_OUVRE
adr_tampon,taille/erreur
Ouverture d'un fichier décrit par
la chaîne de caractères adr_chemin/nom en écriture
si lec/ecr est nul sinon en lecture.
adr_tampon est l'adresse du descripteur du fichier ouvert.
taille/erreur peut avoir les valeur suivantes:
taille du fichier si ouverture en lecture correcte (0 si le fichier
n'existe pas)
0 ou taille du fichier déjà existant si ouverture
en écriture correcte
-40 si il est impossible de lire un bloc
-41 si la mémoire est insuffisante pour réaliser
l'ouverture
-42 si le chemin du fichier est inconnu
-43 si une écriture de fichier est déjà en
cours alors qu'une écriture est demandée
-44 si le fichier ouvert est un répertoire
adr_tampon FLASH_FICHIER_LIT taille/erreur,octet
Lecture séquentielle d'un octet du
fichier ouvert avec adr_tampon.
taille/erreur peut avoir les valeur suivantes:
taille restante du fichier si lecture correcte (>=0)
-1 si une erreur est survenue pendant la lecture
-2 si adr_tampon ne correspond à aucun fichier en cours
de lecture
octet,adr_tampon FLASH_FICHIER_ECRIT taille/erreur
Ecriture séquentielle d'un octet dans
le fichier ouvert avec adr_tampon.
taille/erreur peut avoir les valeur suivantes:
>0 si écriture correcte, la valeur étant le nombre
d'octets écrits (taille)
-10 si une erreur est survenue pendant l'écriture
-11 si le système de fichier est saturé
-12 si adr_tampon ne correspond à aucun fichier en cours
d'écriture
adr_tampon FLASH_FICHIER_FERME erreur
Fermeture du fichier ouvert avec adr_tampon.
erreur peut avoir les valeur suivantes:
0 si fermeture correcte
code de l'erreur survenue pendant les opérations précédantes
-20 si une erreur est survenue pendant l'écriture
-21 si le système de fichier est saturé
-22 si adr_tampon ne correspond à aucun fichier en cours
d'utilisation
- FICHIER_CHEMIN? adresse
Alloue de la mémoire pointée
par adresse et contenant une chaine de caractères avec
le chemin courant.
La mémoire allouée devra être restituée
(MEMOIRE_LIBERE) après utilisation.
Retourne 0 s'il ny a plus de mémoire disponible ou que
le système de fichier n'est pas fonctionnel
adr_nom,nbc CHEMIN_CONCATENE adr_mem
Alloue de la mémoire pointée
par adr_mem et contenant la chaîne de caractère résultante
de la concaténation du chemin courant et de la chaîne
pointée par adr_nom de longueur nbc.
La mémoire allouée devra être restituée
(MEMOIRE_LIBERE) après utilisation.
Retourne 0 s'il ny a plus de mémoire disponible ou que
le système de fichier n'est pas fonctionnel
adr_nom REPERTOIRE_LISTER adr_mem,erreur
Alloue de la mémoire qui contiendra
la description du répertoire pointé par la chaîne
de caractères adr_nom.
adr_mem, si différent de 0 et erreur nul, pointe la séquence
suivante:
nombre de fichiers/dossiers sur 4 octets
taille du fichier/dossier 1 sur 4 octets
type fichier (1), dossier (2) ou inconnu (0) 1 sur 4 octets
numéro de création du fichier/dossier 1 sur 4 octets
nombre de modifications du fichier/dossier 1 sur 4 octets
Chaîne de caractère avec nom du dossier/fichier 1
sur n*4 octets
taille du fichier/dossier 2 sur 4 octets
...
Chaîne de caractère avec nom du dernier dossier/fichier
sur n*4 octets
0 pour fin de la liste sur 4 octets
La mémoire allouée devra être restituée
(MEMOIRE_LIBERE) après utilisation.
adr_nom,nbc,adr_mem,taille_max FICHIER_LIRE
erreur
Lecture d'un fichier à l'adresse adr_mem
sur une taille maximale taille_max et dont le chemin/nom est pointé
par la chaîne de caractères adr_nom de longueur nbc.
erreur est nul si tout s'est bien déroulé
adr_mem,taille,adr_nom,nbc FICHIER_ECRIRE
erreur
Ecriture d'un fichier à partir de
l'adresse adr_mem sur une longueur taille et dont le chemin/nom
est pointé par la chaîne de caractères adr_nom
de longueur nbc.
erreur est nul si tout s'est bien déroulé
- PWD -
Commande affichant les caractéristiques
du système de fichier et le chemin courant
- CD"
chemin" -
Commande permettant de se déplacer
dans les système de fichier
- LS" chemin" -
Affichage du contenu du répertoire
"chemin"
- MKDIR" chemin/nom"
-
Création du répertoire "chemin/nom"
- RM" chemin/nom"
-
Suppression du fichier "chemin/nom"
- RMDIR" chemin/nom"
-
Suppression du répertoire "chemin/nom"
- MORE" chemin/nom"
-
Affichage sur l'écran du fichier de
texte "chemin/nom"
- CF" chemin/nom"
-
Compilation du fichier source FORTH "chemin/nom"
- CP" chemin1/nom1 chemin2/nom2"
-
Copie de fichier
- MV" chemin1/nom1 chemin2/nom2"
-
Déplacement de fichier
- XMODEM_RECOIT" chemin/nom"
-
Réception du fichier "chemin/nom"
sous protocole XMODEM
- XMODEM_EMET" chemin/nom"
-
Transmission du fichier "chemin/nom"
sous protocole XMODEM
Utilisation
L'écriture ou la lecture d'un
fichier nécessite l'utilisation des instructions suivantes:
- FLASH_FICHIER_OUVRE,
- FLASH_FICHIER_LIT ou FLASH_FICHIER_ECRIT,
- FLASH_FICHIER_FERME.
L'utilisateur se contente donc de passer le nom du fichier
juste avant l'instruction FLASH_FICHIER_OUVRE qui créera
alors un descripteur en mémoire vive dont le pointeur devra
être conservé par l'utilisateur. Ce descripteur sera
utilisé jusqu'à la fin de l'exécution de
l'instruction FLASH_FICHIER_FERME qui restituera la mémoire
vive correspondante.
L'instruction FLASH_FICHIER_FERME doit impérativemen
être exécutée à la fin d'une opération
sur un fichier. Dans le cas d'une lecture, la mémoire vive
du descripteur sera automatiquement restituée au système.
De plus, en écriture, le bloc initial sera mis à
jour permettant d'utiliser correctement le nouveau fichier.
La seule façon de créer un répertoire
est d'utiliser l'instruction MKDIR". Pour en supprimer un,
il faut utiliser l'instruction RMDIR" mais celle-ci refusera
d'effacer un répertoire non vide.
Exemple
Pour illustrer cette page, voici le
code de l'instruction de copie de fichier CP":
: CP"
32 WORD COUNT CHEMIN_CONCATENE ?DUP
IF
DUP >R -1 FLASH_FICHIER_OUVRE R> MEMOIRE_LIBERE DROP DUP 0>
IF
34 WORD COUNT CHEMIN_CONCATENE ?DUP
IF
DUP >R 0 FLASH_FICHIER_OUVRE R> MEMOIRE_LIBERE DROP 0<
IF
SWAP DROP
ELSE
SWAP 0 DO
OVER FLASH_FICHIER_LIT 3 PICK FLASH_FICHIER_ECRIT >R 0< R> 0< OR
IF
LEAVE
THEN
LOOP
THEN
FLASH_FICHIER_FERME
IF
." **** Probleme d'ECRITURE !" CR
THEN
ELSE
DROP
THEN
FLASH_FICHIER_FERME DROP
ELSE
." **** Fichier INEXISTANT !" CR
DROP MEMOIRE_LIBERE DROP
THEN
THEN
;