基于ARM-contexA9蜂鸣器驱动开发
扫描二维码
随时随地手机看文章
上次,我们写了一个LED的驱动程序,这一节,我们只需稍微改动一下就可以实现蜂鸣器的驱动,让我们来看看吧。
还是跟之前一样,先找电路图,找到电路板上对应的引脚和相关联的寄存器。
1、看电路图
(1)蜂鸣器接口位于电路板的底板,看电路图可知道是高电平有效。
(2)相对应的找到核心板的接口。由此可知,我们的蜂鸣器是GPD0_0
接下来找数据手册,找到对应的寄存器,然后配置它就可以了。
2、查数据手册,找到相关的寄存器,并配置
(1)找到GPD0CON,地址是0x114000A0,我们需要配置GPD0CON(0)为输出状态。也就是写0x1这个值到这个寄存器。
(2)找到GPD0DAT这个寄存器,用于配置蜂鸣器的高低电平,物理地址是0x114000A4,刚好与上一个差4个字节的偏移
我们只要对这个寄存器写1和写0,那么蜂鸣器就可以叫起来了,哈哈。是不是很简单?
3、开始写驱动程序。
[plain] view plain copy print?
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#define DEV_NAME "test-dev"
//定义蜂鸣器配置IO的地址
#define GPD0CON 0x114000A0
volatile unsigned long *bell_config = NULL ;
volatile unsigned long *bell_dat = NULL ;
int bell_open(struct inode *inode, struct file *filp)
{
printk("bell_open\n");
//清寄存器
*bell_config &= ~(0xf);
//设置io为输出
*bell_config |= (0x1);
return 0;
}
int bell_close(struct inode *inode, struct file *filp)
{
printk("bell_close\n");
//关闭蜂鸣器
*bell_dat &= ~0x1 ;
return 0;
}
long bell_ioctl(struct file *filp, unsigned int request, unsigned long arg)
{
//控制蜂鸣器的状态
switch(request)
{
case 0:
printk(KERN_EMERG"bell on\n");
*bell_dat |= 0x1 ;
break;
case 1:
printk(KERN_EMERG"bell off\n");
*bell_dat &=~0x1 ;
break;
}
return 0 ;
}
struct file_operations fops = {
.owner = THIS_MODULE ,
.open = bell_open,
.release = bell_close,
.unlocked_ioctl = bell_ioctl,
};
int major ;
int test_init(void)
{
printk("bell_init\n");
//注册设备
major = register_chrdev(major, DEV_NAME, &fops);
//映射IO
bell_config = (volatile unsigned long *)ioremap(GPD0CON , 16);
//加4个字节偏移到GP0DAT顺便映射该物理地址
bell_dat = bell_config + 1 ;
return 0;
}
void test_exit(void)
{
printk("bell_exit\n");
//解除注册
unregister_chrdev(major, DEV_NAME);
//取消映射
iounmap(bell_config);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Y.X.YANG");
MODULE_VERSION("2016.1.16");</span>
4、写测试程序
[plain] view plain copy print?
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int fd;
//打开设备
fd = open("/dev/test-dev",O_RDWR) ;
if(-1 == fd)
{
printf("open fair!\n");
return -1 ;
}
while(1){
//打开蜂鸣器
ioctl(fd,1);
sleep(1);
//关闭蜂鸣器
ioctl(fd,0);
sleep(1);
}
return 0;
}</span>
5、编写makefile
[plain] view plain copy print?
obj-m += bell.o
ROOTFS = /disk/A9/filesystem
KERNEL = /disk/A9/linux-3.5/
all:
make -C $(KERNEL) M=`pwd` modules
clean:
make -C $(KERNEL) M=`pwd` clean
rm -rf my_bell
install:
make -C $(KERNEL) M=`pwd` modules_install INSTALL_MOD_PATH=$(ROOTFS)
my_bell:
arm-linux-gcc my_bell.c -o my_bell
</span>
6、编译
7、查看设备主设备号,这里就省略图了,我们得到主设备号是250 cat /proc/devices
8、创建设备节点 mknod /dev/test-dev c 250 0
9、开始执行
由于蜂鸣器的现象没有实质的效果展示,只能通过终端打印,如有兴趣,自己去尝试,用其它板子也可以,就照着我这个方法写驱动,一定成功的!
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!