FAT12ファイルシステムを備えたフラッシュドライブとしてのSTM32F103C8T6

デバイスを開発する場合、多くの場合、作業プログラムの外部に設定を保存する必要があります。 特別なツールを使用せずにそれらを変更できるとさらに便利です。



おそらく最も一般的なSTM F103マイクロコントローラーのストレージオプションを検討してください。 有名なBlue Pillブレッドボードも普及に貢献しました。



画像

フラッシュを使用すると、内部フラッシュのFAT12ファイルシステムを使用して設定を保存および変更できるだけでなく、ファームウェアの更新を整理することもできます。



ドキュメントによると、STM32F103C8T6には64Kのフラッシュメモリが搭載されています。 ただし、ほとんどすべてのSTM32F103C8T6には、128Kがインストールされています。 これはさまざまな情報源でも言及されています-通常は64K増えます。 この「機能」により、128K-20K(システムにはFAT12が必要)-ファームウェアのサイズのフラッシュドライブとしてマイクロコントローラーを使用できます。



このコントローラーをフラッシュドライブとして使用しようとする多くの愛好家は、FAT12ファイルシステムモードで使用する際の問題に直面しました。 判明したディスクイメージを削除/塗りつぶすために使用します。 しかし、ファイルドライブとして作業するとき、問題が始まりました。



この問題は、セクター(ブロック)への異なるアクセスシーケンスにあります。 ディスクイメージがロードされると、たとえば次のように記録が順次行われます。



-ブロック番号1を記録

-記録ブロック番号2

-ブロック番号3を記録します。



FAT12データを書き込むとき、記録は任意に発生します。



-ブロック番号3を記録

-ブロック番号1を記録

-レコードブロック番号2。



また、フラッシュへの書き込みには1Kページ全体を消去する必要があるため、ドライブで512バイトのセクターを使用する場合(および他のセクターを使用できない場合)、ランダムアクセスを使用すると、隣接するセクターの情報が消去されます。 これを防ぐため、上記の例では512バイトの配列を使用して隣接セクターを保存しています。 記録は次のようになります。



-ページの先頭のアドレスを決定し、

-隣接するセクターを覚えて、

-ページを消去し、

-記憶されたセクターを書く、

-データを書き込みます。



必要な必要なしに鉄のジャングルを掘り下げないために、CubeMXでプロジェクトを準備しました。



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(); }
      
      





バイナリファイルのサイズは約20Kでしたので、データメモリページは0x08006000(24K)で定義されています。



コンパイルします(例のソースコードはここで取得できます)。



接続します:



 [ 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
      
      





ディスクが決定され、すべてが正常です!



パーティションの形成とディスクのフォーマットを始めましょう。



Linuxでは、これはコマンドラインから非常に簡単です。



 sudo fdisk /dev/sdb
      
      









FAT12の形式:



 sudo mkfs.fat /dev/sdb -F 12
      
      





テスト用のファイルをコピーします。







ただし、ドキュメントによると、フラッシュ書き換えサイクルの数は

たとえば、1つの30Kファイルをフォーマットして書き込むには、この例のデバッグログによると、次のようになります。



 00106 44 67 Write_FS blk_addr=003 0x08006600
      
      





106書き換えサイクル。



問題は残っています-FAT12ファイルに直接アクセスしてデータを読み取るにはどうすればよいですか?

これについては、 次の記事で説明します。

ご清聴ありがとうございました!



All Articles