关键词:Android linux hrtimer 蜂鸣器 等待队列 信号量 字符设备
平台信息:
内核:linux3.4.39
系统:android/android5.1
平台:S5P4418
作者:庄泽彬(欢迎转载,请注明作者)
邮箱:2760715357@qq.com
程序描述:本文控制的设备是无源蜂鸣器,由于无源蜂鸣器是需要产生一定的频率的PWM才能够控制蜂鸣器,不像有源蜂鸣器,只需要提供高低电平就可以控制蜂鸣器。linux内核普通的定时器,由于具有一定的局限性,不能达到纳秒级别的定时,使用普通的定时器模拟GPIO口产生PWM会导致蜂鸣器出现杂音,因此要使用hrtimer高精度定时器模拟GPIO口产生PWM可以极大的改善性能。使用信号量sem只是为了避免多个应用程序打开设备,使用等待队列是为了让程序可以按照指定的方式去运行,如果不加等待队列,在启动hrtimer定时器之后就会不会等待定时器完成之后在关闭设备,因此需要加入等待队列,等待定时器定时的工作完成之后再唤醒等待队列。虽然程序可以使用GPIO模拟PWM产生一定频率的信号去控制无源蜂鸣器,但是还是存在一定的局限性,因为定时器也是加入内核进行调度,所以有可能杂定时的时候会导致输出的PWM被打断,导致杂音的出现。因此严格来说不能完整的输出一段不被打断模拟PWM信号。如果有什么好方法可以实现的话,可以共同探讨。好吧不说了上代码吧。
无源蜂鸣器的驱动程序(代码写的一般般如有不对,欢迎指点)
buzzer_driver.c
1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/fs.h>
4 #include <linux/device.h>
5 #include <linux/slab.h>
6 #include <linux/cdev.h>
7 #include <linux/interrupt.h>
8 #include <linux/gpio.h>
9 #include <linux/input.h>
10 #include <linux/sched.h>
11 #include <linux/wait.h>
12 #include <linux/delay.h>
13 #include <linux/semaphore.h>
14
15 #include <asm/uaccess.h>
16 #include <asm/io.h>
17
18 #include <mach/platform.h>
19
20 #define BUZZER_DEVICE_NAME "mybuzzer"
21 #define BUZZER_CLASS_NAME "mybuzzer" //sys/class/mybuzzer
22 #define BUZZER_DEVICE_NUM 1 //设备节点的编号最终生成节点的名字为/dev/buzzer-1
23
24
25 #define BUZZER_GPIO_SWITCH 1 //是否设置buzzer的gpio的初始化,另一个驱动已经初始化GPIO
26 #define BUZZER_DELAY_TIME_HIGHT (190000) //2.7KHZ
27 #define BUZZER_DELAY_TIME_LOW (190000) //2.7KHZ
28 #define DE_BUG 1
29
30 #if DE_BUG
31 #define prdebug(fmt,arg...) printk("zbzhuang"KERN_ERR fmt"\n",##arg)
32 #else
33 #define prdebug(fmt,arg...) do{}while(0);
34 #endif
35
36
37
38 typedef enum {
39 BUZZER_DISABLE = 0,
40 BUZZER_ENABLE,
41 }BUZZER_STATUS_t;
42
43 //buzzer的设备对象
44 struct buzzer_chip{
45