1

私はこう聞かれます:

RPi を使用して、フリーランニング システム タイマーを読み取る C 関数を記述します。システム タイマーはマイクロ秒ごとにカウントアップします。この関数のソースを独自のファイルに配置します。フリーランニング タイマーは、物理メモリ アドレス 0x20003004 にある 64 ビット値ですが、RPi はこのメモリ領域で一度に 32 ビットしかアクセスできません。これらのメモリ位置にアクセスするには、ファイル /dev/mem で mmap() が呼び出されます。常にエラーを確認し、適切に対処してください。システム タイマーにアクセスするには、次の手順に従います。 (a) 静的変数をテストして、カウンターがマップされているかどうかを確認します。

(b) カウンターがマップされていない場合

私。/dev/men を読み取り専用で開きます。

ii. システム ページ サイズを取得する

iii. mmap() を呼び出し、返されたアドレス (32 ビット整数へのポインター) を静的変数に保存します。mmap() がアドレス マッピングを設定できるようにして、mmap() を呼び出します。長さをページサイズに設定します。保護を読み取り専用に設定します。フラグを共有マップに設定します。次に、open() によって返されたファイル記述子を渡し、オフセットを 0x20003000 に設定します。この場合、mmap() は __SC_PAGESIZE バイトのページでしか操作できないため、アドレス 0x20003004 を直接マップすることはできません。アドレスは __SC_PAGESIZE に揃える必要があります。

iv。初期化が行われたことを示すために静的変数を設定します。

v. 開いているファイルを閉じます。

(c) 初期化が成功した場合、インデックス 1 の 32 ビット値とインデックス 2 の 32 ビット値を組み合わせて 64 ビット数を返します。インデックス 1 の 32 ビット値には、カウンターの最下位 32 ビットが含まれます。インデックス 2 の 32 ビット値には、カウンターの最上位 32 ビットが含まれます。それ以外の場合は 0 を返します。

最初のメモリ位置のタイマーの内容を取得できました0x20003000:

int main(int argc, char * argv[])
{
    int temp;
    int page_size;
    int *map;

    temp = open("/dev/mem", O_RDONLY);
    page_size = sysconf(_SC_PAGESIZE);


    map = mmap(0, page_size, PROT_READ, MAP_SHARED, temp, 0x20003000);
    printf("%X \n", map);

    close(temp);
    return 0;
}

他の 32 ビット番号を取得0x20003004して元の番号と組み合わせるように求められる部分で迷っています。どんな助けやガイダンスも歓迎します。

4

1 に答える 1

2

引用した説明から:

この場合、mmap()は__SC_PAGESIZEバイトのページでのみ動作できるため、アドレス0x20003004を直接マップすることはできません。アドレスは__SC_PAGESIZEに揃える必要があります。

これが意味するのは、mmap()に整列されているアドレスにのみマップできるということ__SC_PAGESIZEです。また、によって返されるアドレスをmmap()最大で逆参照できることも意味しpage_sizeます。つまり、withの呼び出しがmmap()0x20003000返す場合、0x20003000内のポインタを逆参照できます[0x20003000, 0x20003000 + page_size)

残りは読者の練習問題として残しておきます。

于 2013-01-31T02:18:33.277 に答える