前言
新手小白刚刚搞过了字符设备,还不是很了解,其实最早接触的算是杂项设备了misc,但是当时看不懂操作,因此就没有采用,因为常听说的是字符设备,看到了杂项设备的操作以为是某个板子昌尚自己封装的呢。后来发现杂项设备一种驱动的形式。
杂项设备听名字就知道,不知道属于什么设备,那就归类杂类把,不好分类的一些驱动。
优点是(1)可以节省主设备号,主设备号255个.(2)驱动写法简单,不用注册主设备号
下面就是我在4412上面经过验证得到的简单额demo。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#define DEVICE_NAME "misc_leds"
// 注册的杂项设备在这里 /dev/misc_leds
static long tiny4412_leds_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
switch(cmd) {
case 0:
case 1:
printk(DEVICE_NAME"my 4412 led ioctl");
break;
default:
return -EINVAL;
}
return 0;
}
static struct file_operations tiny4412_led_dev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tiny4412_leds_ioctl,
};
static struct miscdevice tiny4412_led_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &tiny4412_led_dev_fops,
};
static int __init tiny4412_led_dev_init(void) {
int ret;
int i;
printk(DEVICE_NAME"\iiiiiiiiiiiiiiii\n");
ret = misc_register(&tiny4412_led_dev);
printk(DEVICE_NAME"\tinitialized\n");
return ret;
}
static void __exit tiny4412_led_dev_exit(void) {
int i;
printk(DEVICE_NAME"\tttttttttttttttt\n");
misc_deregister(&tiny4412_led_dev);
}
module_init(tiny4412_led_dev_init);
module_exit(tiny4412_led_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Gao Yuan");
最简单的一个杂项设备注册框架。
Makefile 内容是:
ifeq ($(KERNELRELEASE),)
PWD = $(shell pwd)
#KERNEL_DIR = /home/yuan/linux/linux-3.16.2
KERNEL_DIR = /root/linux-3.5
modules:
make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
make -C $(KERNEL_DIR) M=$(PWD) clean
else
obj-m += misc_mo_led.o
endif
app应用的内容是:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
/*
* app_mp_led on
* app_mp_led off
*/
int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/misc_leds", O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
if (argc != 2)
{
printf("Usage :\n");
printf("%s <on|off>\n", argv[0]);
return 0;
}
if (strcmp(argv[1], "on") == 0)
{
val = 1;
}
else
{
val = 0;
}
ioctl(fd, val, 4);
return 0;
}
框架简单易懂,