web-dev-qa-db-ja.com

request_mem_region()は実際には何をし、いつ必要なのですか?

私は組み込みLinuxドライバーの作成について勉強していて、本 (LDD3、chap9.4.1) を正しく理解するために、いくつかのGPIOを起動することにしました。

意図したとおりに正しいGPIOピンを制御できます(高低にして、マルチメーターでプローブしました)。ただし、2つのコードをテストしました。1つはrequest_mem_region()あり、もう1つはなしです。私はそれがないと失敗することを期待していますが、どちらもうまくいきます。

_request_mem_region_を使用したコード:

_if( request_mem_region( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF,DEVICE_NAME ) == NULL )
  {
    printk( KERN_ALERT
            "GPIO_140_141_conf_phys error:%s: unable to obtain I/O memory address 0x%08llX\n",
            DEVICE_NAME, PIN3_CONF_PHYS );

    return -EBUSY;
  }

pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
//-----------------------------------------------------------------
if( request_mem_region( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5,DEVICE_NAME ) == NULL )
  {
    printk( KERN_ALERT
            "error:%s: unable to obtain I/O memory address 0x%08llX\n",
            DEVICE_NAME, GPIO_BANK5_PHYS );

    return -EBUSY;
  }

gpio_virt = (u32)ioremap( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5 );

//some iowrite32() functions continue...
_

request_mem_region()なしのコード:

_pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
gpio_virt = (u32)ioremap( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5 );
//some iowrite32() functions continue...
_

両方のケースで確認できる唯一の違いは、_cat /proc/iomem_を実行した結果です。request_mem_region()を使用すると、_49056000-49056097 : GPIO3_を示す追加の行が表示されます。

私の質問は、request_mem_region()だけでハードウェアアドレスと通信できるため、ioremap()が必要な理由です。では、実際にrequest_mem_region()を使用する必要があるのはいつですか?

返信ありがとうございます!

24

request_mem_regionは、ドライバーがこの範囲のI/Oアドレスを使用することをカーネルに通知します。これにより、他のドライバーがrequest_mem_regionを介して同じ領域を重複して呼び出すことができなくなります。このメカニズムはいかなる種類のマッピングも行いません。これは純粋な予約メカニズムであり、すべてのカーネルデバイスドライバーがNiceでなければならず、request_mem_regionを呼び出し、戻り値を確認し、ケースで適切に動作する必要があるという事実に依存していますエラーの。

したがって、コードがrequest_mem_regionなしで機能することは完全に論理的です。それは、カーネルコーディングルールに準拠していないというだけです。

ただし、コードがカーネルコーディングスタイルに準拠していません。さらに、gpiolibという名前のGPIOを処理するための既存のインフラストラクチャがあり、GPIOバンクレジスタを手動で再マップする代わりに使用する必要があります。どのプラットフォームに取り組んでいますか?

41

デバイスドライバーでのrequest_mem_region()およびioremap()の使用は非推奨になりました。代わりに、以下の「マネージ」関数を使用してください。これにより、ドライバーのコーディングとエラー処理が簡素化されます。

devm_ioremap()
devm_iounmap()
devm_ioremap_resource(), Takes care of both the request and remapping operations

https://bootlin.com/doc/training/linux-kernel/linux-kernel-slides.pdf スライド276

1
jordi oliva