Linux驱动编写(蜂鸣器 杂项)

文章介绍了如何在Linux内核中编写驱动程序,通过修改GPIO5_DR寄存器控制BEEP蜂鸣器,应用层通过命令行接口发送1或0来开启或关闭蜂鸣器。同时涉及到了ioremap和iounmap函数用于地址映射和解除映射操作。
摘要由CSDN通过智能技术生成

需求:应用层输入1蜂鸣器响,输入0蜂鸣器关闭。

一、beep.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>

#define GPIO5_DR 0x020AC000
unsigned int *vir_gpio5_dr;


int misc_open(struct inode *inode,struct file *file)
{
    printk("open ok\n");
    return 0;
}

int misc_release(struct inode *inode,struct file *file)
{
    printk("close ok\n");
    return 0;
}

ssize_t misc_read(struct file *file,char __user *ubuf,size_t size,loff_t *loff_t)
{
    char kbuf[64] = "hehehe";

    if(copy_to_user(ubuf,kbuf,strlen(kbuf)) != 0)
    {
        printk("copy_to_user error\n");
        return -1;
    }

    printk("read ok\n");
    return 0;
}

ssize_t misc_write(struct file *file,char __user *ubuf,size_t size,loff_t *loff_t)
{
    char kbuf[64] = {0};
    if(copy_from_user(kbuf,ubuf,size) != 0)
    {
        printk("copy_from_user error\n");
        return -1;
    }
    printk("kbuf is %s\n",kbuf);

    if(kbuf[0] == 1)
    {
        *vir_gpio5_dr |= (1<<1);
    }else
    {
        *vir_gpio5_dr &= ~(1<<1);
    } 

    return 0;
}

struct file_operations misc_fops = {
    .owner = THIS_MODULE,
    .open = misc_open,
    .release = misc_release,
    .read = misc_read,
    .write = misc_write
};

struct miscdevice misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = "hello_misc",
    .fops = &misc_fops
};

static int misc_init(void)
{
    int ret;

    ret = misc_register(&misc_dev);

    if(ret < 0)
    {
        printk("misc register is error\n");
        return -1;
    }

    printk("misc register is succeed\n");

    vir_gpio5_dr = ioremap(GPIO5_DR,4);
    if(vir_gpio5_dr == NULL)
    {
        printk("GPIO5_DR ioremap error\n");
        return -EBUSY;
    }
    printk("GPIO5_DR ioremap OK\n");

    return 0;
}

static void misc_exit(void)
{
    misc_deregister(&misc_dev);

    iounmap(vir_gpio5_dr);

    printk("misc bye bye\n");
}


module_init(misc_init);
module_exit(misc_exit);

MODULE_LICENSE("GPL");

解释:

        1、底板原理图找到BEEP蜂鸣器的引脚名称 SNVS TAMPER1,6ULL开发手册找到这个引脚,然后对应GPIO5_1,然后找到GPIO5_DR的物理地址20A_C000,GPIO5是一个32位的寄存器。注意:因为Linux中已经有了蜂鸣器的驱动程序,所以只需要修改DR数据寄存器就可以了,我们写的驱动是基于Linux 在应用层操作硬件。

        2、添加头文件<linux/io.h>   使用 ioremap函数 物理地址 --> 虚拟地址,iounmap --> 接触虚拟地址。在Linux中只能操作虚拟地址,所以要进行转换。

        3、应用层输入1(就是在命令行执行 ./app 1),则调用 fops中的 write函数,向GPIO5 的虚拟地址的bit1位置1 打开蜂鸣器。

二、app.c文件

#include <stdio.h>

int main(int argc,char *argv[])
{
    int fd;

    char buf[64] = {0};

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

    if(fd < 0)
    {
        perror("open error");
        return fd;
    }

    buf[0] = atio(argv[1]);

    write(fd,buf,sizeof(buf));

    close(fd);

    return 0;
}

注意:atio函数是将字符串转换成int类型

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值