MSCのサンプルアプリは8KByteのRAMドライブを使用していますがこのRAMドライブをフラッシュに置き換えていわゆるUSBメモリー的な動作をするようにしてみました。
まずはRAMドライブが512Byte/セクターになっているのでこれをフラッシュの消去単位である4KByte/セクターに変更します。ブロック数も256ブロックにして合計1MByteのドライブになるようにします。
enum
{
DISK_BLOCK_NUM = 256,
DISK_BLOCK_SIZE = 4096
};
合わせてBPBの内容をこのサイズに合わせます。
uint8_t msc_disk[ 4 /*DISK_BLOCK_NUM*/][DISK_BLOCK_SIZE] =
{
{
0xEB, 0x3C, 0x90, /* BS_jmpBoot */
0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, /* BS_OEMName "MSDOS5.0" */
0x00, 0x10, /* ☆BPB_BytePerSec */
0x01, /* BPB_SecPerClus */
0x01, 0x00, /* BPB_RsvdSecCnt */
0x01, /* BPB_NumFATs */
0x80, 0x00, /* ☆BPB_RootEntCnt */
0x00, 0x01, /* ☆BPB_TotSec16 */
0xF8, /* BPB_Media */
0x01, 0x00, /* BPB_FATSz16 */
0x01, 0x00, /* BPB_SecPerTrk */
0x01, 0x00, /* BPB_NumHeads */
0x00, 0x00, 0x00, 0x00, /* BPB_HiddSec */
0x00, 0x00, 0x00, 0x00, /* BPB_TotSec32 */
BPBの表記はリトルエンディアンなのでセクターサイズ(BPB_BytePerSec)4096=0x1000が0x00,0x10となり、セクターサイズが8倍になったのでルートエントリー(BPB_RootEntCnt)が0x10から0x80(128個)、トータルセクターサイズ(BPB_TotSec16)は256=0x100なので0x00,0x01となります。
管理情報を予め書いておかないとアクセスできないので未フォーマットの場合(BPBのシグネイチャーが書かれていないことで判断)管理情報をフラッシュに書き込みます。
void msc_init(void)
{
#if 1 /* 0にすると強制フォーマット */
flash_read( 0, 0, temp_buff, 512);
if (( temp_buff[510] != 0x55) || (temp_buff[511] != 0xaa))
#endif
{
flash_range_erase( FLASH_TARGET_OFFSET, SECTOR_SIZE *4);
flash_range_program( FLASH_TARGET_OFFSET, msc_disk[0], SECTOR_SIZE *4);
}
}
後は肝心の読み書きAPIのwrite10,read10をフラッシュの読み書きに置き換えます。
void flash_read( int32_t sec, int32_t offset, uint8_t *p_buff, int32_t size )
{
memcpy( p_buff, &flash_target_contents[sec*4096+offset], size);
}
void flash_write( int32_t sec, int32_t offset, uint8_t *p_buff, int32_t size )
{
if (offset == 0)
{
flash_range_erase( FLASH_TARGET_OFFSET+ sec*4096, SECTOR_SIZE);
}
flash_range_program( FLASH_TARGET_OFFSET+ sec*4096 +offset, p_buff, size);
}
ReadはRP2040のeXecute In Place(XIP)の仕組みのおかげでダイレクトにメモリにマッピングされているように見えますので単純にメモリーコピーで読めます。問題なのは書き込みの方でフラッシュに書き込みを行うとキャッシュのコヒーレンシーの問題が出てしまいキャッシュをクリアする必要があるのですが、このキャッシュの管理がコードを実行しているXIPと共通なのでコードの実行に支障が出て書き込み時にストールしてしまうことがあります。データシートを見ると何か回避策がありそうな感じですが。一般的なセオリーであるフラッシュ書き込み時には別のメモリー(RAM)でコードを実行するという方法で回避します。調べてみると実に簡単にRAM上で実行できました。
CMakeLists.txtに以下の1行を足すだけです。
pico_set_binary_type(TestMSC copy_to_ram)
これで1MByteのUSBメモリーになりました。
Pico側でもこのファイルを読み書きできるように実装すればPCとのデータ共有が楽になるのでアプリケーションの幅が広がるかなと思います。
はじめまして。
返信削除こちらの記事を見て、↓のサンプルアプリ
https://github.com/hathach/tinyusb/tree/master/examples/device/cdc_msc
をフラッシュドライブがマウントされるように改造してみているのですが、マウントされません。
もし可能でしたら、お作りになったコードの全体を見せていただけないでしょうか。
その後いろいろ試したらできるようになりました。失礼しました
削除