Automatically create device nodes class_create and device_create

Source: Internet
Author: User

When you start learning to drive, you need Mknod/dev/timer C 500 0 To create a device node manually; The Linux kernel actually provides a set of functions that can be used to automatically create the corresponding device node in the/dev directory when the driver module is loaded. and delete the node at the time of the download .


Device_create (struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *FMT, ... ) paired with Device_destroy (struct class *class,dev_t devt)

Class_create (owner, name) and Class_destroy (struct class *cls);





Code implementation:

/*

*************************************************************************

Environment: Ubuntu 12.04

Cross-compilation tool:arm-none-linux-gnueabi-

Development Board: exynos4412

***********************************************************************************

*/

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>//character device header files

#include <asm/uaccess.h>

#include <linux/timer.h>

#include <linux/device.h>


#define MA 300//main device number


struct class *my_class; Define a class for Udev to automatically create a node



Module_license ("Dual BSD/GPL"); Module License Statement One of three elements


int timer_major=ma; The main device number is used to distinguish different kinds of devices


Timer Device Structure Body

struct Timer_dev {

struct Cdev Cdev; Cdev Structural Body

int counter; How many seconds did you go through?

struct Timer_list s_timer;//device to use timers

}timer_dev;

Timer handler function

static void Timer_handle (unsigned long arg) {

Mod_timer (&timer_dev.s_timer,jiffies+hz);

timer_dev.counter++;

PRINTK (kern_notice "Current jiffies%d\n", jiffies);

}


File Open function

int Timer_open (struct inode *inode,struct file *filp) {

Initialize Timer

Init_timer (&timer_dev.s_timer); Initialize Timer

Timer_dev.s_timer.function=timer_handle; specifying timer handler functions

Timer_dev.s_timer.expires=jiffies+hz; //


Add_timer (&timer_dev.s_timer);//Add Registration Timer

timer_dev.counter=0; Count zeroing

return 0;

}

File Close function

int timer_release (struct inode *inode,struct file *filp) {

Del_timer (&timer_dev.s_timer);

PRINTK ("timer release \ n");

return 0;

}

File Read function

Static ssize_t timer_read (struct file * Filp,char __user *buf,size_t count,loff_t *ppos) {

if (Put_user (timer_dev.counter, (int *) BUF))

Return-efault;

Else

return sizeof (unsigned int);

}

File Operation structure Body

static const struct File_operations Timer_fops = {

. owner = This_module,

. Open = Timer_open,

. Release = Timer_release,

. read = Timer_read,

};

Initialize and register Cdev

static void Timer_setup_cdev (struct Timer_dev *dev,int index) {

int Err,devno =mkdev (timer_major,index); Get the device number

Cdev_init (&dev->cdev,&timer_fops); Character Device Initialization

Err=cdev_add (&dev->cdev,devno,1); Add a character device to the system

if (ERR)//anomaly judgment

{

PRINTK (kern_notice "Error%d adding led%d", err,index);

}

}


Device Driver Module load function

int Timer_init (void) {


int ret;

dev_t devno =mkdev (timer_major,0); Get the device number

/*

*mkdev (major,min);

*major: What type of device does the main device number refer to?

*min: Secondary device number refers to which device is specific

*/

Ret=register_chrdev_region (devno,1, "Timmer");//Registered device number

/*

* Register a character device number (statically assigned)

* Get one or more device numbers for one character drive

*register_chrdev_region (Dev_id,device_num,device_name);

*DEV_ID assigned starting device number (typically 0)

*device_num: Total number of connected device numbers requested (not too large to avoid other major device number conflicts)

*device_name: is the device name that should be connected to this number

*/

if (ret<0)

return ret;

Timer_setup_cdev (&timer_dev,0); Initialize handler function

Automatically create a device node

My_class=class_create (This_module, "timer");

if (Is_err (My_class)) {

PRINTK ("err:failed in creating class.\n");

return-1;

}

Register this device node

Device_create (My_class,null,devno,null, "Timer_dev");

PRINTK ("Timer init, ok\n");

return 0;

}

Device Driver module unload function

void Timer_exit (void) {

dev_t devno =mkdev (timer_major,0); Get the device number


Cdev_del (&timer_dev.cdev);

Device_destroy (MY_CLASS,DEVNO); Unregister This device node

Class_destroy (My_class); //Delete a device node

Unregister_chrdev_region (MKDEV (timer_major,0), 1);//Release device number

PRINTK ("Timer exit ok\n");

}

Module_init (Timer_init); Module loading entry declaration one of three elements

Module_exit (Timer_exit); Module unload entry declaration one of three elements

Execution Result:

[[email protected]] #ls

A.out Dev lib mnt root sys timer.o usr

Bin etc LINUXRC proc Sbin Timer.ko tmp var

Load the Drive module:

[[email protected]] #insmod Timer.ko

[47.760000] Timer init OK

View Driver Module Load Information

[[email protected]] #lsmod

Timer 2172 0-live 0xbf000000 (O)

View the automatically created device nodes

[[email protected]] #ls-l/dev/timer_dev

CRW-RW----1 0 0, 0 Jan 1 00:00/dev/timer_dev

You can see that the automatic creation of the device node succeeded

To unload the drive module:

[[email protected]] #rmmod timer

[243.960000] Timer exit OK

can also be successfully loaded again

[[email protected]] #insmod Timer.ko

[304.940000] Timer init OK


If no pairing is used, the reload will be error-free

Class_destroy (My_class); //Delete a device node

I'm going to block this line and see how the results work.

[[email protected]] #insmod Timer.ko

[445.950000] Timer init OK

[[email protected]] #rmmod Timer.ko

[[email protected]] #insmod Timer.ko

Insmod:can ' t insert ' Timer.ko ': File exists

This error occurs when loading.


Block the next two lines

Device_destroy (MY_CLASS,DEVNO); Unregister This device node

Class_destroy (My_class); //Delete a device node

Results:


[[email protected]] #insmod Timer.ko

[58.595000] Timer init OK

[[email protected]] #ls-l/dev/timer_dev

CRW-RW----1 0 0, 0 Jan 1 00:00/dev/timer_dev

[[email protected]] #rmmod timer

[84.430000] Timer exit OK

The first time there is no problem loading, uninstall when the problem comes, you can see that the display is successful, but look at the following query, is not deleted successfully


[[email protected]] #ls-l/dev/timer_dev

CRW-RW----1 0 0, 0 Jan 1 00:00/dev/timer_dev

The following issue occurs when you load this

[[email protected]] #insmod Timer.ko

[103.780000]------------[Cut here]------------

[103.785000] warning:cpu:0 pid:1203 at fs/sysfs/dir.c:52 sysfs_warn_dup+0x68/0x84 ()

[103.795000] sysfs:cannot create duplicate filename '/class/timer '

[103.800000] Modules linked In:timer (o+) [Last Unloaded:timer]

[103.805000] cpu:0 pid:1203 comm:insmod tainted:g O 3.14.0 #2

[103.810000] [<c0013e10>] (unwind_backtrace) from [<c0011240>] (show_stack+0x10/0x14)

[103.820000] [<c0011240>] (show_stack) from [<c03b874c>] (DUMP_STACK+0X64/0XB4)

[103.825000] [<c03b874c>] (dump_stack) from [<c001ce74>] (warn_slowpath_common+0x68/0x88)

[103.835000] [<c001ce74>] (Warn_slowpath_common) from [<c001cf28>] (warn_slowpath_fmt+0x30/0x40)

[103.845000] [<c001cf28>] (warn_slowpath_fmt) from [<c01092e8>] (sysfs_warn_dup+0x68/0x84)

[103.850000] [<c01092e8>] (sysfs_warn_dup) from [<c0109388>] (sysfs_create_dir_ns+0x84/0x8c)

[103.860000] [<c0109388>] (Sysfs_create_dir_ns) from [<c01d6240>] (KOBJECT_ADD_INTERNAL+0X9C/0X2C0)

[103.870000] [<c01d6240>] (kobject_add_internal) from [<c01d6484>] (kset_register+0x20/0x3c)

[103.880000] [<c01d6484>] (kset_register) from [<c02482b8>] (__class_register+0xac/0x198)

[103.885000] [<c02482b8>] (__class_register) from [<c02483e4>] (__class_create+0x40/0x6c)

[103.895000] [<c02483e4>] (__class_create) from [<bf004168>] (init_module+0x6c/0xec [timer])

[103.900000] [<bf004168>] (init_module [timer]) from [<c00087b4>] (do_one_initcall+0x30/0x144)

[103.910000] [<c00087b4>] (Do_one_initcall) from [<c0074f9c>] (load_module+0x173c/0x1c68)

[103.920000] [<c0074f9c>] (load_module) from [<c00755a4>] (SYS_INIT_MODULE+0XDC/0XE0)

[103.925000] [<c00755a4>] (sys_init_module) from [<c000e420>] (ret_fast_syscall+0x0/0x30)

[103.935000]---[end trace 11ebc48fbb16ce8a]---

[103.940000]------------[Cut here]------------

[103.945000] warning:cpu:0 pid:1203 at lib/kobject.c:240 kobject_add_internal+0x238/0x2c0 ()

[103.950000] kobject_add_internal failed for timer with-eexist, and don ' t try to register things with the same name in the Same directory.

[103.965000] Modules linked In:timer (o+) [Last Unloaded:timer]

[103.970000] cpu:0 pid:1203 comm:insmod tainted:g W O 3.14.0 #2

[103.975000] [<c0013e10>] (unwind_backtrace) from [<c0011240>] (show_stack+0x10/0x14)

[103.985000] [<c0011240>] (show_stack) from [<c03b874c>] (DUMP_STACK+0X64/0XB4)

[103.990000] [<c03b874c>] (dump_stack) from [<c001ce74>] (warn_slowpath_common+0x68/0x88)

[104.000000] [<c001ce74>] (Warn_slowpath_common) from [<c001cf28>] (warn_slowpath_fmt+0x30/0x40)

[104.010000] [<c001cf28>] (warn_slowpath_fmt) from [<c01d63dc>] (KOBJECT_ADD_INTERNAL+0X238/0X2C0)

[104.020000] [<c01d63dc>] (kobject_add_internal) from [<c01d6484>] (kset_register+0x20/0x3c)

[104.025000] [<c01d6484>] (kset_register) from [<c02482b8>] (__class_register+0xac/0x198)

[104.035000] [<c02482b8>] (__class_register) from [<c02483e4>] (__class_create+0x40/0x6c)

[104.040000] [<c02483e4>] (__class_create) from [<bf004168>] (init_module+0x6c/0xec [timer])

[104.050000] [<bf004168>] (init_module [timer]) from [<c00087b4>] (do_one_initcall+0x30/0x144)

[104.060000] [<c00087b4>] (Do_one_initcall) from [<c0074f9c>] (load_module+0x173c/0x1c68)

[104.065000] [<c0074f9c>] (load_module) from [<c00755a4>] (SYS_INIT_MODULE+0XDC/0XE0)

[104.075000] [<c00755a4>] (sys_init_module) from [<c000e420>] (ret_fast_syscall+0x0/0x30)

[104.085000]---[end trace 11ebc48fbb16ce8b]---

[104.085000] err:failed in creating class.

Insmod:can ' t insert ' Timer.ko ': Operation not permitted

[[Email protected]]#


Summary: In the driver writing, many functions are used in pairs, need to pay special attention to the general application is released, there is a new delete

Automatically create device nodes class_create and device_create

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.