misc(杂项设备类)
struct miscdevice {
int minor; // 次设备号
const char *name; // 设备名
const struct file_operations *fops; // 操作方法
struct list_head list;
struct device *parent; // 私有指针
struct device *this_device; // 指向自己的指针
const char *nodename;
mode_t mode;
struct miscdevice {
int minor; // 次设备号
const char *name; // 设备名
const struct file_operations *fops; // 操作方法
struct list_head list;
struct device *parent; // 私有指针
struct device *this_device; // 指向自己的指针
const char *nodename;
mode_t mode;
};
extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice *misc);
实例:
misc.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#define LED_ON 0
#define LED_OFF 1
struct resource *ptr = NULL;
unsigned long *gpj2con = NULL;
int led_open(struct inode *inode, struct file *file)
{
printk("led init ....\n");
int val;
/* led init */
val = ioread32(gpj2con);
val &=~(0xF<<0);
val |=(0x1<<0);
iowrite32(val,gpj2con);
val = ioread32(gpj2con+1);
val |=(0x1<<0);
iowrite32(val,gpj2con+1);
printk("debug_001\n");
return 0;
}
int led_close(struct inode *inode, struct file *file)
{
printk("led close ....\n");
return 0;
}
void led_on()
{
int val;
val = ioread32(gpj2con+1);
val &=~(0x1<<0);
iowrite32(val,gpj2con+1);
}
void led_off()
{
int val;
val = ioread32(gpj2con+1);
val |=(0x1<<0);
iowrite32(val,gpj2con+1);
}
int led_ioctl(struct inode *inode,struct file *file,int cmd,int arg)
{
switch(cmd){
case LED_ON:
led_on();
break;
case LED_OFF:
led_off();
break;
}
}
struct file_operations led_fops = {
.open = led_open,
.release = led_close,
.ioctl = led_ioctl,
};
struct miscdevice led_miscdev ={
.minor = 138,
.name = "led-misc",
.fops = &led_fops,
};
int led_platdev_probe(struct platform_device *pdev)
{
printk("led driver entry>>>>>>>\n");
int val;
int phys_addr = pdev->resource[0].start; // =0xe0200280
ptr = request_mem_region(phys_addr,0x1000,"led-drv");
if(ptr == NULL)
{
printk("request_mem_region\n");
return -1;
}
gpj2con = (unsigned long*)ioremap(phys_addr,0x1000);
if(gpj2con == NULL)
{
printk("ioremap fail\n");
return -1;
}
val = misc_register(&led_miscdev);
if(val < 0)
{
printk("misc register fail\n");
return -1;
}
return 0;
}
int led_platdev_remove(struct platform_device *pdev)
{
misc_deregister(&led_miscdev);
iounmap(gpj2con);
release_mem_region(0xe0200280,0x1000);
}
struct platform_driver led_platdrv ={
.driver = {
.name = "led-dev-drv",
},
.probe = led_platdev_probe,
.remove = led_platdev_remove,
};
int __init led_platdrv_init()
{
printk("led plat drv init \n");
platform_driver_register(&led_platdrv);
return 0;
}
void __exit led_platdrv_exit()
{
printk("usb drv mouse exit \n");
platform_driver_unregister(&led_platdrv);
}
module_init(led_platdrv_init);
module_exit(led_platdrv_exit);
MODULE_LICENSE("xx");
MODULE_AUTHOR("xx");
MODULE_DESCRIPTION("xx..");
加载这个杂项类设备驱动,在对应的杂项类cat /sys/class/misc也可以看到创建的。
需要上一篇的insmod dev.c和应用程序测试。
这样你也可以比较上一篇的pdrv.c的设备类。
类都帮我们创建好了设备节点,所以可以直接./app运行测试。