原创 linux设备驱动学习笔记8-----------蜂鸣器驱动

2009-11-30 09:08 4177 6 6 分类: MCU/ 嵌入式

/*头文件*/


#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/delay.h>


#include <asm/system.h>


#include <asm/uaccess.h>


#include <asm/io.h>


#include <asm/hardware.h>


/*一些定义*/


#define BEEP_MAJOR 245/* 主设备号*/


#define BEEP_ON 1


#define BEEP_OFF 2


/*定义了蜂鸣器操作的结构体*/


struct beep_dev


{


       struct cdev cdev;


       unsigned char value;


};


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


/*定义了蜂鸣器操作的结构体的成员*/


struct beep_dev *beepdev;


 


/*硬件初始化函数,初始化GPIO*/


static void sep4020_beep_setup(void)


{


*(volatile unsigned long*)GPIO_PORTA_SEL_V |= (0x1<<6); //作为通用用途


*(volatile unsigned long*)GPIO_PORTA_DIR_V &= ~(0x1<<6 );//输出


*(volatile unsigned long*)GPIO_PORTA_DATA_V &= ~(0x1<<6 );//初始输出拉低


}


 


/*蜂鸣器驱动的open函数*/


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


{


      


sep4020_beep_setup(); 


return 0;


}


 


/*蜂鸣器程序的relesase函数*/


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


{


       return 0;


}


/*蜂鸣器程序的readwrite函数,


因为我们不需要使用readwrite


所以直接返回0*/


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


{


       return 0;


}


 


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


{


       return 0;


}


/*应用程序就是通过调用ioctl这个函数来控制硬件*/


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


{


              switch (cmd)


       {


       case BEEP_ON:


       *(volatile unsigned long*)GPIO_PORTA_DATA_V |= 0x1<<6; //beep is open;


              break;


       case BEEP_OFF:


       *(volatile unsigned long*)GPIO_PORTA_DATA_V &= ~0x1<<6; //beep is close;


              break;


       default:


              return -ENOTTY;


       }


       return 0;


}


/*将我们自己写的文件操作函数与系统提供的函数结构想挂钩*/


static const struct file_operations sep4020_beep_fops =


{


       .owner = THIS_MODULE,


       .read = sep4020_beep_read,


       .write = sep4020_beep_write,


       .ioctl = sep4020_beep_ioctl,


       .open = sep4020_beep_open,


       .release = sep4020_beep_release,


};


 


 


/*加载驱动时执行的init函数*/


static int __init sep4020_beep_init(void)


{


       int err,result;


       dev_t devno = MKDEV(BEEP_MAJOR, 0);


       if(BEEP_MAJOR)        


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


       else


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


       if(result < 0)


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


       beepdev = kmalloc(sizeof(struct beep_dev),GFP_KERNEL);


       if (!beepdev)


       {


              result = -ENOMEM;  //如果申请失败,跳转到错误处理函数


              goto fail_malloc;


       }


       /*将结构体清空*/


       memset(beepdev,0,sizeof(struct beep_dev));


 


       /*注册设备进内核*/


       cdev_init(&(beepdev->cdev), &sep4020_beep_fops);


       beepdev->cdev.owner = THIS_MODULE;


       err = cdev_add(&beepdev->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_beep_exit(void)


{


       cdev_del(&beepdev->cdev);


       kfree(beepdev);


       unregister_chrdev_region(MKDEV(BEEP_MAJOR, 0),1);


}


 


module_init(sep4020_beep_init); //Linux系统记录设备初始化的函数名


module_exit(sep4020_beep_exit); //Linux系统记录设备退出的函数名称


 


MODULE_AUTHOR("fpmystar");


MODULE_LICENSE("GPL");


 


//-------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------


下面是一个蜂鸣器简单的测试程序:


#include <stdio.h>


#include <fcntl.h>


#define OPEN 1


#define CLOSE 2


 


int main(int argc,char **argv)


{


int fd;


int i,j;


       fd = open("/dev/beep",O_RDWR);


       if(fd == -1)


       {


              printf("wrong\r\n");


              exit(-1);


       }


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


       {


              ioctl(fd, OPEN,0);


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


              ioctl(fd, CLOSE,0);


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


       }


       close(fd);


       return 0;


}


 
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条