linux设备驱动学习笔记7------led流水灯的驱动编写

 

http://bbs.ednchina.com/BLOG_ARTICLE_297038.HTM

本实验的基于sep4020EVB 1.5开发板的一个小实验,实现流水灯的功能。


利用的端口是GPB0-GPB4 这5个端口


底层的驱动程序:


#include <linux/module.h>


#include <linux/types.h>


#include <linux/fs.h>


#include <linux/errno.h>


#include <linux/mm.h>


#include <linux/sched.h>


#include <linux/init.h>


#include <linux/cdev.h>


//#include <linux/interrupt.h>


 


#include <linux/delay.h>


#include <asm/system.h>


#include <asm/uaccess.h>


#include <asm/io.h>


#include <asm/hardware.h>


 


#define KEY_MAJOR 211


#define flowled_cmd0 1


 


 


unsigned int i="0";


unsigned int j="0";


 


struct flowled_dev


{


       struct cdev cdev;


       unsigned char value;


};


 


struct flowled_dev *flowleddev;


 


int sep4020_flowled_open(struct inode *inode, struct file *filp)


{


       return 0;


}


 


int sep4020_flowled_release(struct inode *inode, struct file *filp)


{


       return 0;


}


 


static ssize_t sep4020_flowled_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)


{


      


       return 0;


}


 


static ssize_t sep4020_flowled_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)


{


       return 0;


}


 


int sep4020_flowled_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)


{


       switch (cmd)


       {


              case flowled_cmd0:


                    


              {


              for(i=0;i<5;i++)


      


{*(volatile unsigned long*)GPIO_PORTB_DATA_V=((*(volatile unsigned long*)GPIO_PORTB_DATA_V) & (0xffe0)) | i;


  for(j=0;j<4000;j++);


 


}           


                     break;


                     }


             


              default:


                     return -ENOTTY;


       }


      


       return 0;


}


 


static const struct file_operations sep4020_flowled_fops =


{


       .owner = THIS_MODULE,


       .read  = sep4020_flowled_read,


       .write = sep4020_flowled_write,


       .ioctl = sep4020_flowled_ioctl,


       .open  = sep4020_flowled_open,


       .release = sep4020_flowled_release,


};


 


 


static void sep4020_flowled_setup(void)


{


             *(volatile unsigned long*)GPIO_PORTB_SEL_V |= (0x001f); //作为通用用途


              *(volatile unsigned long*)GPIO_PORTB_DIR_V &= (0xffe0);//输出


        


}


 


static int __init sep4020_flowled_init(void)


{


       int err,result;


       dev_t devno = MKDEV(KEY_MAJOR, 0);


       if(KEY_MAJOR)


              result = register_chrdev_region(devno, 1, "sep4020_flowled");


       else


       {


              result = alloc_chrdev_region(&devno, 0, 1, "sep4020_flowled");             


       }


      


       if(result < 0)


              return result;


      


       /*动态申请设备结构体的内存*/


       flowleddev = kmalloc(sizeof(struct flowled_dev),GFP_KERNEL);


       if (!flowleddev)


       {


              result = -ENOMEM;


              goto fail_malloc;


       }


       memset(flowleddev,0,sizeof(struct flowled_dev));


       /*注册中断函数*/


       /*对键盘进行初始化*/


 


       sep4020_flowled_setup();


       cdev_init(&(flowleddev->cdev), &sep4020_flowled_fops);


       flowleddev->cdev.owner = THIS_MODULE;


       err = cdev_add(&flowleddev->cdev, devno, 1);


       if(err)


              printk("adding err\r\n"); 


       return 0;


      


       fail_malloc: unregister_chrdev_region(devno,1);


       return result;


}


 


static void __exit sep4020_flowled_exit(void)


{


       printk("sep4020_flowled_exit\n");


       unregister_chrdev_region(KEY_MAJOR,1);


}


 


module_init(sep4020_flowled_init);


module_exit(sep4020_flowled_exit);


 


MODULE_AUTHOR("scx");


MODULE_LICENSE("GPL");


上层的应用程序如下:


#include <stdio.h>


#include <string.h>


#include <stdlib.h>


#include <unistd.h>


#include <sys/types.h>


#include <sys/stat.h>


#include <fcntl.h>


 


#define DEVICE_NAME "/dev/sep4020_flowled"


#define flowled_cmd0 1


int main(void)


{


int fd;


printf("\n start sep4020_flowled test\n\n");


 


fd=open("/dev/sep4020_flowled",O_RDONLY);


printf("fd=%d\n",fd);


if(fd==-1)     


   {       


       printf("wrong\r\n");         


       exit(-1);   


}


else


{


while(1)


{


      ioctl(fd,flowled_cmd0);


     


}


}


close(fd);


printf("\n close sep4020_flowled test!!!\n\n");


return 0;


}


你可能感兴趣的:(linux设备驱动学习笔记7------led流水灯的驱动编写)