Подтвердить что ты не робот

Что делает 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()?

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

4b9b3361

Ответ 1

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

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

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