LED驱动,自动创建设备节点
2011-07-14 13:51
274 查看
下面是我写的LED简单驱动代码,Arm平台(lpc3250)如下实现功能:
1>把代码编译后,添加到内核模块使LED灭10秒,然后亮10秒
2>在/dev目录自动挂载LED设备节点,可以“Echo "1" >/dev/led”控制LED
3>再实现在开机自动运行,自动添加到内核中。当然是修改启动代码实现的。
4>最后我编译进内核中,下面我先把代码贴出来。
1>把代码编译后,添加到内核模块使LED灭10秒,然后亮10秒
2>在/dev目录自动挂载LED设备节点,可以“Echo "1" >/dev/led”控制LED
3>再实现在开机自动运行,自动添加到内核中。当然是修改启动代码实现的。
4>最后我编译进内核中,下面我先把代码贴出来。
/** * @:0xf4028004和0xf4028008是GPIO端口3输出与输出寄存器虚拟地址 * 地址是我直接算出来的,可以用io_p2v()函数实现 * @: __raw_writel()向地址写数据 * @: class_create()创建总线,class_destroy()删除 * @: device_create()创建设备节点,device_destroy()删除 */ #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/errno.h> #include <linux/device.h> #include <linux/miscdevice.h> #include <linux/platform_device.h> #include <linux/types.h> #include <linux/io.h> #include <linux/delay.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <asm/uaccess.h> #include <mach/irq.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/page.h> #include <mach/hardware.h> #include <mach/platform.h> #include <mach/lpc32xx_gpio.h> #define DEVNAME "LED" #define LED_MAJOR 251 #define P3_SET ((volatile unsigned int) 0xf4028004) #define P3_CLR ((volatile unsigned int) 0xf4028008) struct led_dev { struct cdev cdev; unsigned int value; }; struct led_dev *led_dev; int led_open(struct inode *inode, struct file *filp) { struct led_dev *dev; dev = container_of(inode->i_cdev, struct led_dev, cdev); filp->private_data = dev; try_module_get(THIS_MODULE); return 0; } int led_release(struct inode *inode, struct file *filp) { module_put(THIS_MODULE); return 0; } static int led_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct led_dev *dev = filp->private_data; if(copy_from_user(&(dev->value), buf , 1)) { return -EFAULT; } if(dev->value == 1) __raw_writel(1 << 5, P3_SET); else __raw_writel(1 << 5, P3_CLR); return 1; } int led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct led_dev *dev = filp->private_data; switch (cmd) { case 0: dev->value = 0; __raw_writel(1 << 5, P3_CLR); break; case 1: dev->value = 1; __raw_writel(1 << 5, P3_SET); break; default : dev->value = 1; __raw_writel(1 << 5, P3_SET); break; } return 0; } struct file_operations led_fops = { .owner = THIS_MODULE, .write = led_write, .ioctl = led_ioctl, .open = led_open, .release = led_release, }; static void led_setup_cdev(struct led_dev *dev, int index) { int err, devno = MKDEV(LED_MAJOR, 0); cdev_init(&dev->cdev, &led_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &led_fops; err = cdev_add(&dev->cdev, devno, 1); if(err) printk(KERN_NOTICE "Error adding LED"); } struct class *led_class; static int __init led_init(void) { int i,result; dev_t dev = MKDEV(LED_MAJOR, 0); result = register_chrdev_region(dev, 1, DEVNAME); if(result < 0) return result; led_dev = kmalloc(sizeof(struct led_dev), GFP_KERNEL); if(!led_dev) { result = ~ENOMEM; goto fail; } memset(led_dev, 0, sizeof(struct led_dev)); led_setup_cdev(led_dev, 0); led_class = class_create(THIS_MODULE, "led_class"); device_create(led_class, NULL, MKDEV(LED_MAJOR, 0), "LED","LED%d", 0); __raw_writel(1 << 5, P3_SET); for(i = 0; i< 5; i++) { msleep(1000); } __raw_writel(1 << 5, P3_CLR); for(i = 0; i < 10; i++) { msleep(1000); } __raw_writel(1 << 5, P3_SET); return 0; fail: unregister_chrdev_region(dev, 1); return result; } static void __exit led_exit(void) { cdev_del(&led_dev->cdev); device_destroy(led_class, MKDEV(LED_MAJOR, 0)); class_destroy(led_class); kfree(led_dev); unregister_chrdev_region(MKDEV(LED_MAJOR, 0), 1); } module_init(led_init); module_exit(led_exit); MODULE_LICENSE("GPL"); |
相关文章推荐
- Linux驱动开发之四-----LED改进测试(增加自动创建设备节点)
- TQ2440 LINUX 2.6.30.4 LED驱动感言,从最初的打印字符,到自动分配设备号,到自动创建设备节点,到此设备号分控led
- TQ2440 LINUX 2.6.30.4 LED驱动感言,从最初的打印字符,到自动分配设备号,到自动创建设备节点,到次设备号分控led
- LED驱动,自动创建设备节点 - 嵌入…
- led驱动_自动创建设备节点
- linux字符设备驱动中自动创建设备节点
- 【Linux驱动】自动创建设备节点
- 6410之驱动的一些优化(自动创建/dev设备节点)
- linux驱动开发之自动创建设备节点的方法
- linux字符设备驱动:自动创建设备及其节点
- Linux内核驱动自动创建设备节点文件
- Linux驱动开发--自动创建设备文件节点
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- 设备驱动-----自动创建节点
- linux字符设备驱动总结之:全自动创建设备及节点
- linux字符驱动之自动创建设备节点
- 驱动中使用class_device_create()报错的原因,自动创建设备节点
- 一步一步学习 Linux 驱动之自动创建设备节点
- linux字符设备驱动 自动创建设备节点的的方法
- linux驱动之自动创建设备节点