STM32F103C8T6 en tant que lecteur flash avec système de fichiers FAT12

Lors du développement de périphériques, il est souvent nécessaire de stocker les paramètres en dehors du programme de travail. Il est encore préférable de pouvoir les modifier sans utiliser d'outils spéciaux.

Envisagez l'option de stockage dans les microcontrôleurs STM F103 les plus courants. La planche à pain bien connue Blue Pill a également contribué à la prévalence.

image
Le flash qui y est disponible permet non seulement de stocker et de modifier les paramètres à l'aide du système de fichiers FAT12 dans le flash interne, mais également d'organiser une mise à jour du firmware.

Selon la documentation, le STM32F103C8T6 possède une mémoire flash de 64 Ko. Cependant, dans presque tous les STM32F103C8T6, 128 Ko est installé. Cela est également mentionné dans diverses sources - ils mettent généralement 64 Ko de plus. Cette "fonctionnalité" vous permet d'utiliser le microcontrôleur comme un lecteur flash d'une capacité de 128K - 20K (le système a besoin de FAT12) - la taille du firmware.

De nombreux amateurs qui ont essayé d'utiliser ce contrôleur comme lecteur flash ont rencontré le problème de son utilisation en mode système de fichiers FAT12. Utilisez pour supprimer / remplir l'image disque avérée. Mais lorsque vous travaillez avec un lecteur de fichiers, les problèmes ont commencé.

Ce problème consiste en une séquence d'accès différente aux secteurs (blocs). Lorsqu'une image disque est chargée, l'enregistrement se produit séquentiellement, par exemple:

-enregistrement du numéro de bloc 1,
-enregistrement du numéro de bloc 2,
-enregistrer le numéro de bloc 3.

Lors de l'écriture de données FAT12, l'enregistrement peut se produire arbitrairement:

-enregistrer le numéro de bloc 3,
-enregistrement du numéro de bloc 1,
-enregistrer le numéro de bloc 2.

Et, comme l'écriture sur Flash nécessite l'effacement de la page entière de 1 Ko, lorsque vous utilisez des secteurs de 512 octets dans le lecteur (et vous ne pouvez pas utiliser d'autres secteurs), si l'accès aléatoire est utilisé, les informations du secteur voisin sont effacées. Pour éviter cela, l'exemple ci-dessus utilise un tableau de 512 octets pour stocker le secteur voisin. Et l'enregistrement devrait être le suivant:

- déterminer l'adresse du début de la page,
- souvenez-vous du secteur voisin,
- effacer la page,
- écrire un secteur mémorisé,
- écrire des données.

Afin de ne pas plonger dans la jungle de fer sans le besoin requis, j'ai préparé le projet dans CubeMX.

Je vais donner un exemple de fonction pour écrire sur flash via HAL (usbd_storage_if.c)

//    flash void writeBuf (uint32_t page_addr, uint8_t *buf){ uint32_t erase_addr=get_erase_addr(page_addr); uint32_t buf_erase_addr; uint32_t buf32; if (page_addr != erase_addr) { buf_erase_addr=erase_addr; } else { buf_erase_addr=erase_addr+STORAGE_BLK_SIZ; } HAL_FLASH_Unlock(); //      set_buf_before_erase(buf_erase_addr); //       FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PAGEError = 0; EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = erase_addr; EraseInitStruct.NbPages = 1; HAL_FLASHEx_Erase(&EraseInitStruct,&PAGEError); //    for (int i=0; i<STORAGE_BLK_SIZ/4;i++) { HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,buf_erase_addr,blk_buff[i]); buf_erase_addr+=4; } //   for (int i=0; i<STORAGE_BLK_SIZ/4;i++) { buf32=*(uint32_t *)&buf[i*4]; HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, page_addr,buf32); page_addr+=4; } HAL_FLASH_Lock(); } 

La taille du fichier binaire que j'ai eu environ 20K, donc ma page de mémoire de données est définie avec 0x08006000 (24K).

Nous compilons (le code source de l'exemple peut être pris ici).

Nous connectons:

 [ 8193.499792] sd 4:0:0:0: Attached scsi generic sg2 type 0 [ 8193.502050] sd 4:0:0:0: [sdb] 128 512-byte logical blocks: (65.5 kB/64.0 KiB) [ 8193.502719] sd 4:0:0:0: [sdb] Write Protect is off [ 8193.502722] sd 4:0:0:0: [sdb] Mode Sense: 00 00 00 00 [ 8193.503439] sd 4:0:0:0: [sdb] Asking for cache data failed [ 8193.503445] sd 4:0:0:0: [sdb] Assuming drive cache: write through [ 8193.523812] sdb: [ 8193.526914] sd 4:0:0:0: [sdb] Attached SCSI removable disk 

Le disque est déterminé, tout va bien!

Commençons à former la partition et à formater notre disque.

Sous Linux, c'est assez simple depuis la ligne de commande:

 sudo fdisk /dev/sdb 



format en FAT12:

 sudo mkfs.fat /dev/sdb -F 12 

Copiez le fichier pour le test:



Cependant, il ne faut pas oublier que selon la documentation, le nombre de cycles de réécriture flash
garanti uniquement dans les 100 000. Par exemple, le formatage et l'écriture d'un seul fichier de 30 Ko prendront (selon le journal de débogage de cet exemple):

 00106 44 67 Write_FS blk_addr=003 0x08006600 

106 cycles de réécriture.

La question demeure - comment puis-je lire des données en accédant directement aux fichiers FAT12?
À ce sujet dans le prochain article.
Merci de votre attention!

Source: https://habr.com/ru/post/fr441660/


All Articles