Bei der Entwicklung von Geräten ist es häufig erforderlich, Einstellungen außerhalb des Arbeitsprogramms zu speichern. Es ist sogar noch besser, sie ohne Verwendung von Spezialwerkzeugen ändern zu können.
Erwägen Sie die Möglichkeit der Speicherung in den vielleicht gängigsten STM F103-Mikrocontrollern. Das bekannte Blue Pill Steckbrett trug ebenfalls zur Verbreitung bei.

Der darin verfügbare Flash ermöglicht nicht nur das Speichern und Ändern der Einstellungen mithilfe des FAT12-Dateisystems im internen Flash, sondern auch das Organisieren eines Firmware-Updates.
Laut Dokumentation verfügt der STM32F103C8T6 über einen 64K-Flash-Speicher. In fast allen STM32F103C8T6 sind jedoch 128 KB installiert. Dies wird auch in verschiedenen Quellen erwähnt - sie setzen normalerweise 64K mehr. Mit dieser "Funktion" können Sie den Mikrocontroller als Flash-Laufwerk mit einer Kapazität von 128K - 20K (System benötigt FAT12) - der Größe der Firmware - verwenden.
Viele Enthusiasten, die versuchten, diesen Controller als Flash-Laufwerk zu verwenden, stießen auf das Problem seiner Verwendung im FAT12-Dateisystemmodus. Verwenden Sie diese Option, um das festgestellte Disk-Image zu entfernen / zu füllen. Bei der Arbeit mit einem Dateilaufwerk traten jedoch Probleme auf.
Dieses Problem besteht in einer anderen Reihenfolge des Zugriffs auf Sektoren (Blöcke). Wenn ein Disk-Image geladen wird, erfolgt die Aufzeichnung nacheinander, zum Beispiel:
-aufzeichnungsblock Nummer 1,
-aufzeichnungsblock Nummer 2,
-Aufzeichnungsblock Nummer 3.
Beim Schreiben von FAT12-Daten kann die Aufzeichnung beliebig erfolgen:
-Aufzeichnungsblock Nummer 3,
-aufzeichnungsblock Nummer 1,
-Aufzeichnungsblock Nummer 2.
Und da das Schreiben in Flash das Löschen der gesamten 1K-Seite erfordert, werden bei Verwendung von Sektoren mit 512 Bytes im Laufwerk (und Sie können keine anderen Sektoren verwenden) bei Verwendung des Direktzugriffs Informationen im benachbarten Sektor gelöscht. Um dies zu verhindern, verwendet das obige Beispiel ein Array von 512 Bytes, um den benachbarten Sektor zu speichern. Und die Aufnahme sollte wie folgt sein:
- Bestimmen Sie die Adresse am Anfang der Seite,
- Erinnern Sie sich an den benachbarten Sektor,
- Seite löschen,
- einen gespeicherten Sektor schreiben,
- Daten schreiben.
Um nicht ohne die erforderliche Notwendigkeit in den Dschungel des Eisens einzutauchen, habe ich das Projekt in CubeMX vorbereitet.
Ich werde ein Beispiel für eine Funktion zum Schreiben in Flash über HAL geben (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(); }
Die Größe der Binärdatei, die ich erhalten habe, beträgt ungefähr 20 KB, daher ist meine Datenspeicherseite mit 0x08006000 (24 KB) definiert.
Wir kompilieren (der Quellcode des Beispiels kann hier genommen werden).Wir verbinden:
[ 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
Die Scheibe ist bestimmt, alles ist in Ordnung!
Beginnen wir mit der Bildung der Partition und der Formatierung unserer Festplatte.
Unter Linux ist dies über die Befehlszeile ganz einfach:
sudo fdisk /dev/sdb

Format in FAT12:
sudo mkfs.fat /dev/sdb -F 12
Kopieren Sie die Datei für den Test:

Man sollte jedoch nicht vergessen, dass laut Dokumentation die Anzahl der Flash-Rewrite-Zyklen
garantiert nur innerhalb von 100.000. Zum Beispiel dauert das Formatieren und Schreiben einer einzelnen 30K-Datei (gemäß dem Debug-Protokoll dieses Beispiels):
00106 44 67 Write_FS blk_addr=003 0x08006600
106 Umschreibzyklen.
Die Frage bleibt: Wie kann ich Daten lesen, indem ich direkt auf FAT12-Dateien zugreife?
Darüber im
nächsten Artikel.Vielen Dank für Ihre Aufmerksamkeit!