Cómo encontrar el último nodo de dispositivo agregado en Ubuntu
1. Asegúrese de colocar el código que desarrolló en la ubicación correcta en el kernel
Copie el demo_chardev.c archivo al directorio ../drivers/char/.
demo_chardev.c
[cpp] Ver copia pura
#include
#include
#include
# include
/*Estructura de definición del archivo de encabezado file_ Operations*/
#include
/*Declarar el archivo de encabezado de la función copy_too_/from_user*/
/*Declarar el archivo de encabezado */
#include
/*Declarar información relacionada con class_create y device_create*/
#include
#define DEMO_DEBUG
#ifdef DEMO_DEBUG
#define dem_dbg(fmt, arg...) printk(KERN_WARNING fmt, ##arg ) p>
#else
#define dem_dbg(fmt, arg...) printk(KERN_WARNING fmt, ##arg)
#else
#define dem_dbg(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)
#endif
#define DEVICE_COUNT 2
//* Registre el número de dispositivo principal actual ocupado por el controlador*/
static int major = 0
static int demo_open (struct inode *pnode, struct file *filp)
{
dem_dbg("[kern func]:%s mayor: %d menor: %d\n",
__FUNCTION__, imajor (pnodo), iminor(pnode) );
devuelve 0;
}
static ssize_t demo_read (archivo de estructura *filp, char __user *buf, size_t count, loff_t * offp) p>
{
unsigned char ary[100] = "¡Leíste correctamente! ";
unsigned long len = min(count, sizeof(ary)); //min es una macro utilizada para obtener el menor de dos números
int retval ;
dem_dbg("[kern func]: %s mayor: %d menor: %d\n",
__FUNCTION__, imajor(filp->f_dentry->d_inode),
iminor(filp->f_dentry->d_inode));
// f de la estructura del archivo
El miembro _flags se puede utilizar para determinar si la lectura está bloqueada y luego manejarla en consecuencia
if(copy_to_user(buf, ary, len) != 0){
retval = - EFAULT;
p>
ir a cp_err;
}
Devuelve len.
return len; // Devuelve con éxito el número de bytes realmente transferidos
cp_err:
Devuelve retval
}
estático ssize_to_user(buf, ary, len) ! p> static ssize_t demo_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
{
unsigned char ary[100] = ""; p> unsigned long len = min(count, sizeof(ary)); //min es una macro utilizada para obtener el menor de dos números
int retval
dem_dbg(" [función kern]: %s mayor: %d menor: %d\n",
__FUNCTION__, imajor(filp->f_dentry->d_inode),
iminor(filp- >f_dentry->d_inode));
if(copy_from_user(ary, buf, len) != 0){
retval = -EFAULT; cp_err;
}
printk("[msg]: contexto de escritura: %s\n",ary);
return len; el número real de bytes transferidos
cp_err:
Return retval
}
static int demo_release (struct inode *pnode, struct archivo *filp)
{
dem_dbg("[[kern func]: %s mayor: %d menor: %d\n",
__FUNCTION__ , imajor(pnode), iminor(pnode));
return 0;
}
/*@Defina la variable de estructura de operaciones file_ */ p>
estructura estática file_operaciones fops = {
.owner = ESTE_MODULE,
.read = demo_read,
.write = demo_write,
.open = demo_open ,
.release = demo_release,
};
clase de estructura estática *demo_class; static int __init drvdemo_ init(void)
{
struct dispositivo *demo_device
int
int retval
p>dem_dbg("[msg]:esta es una demostración del controlador, en la función inicial del módulo\n");
> /*Registrar la función del controlador de caracteres, devolver con éxito el número de dispositivo principal asignado dinámicamente, falla
*Devolver código de error (negativo)*
major = Register_chrdev(0, "demo_chrdev", &fops
if(mayor < 0){
retval = mayor
goto chrdev_err; p> /*Crear clase de dispositivo*/
demo_class = class_create(THIS_MODULE , "demo_class");
if(IS_ERR(demo_class)){
retval = PTR_ERR(demo_class);
goto class_err;
}
/*Crea un archivo de dispositivo y notifica al usuario que cree un dispositivo en "/dev". /" archivo de directorio, cree un archivo de dispositivo llamado demoX*/
for(i=0; i demo_device = device_create(demo_class,NULL, MKDEV(major, i), NULL, "demo%d",i); If (IS_ERR(demo_device)) { retval = PTR_ERR(demo_device); get device_err } } } return 0; device_err: while(i--) //Operación de reversión para la creación del nodo del dispositivo device_destroy( demo_class,MKDEV(major, i)); class_destroy(demo_class); //eliminar la clase de dispositivo class_err: unregister_chrdev(major, "demo_chrdev) "); unregister_chrdev(major, "demo_chrdev") "demo_chrdev"); chrdev_err: Devolución de valor; } static void __exit drvdemo_exit(void) { int i; dem_dbg("[msg]:en la función de salida del módulo \n"); /* Función para cancelar el registro del controlador de caracteres, sin valor de retorno, mayor es el número de dispositivo principal asignado*/ unregister_chrdev(major, "demo_chrdev"); /* Eliminar nodo de dispositivo y clases de dispositivo*/ for(i=0; i device_destroy(demo_class,MKDEV(major, i)); /p> class_destroy(clase_demo } module_destroy(demo_class,MKDEV(principal, i)). module_init(drvdemo_init); module_exit( drvdemo_exit); MODULE_LICENSE("Dual BSD/GPL"); //Licencia dual BSD/GPL MODULE_AUTHOR("hanbo"); //autor del módulo (opcional) MODULE_DESCRIPTION("usado para estudiar controladores de Linux"); //perfil secundario del módulo (opcional) 2. Agregar funciones de desarrollo propio a las opciones de configuración del kernel de Linux. Agregue funciones de desarrollo propio a las opciones de configuración del kernel de Linux para que los usuarios puedan seleccionar esta función Al final del archivo vi drivers/char/Konfig, agregue una opción de configuración delante del menú final [cpp ] ver copia simple configuración DEMO_CHARDEV bool "controlador demo_chardev para placas hanbo chardev" valor predeterminado ayuda Este es el controlador CHARDEV para las placas hanbo chardev. 3. Compile o modifique el Makefile según la elección del usuario y compile el código apropiado en el kernel de Linux final generado make menuconfig (agregue opciones de configuración) (si se le solicita). para encontrar la biblioteca " ncurses ", ejecute el siguiente comando: sudo apt-get install libncurses5-dev ) Controlador de dispositivo --> Dispositivo de caracteres-> [ *] controlador demo_chardev para la placa Hanbao chardev 4.vi drivers/char/Makefile Agregue el siguiente contenido: .......... p> obj-$(CONFIG_DEMO_CHARDEV) +=demo_chardev.o (agregar) obj-$(CONFIG_JS_RTC) +=js-rtc.o (self) js -rtc-y = rtc.o (self) 5. make (actualiza la imagen del kernel en la placa de desarrollo) 6. Compila de forma cruzada el programa de prueba en la placa de desarrollo ejecutar arm-linux-gcc-gcc test.c -o demo test.c [cpp] Ver copia pura #incluir #incluir #incluir int main(int argc, char *argv[ ]) { int fd1 = 0, fd2 = 0 unsigned char buf1[100] = "Soy un programa de prueba!"; unsigned char buf2[100] = {0}; int retval; //Abre el archivo del dispositivo en lectura-escritura, sin bloqueo modo fd1 = open("/dev/demo0", O_RDWR | O_NONBLOCK if(fd1 < 0){ perror("open / dev/demo1"); salió; } //Abre el archivo del dispositivo en modo de solo lectura, bloqueando modo fd2 = open ("/dev/demo1", O_RDONLY if(fd2 < 0){ perror("open /dev/); demo2"); salir; } // Éxito del archivo del dispositivo en modo de bloqueo de solo lectura. // El éxito devuelve la palabra escrita real Número de secciones, valor negativo devuelto en caso de error retval = write(fd1, buf1, strlen(buf1)+1 retval); = escribir(fd1, buf1, strlen(buf1)+ 1) strlen(buf1)+1); if(retval < 0){ perror("¡Error al escribir fd1! " "); salir; } > printf(" //Devuelve el número real de bytes leídos cuando se realiza correctamente, devuelve un valor negativo en caso de error retval = read(fd2, buf2, sizeof(buf2)); if(retval < 0){ perror( "¡Error al leer fd2!"); salir } printf(" devolver 0; salir: if(fd1 > 0) cerrar (fd1); if(fd2 > 0) cerrar(fd2 devolver -1; /p> 2. Cargue manualmente el archivo .ko del controlador 1. Compile el archivo demo_chardev.c anterior en el kernel y genere el archivo .ko 2. El archivo demo_chardev.c anterior se compila en el kernel y genera un archivo .ko Makefile [cpp] ver copia simple #Si se define KERNELRELEASE, luego Indica que la llamada al sistema es creada por el kernel #Puedes usar declaraciones integradas ifneq ($(KERNELRELEASE),) obj- m +=demo_chrdev.o # Luego la llamada al sistema es creada por el kernel else #Define y registra la ruta del código fuente del kernel KERNELDIR = /home /hanbo/linux-2.6.35.7 (su propia ruta de código fuente, 2.6.35.7 se refiere a la versión actual del kernel) #Registrar el directorio del proyecto actual PWD := $(shell pwd) Valor predeterminado: $(MAKE) -C $(KERNELDIR) M=$(PWD) módulos p> @ rm -rf *.o .t* .m* .*.cmd *.mod.c *.order *.symvers endif limpio: rm -rf *.ko *.o .t* .m* .*.cmd *.mod.c *.order *.symvers 2. Luego usa el comando para cargar el controlador .ko lsmod enumera todos los módulos del sistema actual lsmod enumera todos los módulos del sistema actual rmmod xxx desinstala el especificado módulo (sin sufijo .ko) 3. Si no se usa en su propio código compilado /*Crear clase de dispositivo* demo_class = class_create( THIS_MODULE, "demo_class"); /*Crea un archivo de dispositivo y notifica al usuario que está ubicado en el directorio "/dev/"*/ demo_device = device_create(demo_class ,NULL,MKDEV(principal, i),NULL, "demo%d",i); Luego, debe agregar el nodo del dispositivo manualmente mknod /dev/demo1 c master 0 mknod /dev/demo2 c master 1 Nota: Si rmmod: chdir (2.6.35.7): No aparece dicho archivo o directorio durante la desinstalación Luego, bajo la raíz de la placa base sistema de archivos Cree un directorio: /lib/modules/2.6.35.7 (con el mismo nombre que la versión actual del kernel) .