&size(24){&color(darkgreen){''UMSC Sample Software''};}; #navi(H8USB) ''CONTENTS'' #contents ---- ''LINKS'' ---- **RenesasのUSBマスストレージクラスサンプルソフト [#vb601339] -仕様書&ref(man.pdf); --これは、マスストレージクラスの概略を知るのに一番良い資料だと思う。 -ソフト本体&ref(Rev_2003_11_04_H8S2215_MSC.lzh); ***USB Mass Storage Class (Bulk-Only Transport)の概要 [#x0acc605] -フロー #ref(flow.JPG) -サポートするSCSIコマンド |~Code|~コマンド名 |~コマンドの動作|~備考| |12| INQUIRY| ドライブに関する情報をホストに伝える|| |25| READ CAPACITY| メディアのセクタに関する情報をホストに伝える|| |28| READ(10)| 指定された読み出しセクタから、指定セクタ量のデータを読み出す|| |2A| WRITE(10)| 指定された書き込みセクタから、指定セクタ量のデータを書き込む|| |03| REQUEST SENSE| 前のコマンドでエラーが発生した時どのようなエラーが発生したかをホストに伝える|| |1A| MODE SENSE(10)| ドライブの状態をホストに伝える|| |1B| STOP START UNIT||ソース中に存在| |1E| PREVENT ALLOW MEDIUM REMOVAL| メディアの着脱を禁止/許可します|常に正常終了する| |00| TEST UNIT READY| メディアが使用可能か否かを調べる|常に正常終了する| |2F| VERIFY(10)| メディア上のデータにアクセス可能を確かめる|常に正常終了する| -未サポートコマンドに対して ++データ送受を要求している場合 ---データ送信を要求されている場合は、要求量の0x00をバルク送信する。 ---データ受信を要求している場合は、要求量のバルク受信する。 ++ホストに対してコマンドフェイルを返信 ***INQUIRY [#adbd2d34] -INQUIRY返答用のプログラム内定数(SetSCSIInfo.h) /* INQUIRY return data */ unsigned char ansInquiryData[] = { 0x00, #ifdef REMOVABLE_DISK /* in case disk is removable */ 0x80, //removable #else 0x00, //fix #endif /* REMOVABLE_DISK */ 0x02, 0x02, 0x5B, 0x00,0x00,0x00, 0x52,0x65,0x6E,0x65,0x73,0x61,0x73,0x20, /* Renesas */ /* product name = EX RAM DISK (below)*/ 0x45,0x58,0x20,0x52,0x41,0x4D,0x20,0x44,0x69,0x73,0x6B,0x20,0x20,0x20,0x20,0x20, 0x31,0x2E,0x31,0x32, /* version =1.12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -意味 |~フィールド|~設定値|~意味| |Peripheral Qualifier|00h|接続装置はdevice type field| |Peripheral Device Type|00h|ダイレクトアクセスデバイス| |RMB (Removable)|80h|取り外し可能(SetSystemSwitch.hでREMOVABLE_DISKが定義)| |Device-type Modifier|00h|SCSI-2では00h| |SCSI version (ISO, ECMA, ANSI)|02h|SCSI-2では02h| |Response|02h|SCSI-2| |Data Length|5Bh|91文字(バイト5以降の文字数)| |RESERVE||| |RESERVE||| |OPTIONS|00h|サポート機能無し| |Vender ID|Renesas|ANSIで管理| |Product ID|EX RAM DISK|ベンダーが定義| |Version|1.12|ベンダーが定義| ***READ CAPACITY [#h361e617] -PBR内に書いてある、1セクタ当りのバイト数と総セクタ数から容量を算出。 -DoSCSICommand.c内 readCapaData[0] = ConvReflexn(&pbrAcsess->pbrMeaningType.allSector[0],2); if (readCapaData[0] == 0x00000000){ readCapaData[0] = ConvReflexn(&pbrAcsess->pbrMeaningType.allSectorLarge[0],4); } readCapaData[1] = ConvReflexn(&pbrAcsess->pbrMeaningType.bytePerSector[0],2); workValue = 8; -すなわち、PBR内のallSectorとallSectorLarge、bytePerSectorから算出している。 -SRAMの初期化データを見ると、 |~項目|~数値|~定義場所| |allSector|FAT_ALL_SECTORS_SMALL(0x7f, 0x00, 0x00)|CatSCSITypedef.h| |allSectorLarge|FAT_ALL_SECTORS_LARGE(0x00, 0x00, 0x00, 0x00)|CatSCSITypedef.h| |bytePerSector|0x00, 0x02 (512バイトの意味?)|SetSCSIInfo.h| -FAT12を定義している。 -元々は、SysMemMap.hのDISK_ALL_BYTEで決まる。容量によってFAT12、FAT16 (small)、FAT16 (large)になる。 -FATの定義を切替えているのは、CatSCSITypedef.hの#if文 ***READ(10) [#d085507d] -DoSCSICommand.c ***WRITE(10) [#hf9fdb11] -DoSCSICommand.c ***REQUEST SENSE [#w08ae220] -DoSCSICommand.c -データ転送方向を確認した後、reqSensDataGVar[]を送出。 /* REQUEST SENSE return value */ unsigned char reqSensDataGVar[] = { 0x70,0x00, 0x00, 0x00,0x00,0x00,0x00, 0x0C, 0x00,0x00,0x00,0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00 }; ***MODE SENSE(10) [#rcf2a52f] -DoSCSICommand.c -これは理解するのが大変 ***PREVENT ALLOW MEDIUM REMOVAL [#j3eb5849] -DoSCSICommand.c -SCSIコマンドの転送方向とunit_stateをチェックして、正常終了する。 ***TEST UNIT READY [#fef2a989] -DoSCSICommand.c -SCSIコマンドの転送方向とunit_stateはチェックして、正常終了する。 ***VERIFY(10) [#ce04884e] -DoSCSICommand.c -SCSIコマンドの転送方向とunit_stateをチェックした後、ちょっとした処理をしてる。 /* in case BytChk bit is "0", confirm designated sector in case BytChk bit is "1", return "PARAMETER VALUE INVALID" */ if ((cbwDataGVar->cbwMeaningType.cmd1 & ~0x02) != 0x00) { /* in case BytChk bit is "1", return "PARAMETER VALUE INVALID" set REQUEST SENSE value */ SetBotCmdErr(INVALID_1,0); workValue = 0; break; } ***SRAMの初期化(FATの構築) [#q8e1a312] -StartUp.c内でMBRとPBRを初期化してる /* set initial MBR partition table1 and EOF in sector 1 */ while (readCounter <= 65) { botDataGVar.byteVal[(readCounter + 446)] = mbrData->byteVal[readCounter]; readCounter++; } readCounter = 0; /* set initial PBR data in sector 20 */ while (readCounter <= 62) { botDataGVar.byteVal[(readCounter + 16384)] = pbrData->byteVal[readCounter]; readCounter++; } -MBRとPBRの型宣言(CatSCSITypedef.h) typedef union MBRDataType { /* MBR */ unsigned char byteVal[532]; struct mbrMeaningType { unsigned char bsl[446]; unsigned char pt1[16]; unsigned char pt2[16]; unsigned char pt3[16]; unsigned char pt4[16]; unsigned char chknum[2]; } mbrMeaningType; } MBRDataType; typedef union PBRDataType { /* PBR */ unsigned char byteVal[62]; struct pbrMeaningType { unsigned char jump[3]; /*Jump command to IPL */ unsigned char dummy[8]; /*name */ unsigned char bytePerSector[2]; /*byte numbers per one sector*/ unsigned char sectorPerClaster; /*sector numbers per one claster*/ unsigned char reserveSectorNum[2]; /*reserved sector numbers */ unsigned char fat; /*FAT numbers */ unsigned char root[2]; /*entry numbers */ unsigned char allSector[2]; /*all sector numbers */ unsigned char mediaDiscripter; /*media descriptor */ unsigned char sectorPerFat[2]; /*sector numbers per one FAT*/ unsigned char sectorPerTrak[2]; /*sector numbers per one track*/ unsigned char head[2]; /*head numbers */ unsigned char hideSector[4]; /*hide sector numbers */ unsigned char allSectorLarge[4]; /*hide sector numbers */ unsigned char dummy2[18]; unsigned char reserve[8]; } pbrMeaningType; } PBRDataType; -MBRとPBRの初期化データ(SetSCSIInfo.h) /* MBR partition table 1 and EOF */ const MBRDataType mbrData[] = { 0x80,0x00,0x00,0x00,PARTITION_TYPE 0x00,0x00,0x00,0x20,0x00,0x00,0x00,PARTITION_ALL_SECTORS /*Prt1*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*Prt2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*Prt3 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*Prt4 */ 0x55,0xAA /*EOF*/ }; /* PBR */ const PBRDataType pbrData[] = { 0xEB,0x3C,0x90, 0x29,0x7B,0x27,0x60,0x6A,0x49,0x48,0x43, 0x00,0x02, FAT_SECTORS_PER_CLUSTER // 1 Byte 0x01,0x00, 0x02, FAT_ROOT_ENTRIES // 2 Byte FAT_ALL_SECTORS_SMALL // 2 Byte 0xF8, FAT_SECTORS_PER_FAT // 2 Byte 0x3F,0x00, 0xFF,0x00, 0x20,0x00,0x00,0x00, FAT_ALL_SECTORS_LARGE // 4 Byte 0x80, 0x00, 0x29, 0x00,0x00,0x00,0x00, FAT_VOLUME_LABEL // 11 Byte FAT_SYSTEM_ID // 8 Byte 0x00,0x00 };