码迷,mamicode.com
首页 > 其他好文 > 详细

s3c2440 杂项驱动实现蜂鸣器

时间:2015-04-20 09:37:51      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:linux驱动   蜂鸣器驱动   杂项驱动   

        这个驱动本来是非常简单的,但是我就是想做个杂项驱动。

        Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述)。miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同。


蜂鸣器控制原理

       先来看下蜂鸣器的电路图:

        技术分享

        其实做了前面的LED点灯驱动,那做这个驱动就是分分钟钟的事。从上面的电路图可以知道控制蜂鸣器的引脚就是GPB0;这样就非常简单了,需要操作的就是。

1、初始化

       s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);// 设置GPBCON

       s3c2410_gpio_setpiin(S3C2410_GPB(0), 1); // 设置GPBDAT

2、根据参数开关蜂鸣器

       s3c2410_gpio_setpin(S3C2410_GPB(0), flag); // 根据flag来开关蜂鸣器;


杂项设备知识

        杂项设备结构体(杂项设备的主设备号固定为10,不同的杂项设备是通过次设备号来区分的)
struct miscdevice  {
	int minor; // 次设备号
	const char *name;// 设备名称
	const struct file_operations *fops; // 关联的操作函数
	struct list_head list;
	struct device *parent;
	struct device *this_device;
	const char *nodename;
	mode_t mode;
};
        其实从上面的结构体可以知道,杂项设备驱动只能驱动一个设备,因为杂项驱动主设备号固定为10(不同杂项设备通过次设备号来区分),而结构体中只有一个次设备号,所以可以看出杂项驱动只能驱动一个设备;如果要驱动多个设备,则不能用杂项驱动;(同类设备要靠次设备来区分)

        下面要说的两个杂项驱动操作函数都在:/devices/char/Misc.c;创建和初始化杂项驱动:int misc_register(struct miscdevice * misc);这个函数就大概相当于:字符驱动中的设备号创建,字符设备的申请和初始化等(alloc_chrdev_region()设备号申请;cdevp = cdev_alloc()申请字符结构;cdev_init(cdevp, &fops)让字符结构和操作函数绑定;cdev_add(cdevp, devNum, 1)绑定主设备号;)
        当然和创建初始化相反的就是:int misc_deregister(struct miscdevice *misc);函数了,该函数的功能和上面的创建函数相反;

驱动代码

#include<linux/init.h>
 #include<linux/module.h>
 #include<linux/fs.h>
 #include<linux/miscdevice.h>
 #include<linux/gpio.h>
 #include<mach/regs-gpio.h>
 
 #define DEV_NAME "yzhBuzzer"
 
 ssize_t myOpen(struct inode *inode, struct file *file)
 {
     printk(KERN_INFO"in myOpen!\n");
     s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
     s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
     return 0;
 }
 
 int myIoctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long  arg)
 {
     printk(KERN_INFO"in myIoctl  cmd:%u, arg:%ld\n", cmd, arg);
     if (!cmd)
         s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
     else
         s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
     return 0;
 }

 struct file_operations fop =
 {
     .owner = THIS_MODULE,
     .ioctl = myIoctl,
     .open  = myOpen,
 };
 
 static struct miscdevice misc =
 {
     .minor = MISC_DYNAMIC_MINOR,
     .name  = DEV_NAME,
     .fops  = &fop,
 };
 
 static int __init buzzer_init(void)
 {
     int ret;
     printk(KERN_INFO"buzzer init!\n");
     ret = misc_register(&misc);
     return ret;
 }

 static void __exit buzzer_exit(void)
 {
     printk(KERN_INFO"buzzer exit!\n");
     misc_deregister(&misc);
 }
 
 module_init(buzzer_init);
 module_exit(buzzer_exit);
 MODULE_LICENSE("Dual BSD/GPL");

        附上一个Makefile,现在写的驱动都是非常简单的,所以Makefile基本是可以通用的:
obj-m:=buzzer.o
 
 CC=arm-linux-gcc
 
 #KERDIR=/lib/modules/$(shell uname -r)/build
 KERDIR=/home/kernel/linux-2.6.32.2
 
 CURDIR=$(shell pwd)
 
 all:
     make -C $(KERDIR) M=$(CURDIR) modules
 
 clean:
     make -C $(KERDIR) M=$(CURDIR) clean

测试代码

        测试代码非常简单,这个驱动加载进去后会自动在dev下面创建设备文件。直接操作这个文件就可以了;因为只有一个蜂鸣器,所以用ioctl函数实现有个参数是多余的。
 #include<stdio.h>
 #include<stdlib.h>
 #include<errno.h>
 #include<fcntl.h>
 
 int main(int argc, char *argv[])
 {
     int flag = 0;
     int fd = open("/dev/yzhBuzzer", O_RDWR);
     if(fd < 0)
         printf("int open error:%d\n", errno);
     if (argc > 1)
         flag = 1;
 
     if(ioctl(fd, flag, 0) < 0)
         printf("int ioctl error:%d", errno);
     
 
     return 0;
 }

        转载请注明作者和原文出处,原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/45131611
        若有不正确之处,望大家指正,共同学习!谢谢!!!


s3c2440 杂项驱动实现蜂鸣器

标签:linux驱动   蜂鸣器驱动   杂项驱动   

原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/45131611

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!