モニタの意味を間違ったようですが、サンプルのmain()プログラムのことです
Writeは全く歯が立ちません。READだけですがMass Storage Devicesにアクセス出来るようになりました!
Sony 8GBのUSBメモリ(USM8GLX WA )にはREAD(12)でアクセスが必要だと思っていたのですが、READ(10)でアクセスできました
マイナーなMediafoのUSBメモリだけが偶然動いた訳ではないようです。正しいアクセス方か否かは不明ですが・・。
上記、ログで、下記が表示されています
dCBWDataTransferLengthの設定が必要だったようです。エンディアンを意識すべきですが、セクタ数はバッファサイズの関係からせいぜい64なので(有り得ないくらい)サボりました
ちなみにMediaFoは下記のように読込みセクタ数だけで動作します
100MBぐらいのデータを転送すると実際の時計とコマンド終了時に表示している経過時間が10秒くらいずれているのが分かりました。経過時間を表示しなかったり、1MBぐらいの小容量のデータ量転送では分からなかったと思います
実際の時計の時間と合うように、クロックのカウント回数を調整(減少)しましたが、まるで「逃げ水」のように実際の時間と離れていきます
ありゃー、、、。酔っぱらったかな。まぁ推測ですが、毎秒1000回の割込みで破綻しているのでは?と考えました。いくら+1するだけとは言え、その前後にはレジスタ類の退避・回復があります。毎秒1000回の割込みが発生すればいくら高性能マイコンでも破綻します
仕方なくハードマニュアルでCMTを調べてみました
周辺クロックPφ=24MHzなので、分周を1/512にするとCMCNT=46875で丁度1秒になり、且つ2バイトで表現できる範囲に収まります
やっと、時計と表示している経過時間が一致したので、再度、性能測定しました。Sony 8GBで1.9MB/秒になってしまいました。なんとかそれでもFull Speedの12Mbpsは上回っています。
MediaFo 512MB (Block Size=32KB)
Sony USM8GLX WA 8GB (Block Size=32KB)
Writeは全く歯が立ちません。READだけですがMass Storage Devicesにアクセス出来るようになりました!
の、使い方がよく分かりません。HELPはコマンドの一覧だけです。APIのサンプルみたいです。
ポチのメモリは小容量且つ揮発性で、新しいことを覚えると、昔の大事な記憶が消えていきます。なのでUnixライクのコマンド名にしてみました。すいません遊びました
またまた、すいません酔っぱらってます。見直してみると(ポチが追加した処は)無駄な処理が多く、隙だらけですね・・・
ポチのメモリは小容量且つ揮発性で、新しいことを覚えると、昔の大事な記憶が消えていきます。なのでUnixライクのコマンド名にしてみました。すいません遊びました
またまた、すいません酔っぱらってます。見直してみると(ポチが追加した処は)無駄な処理が多く、隙だらけですね・・・
Sony 8GBのUSBメモリ(USM8GLX WA )にはREAD(12)でアクセスが必要だと思っていたのですが、READ(10)でアクセスできました
マイナーなMediafoのUSBメモリだけが偶然動いた訳ではないようです。正しいアクセス方か否かは不明ですが・・。
上記、ログで、下記が表示されています
READ_CAPACITY: Last Logical Block Address=15663103, Block Length in Bytes=512
/*""FUNC COMMENT""************************************************************ * ID : * Outline : USB driver *----------------------------------------------------------------------------- * Include : *----------------------------------------------------------------------------- * Declaration: void H_UsbStateManager(void); *----------------------------------------------------------------------------- * Function : Enumeration & Detach check * : *----------------------------------------------------------------------------- * Argument : void *----------------------------------------------------------------------------- * ReturnValue: void *----------------------------------------------------------------------------- * Notice : * : *""FUNC COMMENT END""*********************************************************/ struct CBWbody CBW; static const char CBWconst[32]="USBC"; int read_sectors(USB_U32 lba, USB_U32 sects, USB_U8 * data) { int i, ret; for ( i=0; i<31; i++) CBW.CBWu.CBWc[i]=CBWconst[i]; // Build CBW CBW.CBWu.CBWx.bCBWCBLength = 10 ; // bCBWCBLength = 12 CBW.CBWu.CBWx.dCBWDataTransferLength = 0x00020000 * sects; // dCBWDataTransferLength = 512 * sects CBW.CBWu.CBWx.bmCBWFlags = 0x80; // bmCBWFlags = 0x80 In CBW.CBWu.CBWx.CBWCBu.CBWCBx.op_code = SCSI_CMD_READ_10; // SCSI CMD=SCSI_CMD_READ_10 CBW.CBWu.CBWx.CBWCBu.CBWCBr.CBWlba.LBA[0] = ((USB_U8 *)&lba)[0]; CBW.CBWu.CBWx.CBWCBu.CBWCBr.CBWlba.LBA[1] = ((USB_U8 *)&lba)[1]; CBW.CBWu.CBWx.CBWCBu.CBWCBr.CBWlba.LBA[2] = ((USB_U8 *)&lba)[2]; CBW.CBWu.CBWx.CBWCBu.CBWCBr.CBWlba.LBA[3] = ((USB_U8 *)&lba)[3]; CBW.CBWu.CBWx.CBWCBu.CBWCBr.TL[1] = sects; if( PipeFlag[PIPE2] == PIPE_IDLE ) H_DataOut( PIPE2, 31, &CBW); // Write CBW if( PipeFlag[ PIPE2 ] != PIPE_WAIT ){ switch( PipeFlag[PIPE2] ) { case PIPE_DONE: PipeFlag[ PIPE2 ] = PIPE_IDLE; ret = H_DataIn( PIPE1, sects*512, data ); // Read Sectors if ( ret == USB_SUCCESS ) { if ( PipeLRC[PIPE1] == 13 && // Last Read Count=13=sizeof(CSW) data[12] != 0 ) { Serial_Puts("===>>> request_sense().\n"); request_sense(Buffs); UsbDeviceState = DVST_STALL; // ERROR break; } ret = H_DataIn( PIPE1, 13, DATA.Buffer); // Read CSW if ( ret == USB_SUCCESS ) { ; } else { UsbDeviceState = DVST_STALL; // ERROR } } else { UsbDeviceState = DVST_STALL; /* ERROR */ } break; case PIPE_NORES: UsbDeviceState = DVST_NORES; /* ERROR */ break; case PIPE_STALL: UsbDeviceState = DVST_STALL; /* ERROR */ break; } } return ret; }
CBW.CBWu.CBWx.dCBWDataTransferLength = 0x00020000 * sects; // dCBWDataTransferLength = 512 * sects
dCBWDataTransferLengthの設定が必要だったようです。エンディアンを意識すべきですが、セクタ数はバッファサイズの関係からせいぜい64なので(有り得ないくらい)サボりました
ちなみにMediaFoは下記のように読込みセクタ数だけで動作します
CBW.CBWu.CBWx.CBWCBu.CBWCBr.TL[1] = sects;
タイマの誤差が大きいことが判明しました。下記はボツです。 #15に再掲
READ性能が2.6MB/s程度しかでませんでした・・・
CHanさんのホームページのLPC2368/72MHの場合の1/3程度です(SPIでは無く、nativeなSDカードインタフェース?)
Hi-Speed 480Mbpsのはずなのに、。色々試しましたが、当面の限界のようです。まぁFull Speedの12Mbps以上なので、今は「良し」とします
MediaFo 512MB (Block Size=32KB)
Sony 8GB (Block Size=32KB)
タイマの処理はファイル作成時刻取得のためと勘違いしコメントアウトしましたが、性能測定の為だったのですね
READ性能が2.6MB/s程度しかでませんでした・・・
CHanさんのホームページのLPC2368/72MHの場合の1/3程度です(SPIでは無く、nativeなSDカードインタフェース?)
Hi-Speed 480Mbpsのはずなのに、。色々試しましたが、当面の限界のようです。まぁFull Speedの12Mbps以上なので、今は「良し」とします
MediaFo 512MB (Block Size=32KB)
> >MediaFo 512MB MediaFo 512MB: command not found > >ll D---- 2011/03/24 04:14 0 FAT_HO~1 FAT_host26 D---- 2011/03/25 08:39 0 FAT_HO~2 FAT_host28 ----A 2009/05/18 05:32 94416286 LARG.DAT 1 File(s), 94416286 bytes total 2 Dir(s), 401822720 bytes free UsbDeviceState = DVST_MOUNTED >fo 1 larg.dat rc=0 FR_OK > > >fr 1000000 1000000 bytes read in 1215 ms, with 823 kB/sec. > >fr 10000 10000 bytes read in 12 ms, with 833 kB/sec. > fr10000000 fr10000000: command not found > >fr 10000000 10000000 bytes read in 12384 ms, with 807 kB/sec. >
Sony 8GB (Block Size=32KB)
> >ll D---- 2011/03/25 09:13 0 USB D---- 2011/03/25 13:51 0 写真 写真 ----A 2011/03/19 04:12 2324738644 LARG.DAT ----- 2011/03/27 02:10 0 a.txt 2 File(s),2324738644 bytes total 2 Dir(s), 1284571136 bytes free UsbDeviceState = DVST_MOUNTED > > >fo 1 larg.dat rc=0 FR_OK > > >fr 1000000 1000000 bytes read in 314 ms, with 3184 kB/sec. > >fr 10000000 10000000 bytes read in 3766 ms, with 2655 kB/sec. > >fr 10000000 10000000 bytes read in 3775 ms, with 2649 kB/sec. > >fr 10000000 10000000 bytes read in 3800 ms, with 2631 kB/sec. > >fr 10000000 10000000 bytes read in 3774 ms, with 2649 kB/sec. > >fr 10000000 10000000 bytes read in 3748 ms, with 2668 kB/sec. >
タイマの処理はファイル作成時刻取得のためと勘違いしコメントアウトしましたが、性能測定の為だったのですね
100MBぐらいのデータを転送すると実際の時計とコマンド終了時に表示している経過時間が10秒くらいずれているのが分かりました。経過時間を表示しなかったり、1MBぐらいの小容量のデータ量転送では分からなかったと思います
実際の時計の時間と合うように、クロックのカウント回数を調整(減少)しましたが、まるで「逃げ水」のように実際の時間と離れていきます
ありゃー、、、。酔っぱらったかな。まぁ推測ですが、毎秒1000回の割込みで破綻しているのでは?と考えました。いくら+1するだけとは言え、その前後にはレジスタ類の退避・回復があります。毎秒1000回の割込みが発生すればいくら高性能マイコンでも破綻します
仕方なくハードマニュアルでCMTを調べてみました
周辺クロックPφ=24MHzなので、分周を1/512にするとCMCNT=46875で丁度1秒になり、且つ2バイトで表現できる範囲に収まります
volatile unsigned int Timer_Sec; // * パフォーマンスタイマ (1Hz加算) // *--------------------------------------------------------- // * 1000Hz --> 1Hzインターバルタイマ (CMT0) // Debug // *--------------------------------------------------------- void init_cmt0(void) { // CPG.FRQCR.WORD = 0x1104; // *--- FRQCR設定 内部クロック比 I:B:P = 144MHz:48MHz:24MHz --- CPG.FRQCR.WORD = 0x0104; // *--- FRQCR設定 内部クロック比 I:B:P = 144MHz:48MHz:24MHz --- CPG.STBCR7.BIT.MSTP72 = 0; // *--- STBCR7設定 CMTクロック供給開始 --- CMT.CMSTR.BIT.STR0 = 0; // *--- CMSTR設定 CMCNT0カウント停止 --- CMT.CMCNT0.WORD = 0x0000; // *--- CMCNT0設定 0クリア --- CMT.CMCSR0.WORD = 0x0043; // *--- CMCSR0設定 CMI発生許可 クロック設定[Pφ/512] --- // CMT.CMCOR0.WORD = PCLK / 8 / 1000 - 1; // *--- Set clock divider // CMT.CMCOR0.WORD = PCLK / 512 / 1000 ; // *--- Set clock divider CMT.CMCOR0.WORD = PCLK / 512 ; // *--- 1 Sec Timer // CMT.CMSTR.BIT.STR0 = 0x1; // *--- CMSTR設定 CMCNT0カウントは、まだ開始しない --- // * 割り込み優先レベル設定レジスタ10 INTC.IPR10.BIT._CMT0 = 1; // * コンペアマッチタイマ チャネル1 } void #ifndef HEW // __attribute__((interrupt_handler)) #endif int_cmt_cmi0(void) { if( CMT.CMCSR0.BIT.CMF == 1 ) { } // CMT.CMCNT0.WORD = 0x0000; // *--- CMCNT0設定 0クリア <<<--- 自動でクリア CMT.CMCSR0.BIT.CMF = 0; // * コンペアマッチフラグをクリア Timer_Sec++; // *--- 1 Sec Up // disk_timerproc(); // * ディスク制御タイマ (100Hz) led_toggle(); // Switch LED On <----> Off } static void Timer_Start ( void ) //* Delay in unit of ms { CMT.CMSTR.BIT.STR0 = 0x0; // *--- CMSTR設定 CMCNT0カウント停止!! --- Timer_Sec = 0; // CMT.CMCNT0.WORD = 0x0000; // *--- CMCNT0設定 0クリア --- CMT.CMSTR.BIT.STR0 = 0x1; // *--- CMSTR設定 CMCNT0カウント開始!! --- } static UINT Timer_Stop ( void ) // *--- Delay in unit of ms { int tictac; tictac = (int)CMT.CMCNT0.WORD; // CMT.CMSTR.BIT.STR0 = 0x0; // *--- CMSTR設定 CMCNT0カウント停止!! --- // LED点滅のため敢えて止めない return Timer_Sec*1000 + (tictac*1000)/(24000000/512); // return msec }
やっと、時計と表示している経過時間が一致したので、再度、性能測定しました。Sony 8GBで1.9MB/秒になってしまいました。なんとかそれでもFull Speedの12Mbpsは上回っています。
MediaFo 512MB (Block Size=32KB)
>Mediafo 512MB Mediafo 512MB: command not found > >ll D---- 2011/03/24 04:14 0 FAT_HO~1 FAT_host26 D---- 2011/03/25 08:39 0 FAT_HO~2 FAT_host28 ----A 2009/05/18 05:32 94416286 LARG.DAT 1 File(s), 94416286 bytes total 2 Dir(s), 401822720 bytes free >fo 1 larg.dat rc=0 FR_OK > >fr 10000000 10000000 bytes read in 12071 ms, with 828 kB/sec. > >fr 10000000 10000000 bytes read in 12367 ms, with 808 kB/sec. > >fr 10000000 10000000 bytes read in 12398 ms, with 806 kB/sec. > > >fr 10000000 10000000 bytes read in 12371 ms, with 808 kB/sec. >
Sony USM8GLX WA 8GB (Block Size=32KB)
> >Sony 8GB Sony 8GB: command not found > >ll D---- 2011/03/25 09:13 0 USB D---- 2011/03/25 13:51 0 写真 写真 ----A 2011/03/19 04:12 2324738644 LARG.DAT ----- 2011/03/27 02:10 0 a.txt 2 File(s),2324738644 bytes total 2 Dir(s), 1284571136 bytes free UsbDeviceState = DVST_MOUNTED > >fo 1 larg.dat rc=0 FR_OK > >fr 10000000 10000000 bytes read in 4451 ms, with 2246 kB/sec. > > >fr 10000000 10000000 bytes read in 5040 ms, with 1984 kB/sec. > > >fr 10000000 10000000 bytes read in 5038 ms, with 1984 kB/sec. > > >fr 10000000 10000000 bytes read in 5051 ms, with 1979 kB/sec. > >fr 100000000 100000000 bytes read in 47323 ms, with 2113 kB/sec. >
コメントをかく