Что делает request_mem_region () на самом деле и когда это необходимо?

Я занимаюсь написанием встроенного драйвера linux и решил запустить несколько GPIO, чтобы убедиться, что я правильно понимаю книгу (LDD3, chap9.4.1) .

Я могу контролировать правильные контакты GPIO по назначению (делая его высоким и низким, я пробовал мультиметр); однако я протестировал 2 части кода, один с request_mem_region() и один без него. Я ожидаю, что один, не получится, но оба работают нормально.

Код с 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() ?

Спасибо за любые ответы!

request_mem_region сообщает ядру, что ваш драйвер будет использовать этот диапазон адресов ввода-вывода, что предотвратит выполнение другими перекрывающимися вызовами одного и того же региона через request_mem_region . Этот механизм не делает никакого сопоставления, это чистый механизм резервирования, который полагается на то, что все драйверы устройств ядра должны быть хорошими, и они должны вызывать request_mem_region , проверять возвращаемое значение и вести себя корректно в случае ошибки.

Поэтому вполне логично, что ваш код работает без request_mem_region , просто он не соответствует правилам кодирования ядра.

Однако ваш код не соответствует стилю кодирования ядра. Кроме того, существует существующая инфраструктура для обработки GPIO, называемая gpiolib, которую вы должны использовать вместо того, чтобы вручную переназначать ваши регистры банка GPIO. На какой платформе вы работаете?

Использование 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 slide 276

  • Шпилька в Linux
  • Каково теоретическое максимальное количество открытых TCP-соединений, которые может иметь современный ящик Linux
  • Какая польза от while (0), когда мы определяем макрос?
  • Если streamи разделяют один и тот же PID, как их можно идентифицировать?
  • Почему код ядра / stream, выполняемый в контексте прерывания, не может спать?
  • Directory - / sys в linux
  • Ядро Linux
  • Обоснование макроса container_of в linux / list.h
  • addr2line на модуле ядра
  • Возможно ли раньше сделать прерывание убийцы OOM раньше?
  • Radeon HD6570 работает только в ядре Linux 3.6.7
  • Interesting Posts
    Давайте будем гением компьютера.