#include#include #include #include #include #include #include #include #include #include #include #define LED_MAJOR 0 /*预设的LED_MAJOR的主设备号*/static int led_major = LED_MAJOR;static struct class *led_drv_class;static struct class_device *led_drv_class_dev;volatile unsigned long *gpbcon = NULL ;volatile unsigned long *gpbdat = NULL ; volatile unsigned long *gpbup = NULL ;struct cdev cdev; /*cdev结构体*/ static int led_drv_open(struct inode *inode, struct file *file){ //printk("first_drv_open\n"); /* 配置GPF5,6,8,10为输出 */ *gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(8*2) | (0x3<<(10*2)))); *gpbcon |= ((0x1<<(8*2)) | (0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(10*2))); *gpbup = 0x0; printk("first_drv_open\n"); return 0;}static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos){ int val; int ret; copy_from_user(&val, buf, count) ; if (val == 1) { // 点灯 *gpbdat &= ~( (1<<5) | (1<<6) |(1<<8)| (1<<10)); printk("first_drv_write 1111111\n"); } else { // 灭灯 *gpbdat |= ( (1<<5) | (1<<6) |(1<<8)| (1<<10)); printk("first_drv_write 00000\n"); } return 0;}static struct file_operations led_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = led_drv_open, .write = led_drv_write, };/*初始化并注册cdev*/static void led_setup_cdev(void){ int err, devno = MKDEV(led_major, 0);//index 为从设备号 cdev_init(&cdev, &led_drv_fops); cdev.owner = THIS_MODULE; cdev.ops = &led_drv_fops; err = cdev_add(&cdev, devno, 1);//devno 为第一个设备号,1为数量 if (err) printk(KERN_NOTICE "Error %d adding", err);}static int led_drv_init(void){ int result; dev_t devno; devno=MKDEV(led_major,0); if(led_major)//静态申请设备号 result=register_chrdev_region(devno,1,"led1_dev"); else { result = alloc_chrdev_region(&devno,0,1,"led1_dev");//动态申请设备号 led_major = MAJOR(devno); } if(result<0) { printk (KERN_WARNING "hello: can't get major number %d\n", led_major); return result; } led_setup_cdev(); led_drv_class = class_create(THIS_MODULE, "leddrv"); if(IS_ERR(led_drv_class)) { printk("Err: failed in creating class.\n"); return -1; } led_drv_class_dev = device_create(led_drv_class, NULL, MKDEV(led_major, 0),NULL,"xyz"); /* /dev/xyz */ gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16); gpbdat = gpbcon + 1; gpbup = gpbcon + 2; return 0; }static void led_drv_exit(void){ cdev_del(&cdev); // 注销cdev unregister_chrdev_region(MKDEV(led_major,0),1);//释放设备号 //device_destroy(led_drv_class_dev,MKDEV(led_major,0)); device_unregister(led_drv_class_dev); class_destroy(led_drv_class); iounmap(gpbcon)}module_init(led_drv_init);module_exit(led_drv_exit);MODULE_LICENSE("GPL");