I am trying to create a character device driver (kernel module). The modue gets loaded, creates the character device as can be seen below:
root@imx6x-std:~# ls -l /dev/socledchrdevregion
crw-rw-rw- 1 root root 246, 0 Jan 1 08:56 /dev/socledchrdevregion
But when i try to open the device using a test application (the open function inside the driver doesn't do anything special apart from printing a debug message), i get an error:
root@imx6x-std:~# ./led_ioctltest
led_ioctltest: open /dev/socledchrdevregion failed due to No such device or addres
Following is the content of /proc/devices:
root@imx6x-std:~# cat /proc/devices
Character devices:
1 mem
5 /dev/tty
5 /dev/console
5 /dev/ptmx
10 misc
13 input
29 fb
81 video4linux
89 i2c
90 mtd
116 alsa
128 ptm
136 pts
153 spi
180 usb
189 usb_device
199 galcore
207 ttymxc
244 vuc_sim
245 vuc
246 socledchrdevregion
247 ubi0
248 mxc_src
249 mxc_vpu
250 conti_kmod_tracing
251 mxc_ipu
252 ptp
253 pps
254 rtc
Block devices:
259 blkext
31 mtdblock
179 mmc
The device is present with major number is 246.
This is the way i try to open the device:
#define DEVICE "/dev/socledchrdevregion"
fd = open(DEVICE, O_RDONLY);
This is a snippet of the LKM:
if ((ret = alloc_chrdev_region(&first, 0, 1, DEVICE_NAME)) < 0)
{
printk(KERN_ERR PRINTK_CONTEXT": FAILED TO ALLOCATE CHRDEVREGION \n");
return -1;
}
printk(KERN_INFO PRINTK_CONTEXT": ALLOCATE CHRDEVREGION SUCCESS \n");
classptr = class_create(THIS_MODULE, "socledclass");
device_create(classptr, NULL, first, NULL, DEVICE_NAME);
printk(KERN_INFO "PRINTK_CONTEXT: DEVICE CREATED \n");
led_cdevptr = cdev_alloc();
led_cdevptr->ops = &led_fops;
Could anyone please help me in finding the error? I will post the complete code if necessary.
You have registered your device with sysfs, which causes it to become visible (and for udev to create the device file). You did not, however, register the actual device. You got a major minor assigned, but they are not connected to your driver.
In all likelihood, you have skipped calling cdev_add
.
In a nutshell, the sequence is:
alloc_chrdev_region
gives you a range of major/minor device IDs you can use, that are guaranteed to be only for your device.
cdev_add
register actual handlers for those IDs (you can call it without calling alloc_chrdev_region
if your device has a preallocated region set to it, such as /dev/null or /dev/random).