SDカードの構造と内部レジスタ(その2)

SDカードの内部レジスタ


SDカードには、いくつかの内部レジスタがある。

レジスタ名 内容 使用コマンド
CSD カード特性データレジスタ アクセスタイム、カード容量など CMD9 データ・トークン
CID カード識別レジスタ 製造者情報やシリアル番号 CMD10 データ・トークン
Status カードステータスレジスタ カードのステータス CMD13 フォーマットR2
OCR 動作条件レジスタ カードの動作電圧 CMD58 フォーマットR3

※このほかにもRCA, DSRというレジスタが存在するが、SPIモードではアクセスすることができない。

 

・CSD(カード特性データレジスタ)

CSDレジスタは、CMD9に対するデータ・トークンで読むことができる。

非常に多くの情報を含んでいるが、ここでは主なものを抜粋して掲載する。

略称 意味 ビット位置 データ内の位置
CSD_STRUCTURE CSD structure 127-126 data0[7:6]
SPEC_VERS Spec version 125-122 data0[5:2]
TRAN_SPEED Max data transfer rate 103-96 data3[7:0]
READ_BL_LEN Max read data block length 83-80 data5[3:0]
C_SIZE device size 73-62 data6[1:0]-data7-data8[7:6]
C_SIZE_MULT device size multiplier 49-47 data9[1:0]-data10[7]
FILE_FORMAT File format 11-10 data14[3:2]
ECC ECC code 9-8 data14[1:0]
CRC CRC 7-1 data15[7:1]
always 1 0 data15[0]

 

これら情報のC_SIZEとC_SIZE_MULT、READ_BL_LENの値から、カードの容量を計算することができる。

 

・CID(カード識別レジスタ)

CIDレジスタはCMD10のデータ・トークンとして読むことができ、カードの製造元などの情報が含まれている。

 

名称 バイト数 データ内の位置
Manufacture ID 1 data0
OEM/Application ID 2 data1-data2
Product Name 6 data3-data8
Product Revision 1 data9
Pruduct Serial Number 4 data10-data13
Manufacturing Date 1 data14
CRC 1 data15

 

・Manufacture IDは、01(Matsushita)、02(Toshiba)、03(Sandisk)などとなっている。

 

・Statusレジスタ

Statusレジスタは本来32bitのレジスタであるが、SPIモードでは16bitだけを読み出すことができる。

CMD13(Statusレジスタ取得)を発行し、コマンド・レスポンスのフォーマットR2で送られる2バイトの情報である。先頭の1バイトはフォーマットR1と同じである。

 

フォーマットR1を次に示す。

エラーがない状態では、16bitがすべて0になる。

 

SDカード内のデータ


SDカード内のデータは、通常のメモリと同様に、アドレスで管理されている。(単純にメモリカードとして使用することも可能であるが、通常は何らかのファイルシステムにより管理される)

SDカードでは、データの読み書きはブロック単位で行われる。ブロックの大きさ(Block Length)は、CSDレジスタのREAD_BLK_LENである。またCMD16で変更可能である。

ここでは、後に解説するファイルシステムとの整合性を重視し、1ブロックは512バイトであることを前提に進める。

 

・ブロックサイズ設定

ブロックサイズ(Block Length)の指定はCMD16で行う。

CMD16の引数として、ブロックサイズをバイト単位で与える。512バイトにする場合のコマンド・トークンは

[0x50, 0x00, 0x00, 0x02, 0x00, CRC]となる。

 

・データリード(1ブロック)

データリードはCMD17で行う。CMD17の引数としてアドレス(4バイト)を与える。

コマンド・レスポンス(フォーマットR1)の後、データ・トークンを受信する。リードデータは、Block Lengthバイト分送られる。

0x10000000番地を指定する場合のコマンド・トークンは

[0x51, 0x10, 0x00, 0x00, 0x00, CRC]となる。

 

・データライト(1ブロック)

データライトはCMD24で行う。引数として書き込み先頭アドレスを与える。

当然であるが、誤った書き込みを行うと、カード内のデータを破壊する。注意が必要である。

 

演習問題


次のワークスペースをダウンロード・展開し、次の演習を行う。

sd2.zip

 

演習1:カード容量の計算

プロジェクト[sd2_1]を使用する。SDカードからCSDレジスタを読み出して、表示するプログラムを作成せよ。得られたCSDレジスタの値から、カードの容量を計算せよ。

べき乗の計算には一般的にはpow()関数を使用する。例えば2の5乗はpow(2, 5);で得られる。

この演習でのべき乗の計算は、2のxx乗という計算である。この場合はシフト演算を使ったほうがメモリサイズ、計算速度の両面から有利である。

例) A*(2^3)は、A<<3で得られる。

 

演習2:1ブロックリード

プロジェクト[sd2_2]を使用する。SDカードの先頭から1ブロック読み出して、表示するプログラムを作成せよ。

表示は16進数と、印字可能であれば(isprint()で判断)、文字としての表示も行う。

この領域は、FATファイルシステムの一部(Master Boot Record)であり、パーティション情報などが記録されている。

次のような手順で行う。

  1. CMD17を発行し、データ・トークン・スタートバイトを待つ
  2. 1ブロック(512バイト)分のデータを読み込み、配列に格納する
  3. 配列の先頭のデータから、16進表示と文字表示を行う(1行あたり16バイト)

 

— 表示例 —

※ この表示例は、SDカードの先頭に記録されている情報ではありません

 

演習3:第一パーティション

演習2で読み出したデータの、data[454:457]の4バイトは、第一パーティションのセクタ番号(ブロック番号)を示している。第一パーティションの先頭部分を1ブロック読み出して、表示せよ。

演習2と同様に、表示は16進数表示と文字表示を行う。

1セクタの容量は512バイトであるので、目的とするアドレスはセクタ番号*512である。

※SDカードはFATファイルシステムでフォーマットされており、リトルエンディアンである。data[454:457]の4バイトのセクタ番号はリトルエンディアンで記録されている

Copyright © 2012-2020 ミームス(MEMEs)のサポートページ All rights reserved.
This site is using the Desk Mess Mirrored theme, v2.5, from BuyNowShop.com.