logo资料库

LINUX驱动程序_LED+定时器实现流水灯.doc

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
驱动程序代码如下: #include #include #include #include #include #include #include #include #include #include #include #include #define LED_MAJOR 244 #define GPBCON_CFG_VAL ( (1<<10) | (1<<12) | (1<<14) | (1<<16) ) //GPB5,6,7,8 output mode #define LED1 1 #define LED2 2 #define LED3 3 #define LED4 4 #define ON 1 #define OFF 0 static unsigned long led_major = LED_MAJOR; struct led_dev { struct cdev cdev; struct timer_list s_timer; atomic_t led_no; atomic_t sec_counter; }; struct led_dev *led_devp; volatile unsigned int *GPBCON=NULL; volatile unsigned int *GPBDAT=NULL;
static void sec_timer_handler(unsigned long arg) { int num; mod_timer(&led_devp->s_timer,jiffies+HZ); atomic_inc(&led_devp->sec_counter); num = atomic_read(&led_devp->led_no); if(num == 4) { atomic_set(&led_devp->led_no,1); } else { } } atomic_inc(&led_devp->led_no); static int led_open(struct inode *inode,struct file *filp) { struct timer_list *timer; timer = &led_devp->s_timer; init_timer(timer); timer->function = sec_timer_handler; timer->expires = jiffies+HZ; add_timer(timer); atomic_set(&led_devp->sec_counter,0); atomic_set(&led_devp->led_no,0); return 0; } static int led_release(struct inode *inode, struct file *filp) { del_timer(&led_devp->s_timer); return 0; }
static ssize_t led_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) { } int count,led_no; int result; count = atomic_read(&led_devp->sec_counter); led_no = atomic_read(&led_devp->led_no); result = (count<<3)+led_no; if(put_user(result,(int*)buf)) { return -EFAULT; } else { } return sizeof(int); static int led_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg) if( (arg > 4) || (arg < 1) ) { printk(KERN_NOTICE "Led No. Error!\n"); } switch(cmd) { case OFF: *GPBDAT |= 1<<(arg+4); break; case ON: *GPBDAT &= ~(1<<(arg+4)); break; default: printk(KERN_NOTICE "cmd error!\n"); } return 0; { }
static const struct file_operations led_fops = { .owner = THIS_MODULE, .read = led_read, .open = led_open, .ioctl = led_ioctl, .release = led_release, }; static void led_setup_cdev(struct led_dev *dev, int index) { int err,devno = MKDEV(led_major,index); cdev_init(&dev->cdev,&led_fops); dev->cdev.owner = THIS_MODULE; err = cdev_add(&dev->cdev,devno,1); if(err) { printk(KERN_NOTICE "Error %d adding %d\n",err,index); } } static int led_init(void) { int result; dev_t devno = MKDEV(led_major,0); if(led_major) result = register_chrdev_region(devno,1,"led"); else { } result = alloc_chrdev_region(&devno,0,1,"led"); led_major = MAJOR(devno);
if(result<0) { printk("register failed!"); return result; } /*涓鸿 澶囨弿杩扮粨鏋勫垎閰嶅唴瀛?/ led_devp =(struct led_dev*)kmalloc(sizeof(struct led_dev),GFP_KERNEL); if(!led_devp) { result = -ENOMEM; unregister_chrdev_region(devno,1); } memset(led_devp, 0 ,sizeof(struct led_dev)); led_setup_cdev(led_devp,0); GPBCON = (volatile unsigned int*)ioremap(0x56000010,16); GPBDAT = GPBCON+1; *GPBCON = GPBCON_CFG_VAL; *GPBDAT |= 0xf<<5; return 0; } static void led_exit(void) { cdev_del(&led_devp->cdev); kfree(led_devp); unregister_chrdev_region(MKDEV(led_major,0),1); } MODULE_LICENSE("GPL"); MODULE_AUTHOR("Vanbreaker");
module_init(led_init); module_exit(led_exit); 测试程序代码如下: #include #include #include #include #include #define ON 1 #define OFF 0 int main() { int fd; int led_no,count = 0,old_count = 0; int ret; fd = open("/dev/led_timer",O_RDWR); if(fd != -1) { while(1) { read(fd,&ret,sizeof(int)); led_no = ret&0x07; count = ret>>3; if(count != old_count) { if(led_no!=1) { ioctl(fd,OFF,led_no-1); } else { ioctl(fd,OFF,4); } ioctl(fd,ON,led_no); printf("Led NO:%d sec:%d\n",led_no,count);
old_count = count; } } printf("Cannot Open File"); } else { } }
分享到:
收藏