¿Qué hace realmente request_mem_region() y cuándo se necesita?

4 minutos de lectura

avatar de usuario
soy un dragón rana

Estoy estudiando cómo escribir un controlador de Linux integrado y decidí disparar algunos GPIO para asegurarme de que entiendo el libro. (LDD3, cap9.4.1) correctamente.

Puedo controlar los pines GPIO correctos según lo previsto (haciéndolo alto y bajo, probé con un multímetro); sin embargo, probé 2 piezas de código, una con request_mem_region(), y uno sin. Espero que el que no tiene falle, pero ambos funcionan bien.

Código con 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...

código sin 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...

La única diferencia que puedo observar de ambos casos es el resultado de hacer un cat /proc/iomemel que tiene request_mem_region() mostrará una línea adicional que muestra 49056000-49056097 : GPIO3.

mi pregunta es porque request_mem_region() es necesario ya que todavía puedo comunicarme con la dirección de hardware con solo ioremap()? Entonces, ¿cuándo realmente necesitamos usar request_mem_region()?

¡Gracias por cualquier respuesta!

avatar de usuario
Tomás Petazzoni

request_mem_region le dice al kernel que su controlador va a usar este rango de direcciones de E/S, lo que evitará que otros controladores realicen llamadas superpuestas a la misma región a través de request_mem_region. Este mecanismo no hace ningún tipo de mapeo, es un mecanismo de reserva puro, que se basa en el hecho de que todos los controladores de dispositivos del núcleo deben ser agradables y deben llamar request_mem_regionverifique el valor devuelto y compórtese correctamente en caso de error.

Entonces es completamente lógico que su código funcione sin request_mem_regiones solo que no cumple con las reglas de codificación del kernel.

Sin embargo, su código no cumple con el estilo de codificación del kernel. Y además, existe una infraestructura existente para manejar GPIO, llamada gpiolib, que debe usar en lugar de reasignar manualmente sus registros bancarios GPIO. ¿En qué plataforma estás trabajando?

  • ¡Gracias por la respuesta! Esto me aclara las cosas, estoy usando el beagleboard con Angstrom. Publiqué otra pregunta en grupo beagleboard y me sugirieron usar gpiolib también. Sin embargo, lo intenté #include <linux/gpio.h> o #include <asm/gpio.h> pero ambos fallaron, ¿qué debo usar en su lugar?

    – Soy un dragón rana

    13 de octubre de 2011 a las 3:31

  • Otra pregunta, cuando hago un make para compilar un módulo del kernel o un controlador, qué directorios buscará los encabezados para #include? Por ejemplo, uno de ellos será /incluirpor lo tanto #include <linux/module.h> y #include <linux/kernel.h> investigará /include/linux/; y #include <asm/io.h> investigará /incluir/asm/.

    – Soy un dragón rana

    13 de octubre de 2011 a las 3:44


  • @Petazzoni Perdón por publicar este tercer comentario, acabo de enterarme de que puedo notificar a la persona que responde mis preguntas y no pude editar los comentarios anteriores, así que tengo que publicar esto.

    – Soy un dragón rana

    14 de octubre de 2011 a las 8:21


avatar de usuario
jordi oliva

Utilizando request_mem_region() y ioremap() en los controladores de dispositivos ahora está en desuso. En su lugar, debe usar las siguientes funciones “administradas”, que simplifican la codificación del controlador y el manejo de errores:

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

Mirar diapositiva 289 de empresa bootlin curso de entrenamiento.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad