😊

C/C++: ブロックデバイスのRead/Writeラッパー関数を作る

2023/11/12に公開

はじめに

特にファイルシステムや下回りのデバイスドライバを書くときに、特定のリード操作はブロック単位(例えば512Byteなど)でしかリードライト出来ない事があります。しかし、ユーザプログラムからは任意のサイズでランダムアクセスしたい場合に、メモリのリードライトのためのラッパー関数を作ってあげる必要があります。

ラッパー関数を作る

Read 操作

例えば、以下のような指定されたアドレスから512バイト単位でしかリード出来ないread512関数があるとします。

ブロックデバイスのAPI (512バイト単位でのリードのみ可能)
size_t read512(uint32_t addr, uint8_t* buf);

これをラップし、ユーザが任意のアドレスから任意のサイズだけリード出来るラッパー関数を作成します。

ラッパー関数
size_t read(uint32_t addr, uint32_t len, uint8_t* buf) {
#define BLOCK_SIZE 512
    uint32_t base_addr = addr / BLOCK_SIZE;
    uint32_t offset = addr % BLOCK_SIZE;
    uint32_t read_bytes = 0;

    while (read_bytes < len) {
        uint8_t temp[BLOCK_SIZE];
        uint32_t bytes = read512(base_addr++, temp);

        for (int i = 0; i < bytes && (i + offset) < BLOCK_SIZE 
                                  && read_bytes < len; i++) {
            buf[read_bytes++] = temp[i + offset];
        }
        offset = 0;

        // 実際にリード出来たサイズが512バイト未満の場合、これ以上はリード出来ないので終了
        if (bytes < BLOCK_SIZE) {
            break;
        }
    }

    return read_bytes;
}

Discussion