基于ARM-contexA9蜂鸣器驱动开发

简介: 基于ARM-contexA9蜂鸣器驱动开发

上次,我们写了一个LED的驱动程序,这一节,我们只需稍微改动一下就可以实现蜂鸣器的驱动,让我们来看看吧。

    还是跟之前一样,先找电路图,找到电路板上对应的引脚和相关联的寄存器。

    1、看电路图0.gif

    (1)蜂鸣器接口位于电路板的底板,看电路图可知道是高电平有效。

0.png

  (2)相对应的找到核心板的接口。由此可知,我们的蜂鸣器是GPD0_0

0.png

 接下来找数据手册,找到对应的寄存器,然后配置它就可以了。

 2、查数据手册,找到相关的寄存器,并配置0.gif

(1)找到GPD0CON,地址是0x114000A0,我们需要配置GPD0CON(0)为输出状态。也就是写0x1这个值到这个寄存器。

640.jpg

(2)找到GPD0DAT这个寄存器,用于配置蜂鸣器的高低电平,物理地址是0x114000A4,刚好与上一个差4个字节的偏移

我们只要对这个寄存器写1和写0,那么蜂鸣器就可以叫起来了,哈哈。是不是很简单?0.gif

640.jpg

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、编译

640.jpg

7、查看设备主设备号,这里就省略图了,我们得到主设备号是250  cat /proc/devices  

8、创建设备节点  mknod  /dev/test-dev  c   250  0

9、开始执行

640.jpg

由于蜂鸣器的现象没有实质的效果展示,只能通过终端打印,如有兴趣,自己去尝试,用其它板子也可以,就照着我这个方法写驱动,一定成功的!

目录
相关文章
|
7月前
|
算法 编译器 Linux
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
138 0
|
4月前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
141 3
|
7月前
|
Linux 开发工具 芯片
玩转 PI 系列 - 如何在 Rockchip Arm 开发板上安装 Docker Tailscale K3s Cilium?
玩转 PI 系列 - 如何在 Rockchip Arm 开发板上安装 Docker Tailscale K3s Cilium?
|
7月前
|
存储 Ubuntu Linux
ARM-Linux开发与MCU开发的不同之处分析
ARM-Linux开发与MCU开发的不同之处分析
75 0
|
Linux C++
基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
137 0
|
芯片
基于友善之臂ARM-ContexA9-ADC驱动开发
基于友善之臂ARM-ContexA9-ADC驱动开发
98 0
|
缓存 C++
基于ARM-contexA9-蜂鸣器pwm驱动开发
基于ARM-contexA9-蜂鸣器pwm驱动开发
118 0
|
Linux C++ 流计算
基于ARM_contexA9 led驱动编程
基于ARM_contexA9 led驱动编程
76 0
|
算法 物联网 测试技术
开发一个arm固件加载基址定位器
最近入坑iot,涉及很多芯片固件的逆向。但是这些固件很多时候都不是标准二进制格式,也就是说丢进ida,识别不出架构和指令集。架构和指令集可以查芯片的文档,但是加载基址还没法确定,这个靠自己去定位,再配置ida。人工做这个工作太累,而我又是懒狗,所以自动化这一过程不香吗?
|
24天前
|
机器学习/深度学习 弹性计算 人工智能
阿里云服务器架构有啥区别?X86计算、Arm、GPU异构、裸金属和高性能计算对比
阿里云ECS涵盖x86、ARM、GPU/FPGA/ASIC、弹性裸金属及高性能计算等多种架构。x86架构采用Intel/AMD处理器,适用于广泛企业级应用;ARM架构低功耗,适合容器与微服务;GPU/FPGA/ASIC专为AI、图形处理设计;弹性裸金属提供物理机性能;高性能计算则针对大规模并行计算优化。