335xGPIO型蜂鸣器控制

本文介绍了一个简单的Buzzer驱动模块的实现过程,包括模块的初始化、打开、关闭及IO控制等核心功能,并提供了完整的源代码及编译指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://bbs.elecfans.com/jishu_903104_1_1.html


buzzer_drv.h

#ifndef _BUZZER_DRV_H
#define _BUZZER_DRV_H

#define BUZZER_IOC_MAGIC 'B'
#define BUZZER_ON _IO(BUZZER_IOC_MAGIC, 1)
#define BUZZER_OFF _IO(BUZZER_IOC_MAGIC, 0)
#define BUZZER_IOCTL_MAXNR 2

#endif /*_BUZZER_DRV_H*/
~                                  

buzzer_drv.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/device.h>

#include <linux/version.h>

#include <asm/mach/arch.h>

#include <mach/hardware.h>

#include <mach/gpio.h>

#include <asm/gpio.h>

#include "buzzer_drv.h"



static int major;

static int minor;

struct cdev *buzzer; /* cdev 数据结构 */

static dev_t devno; /* 设备编号 */

static struct class *buzzer_class;

#define DEVICE_NAME "buzzer"

#define GPIO_BUZZER_PIN_NUM (0*32 + 2) /*gpio0_2 */



static int buzzer_open(struct inode *inode,struct file *file )

{

      try_module_get(THIS_MODULE);

      gpio_direction_output(GPIO_BUZZER_PIN_NUM, 1);

      return 0;

}

static int buzzer_release(struct inode*inode, struct file *file )

{

      module_put(THIS_MODULE);

      gpio_direction_output(GPIO_BUZZER_PIN_NUM, 1);

      return 0;

}



static int buzzer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

{

      if(_IOC_TYPE(cmd) != BUZZER_IOC_MAGIC) {

             return -ENOTTY;

      }

      if(_IOC_NR(cmd) > BUZZER_IOCTL_MAXNR) {

             return -ENOTTY;

      }

      switch(cmd){

             case BUZZER_ON:

             		gpio_set_value(GPIO_BUZZER_PIN_NUM, 1);

             break;

             case BUZZER_OFF:

             		gpio_set_value(GPIO_BUZZER_PIN_NUM, 0);

             break;

             default:

             break;

      }

      return 0;



	  

}



struct file_operations buzzer_fops = {

      .owner = THIS_MODULE,

      .open = buzzer_open,

      .release = buzzer_release,

      .unlocked_ioctl = buzzer_ioctl,

};



static int __init buzzer_init(void)

{

      int ret;

      gpio_free(GPIO_BUZZER_PIN_NUM);

      if(gpio_request(GPIO_BUZZER_PIN_NUM, "buzzer_bee")) {

             printk("request %s gpio faile \n", "buzzer");

             return -1;

      }

      ret = alloc_chrdev_region(&devno, minor, 1, "buzzer"); /* 从系统获取主设备号 */

             major= MAJOR(devno);

             if(ret < 0) {

             printk(KERN_ERR"cannot get major %d \n", major);

             return -1;

      }

      buzzer = cdev_alloc(); /* 分配 buzzer 结构 */

      if(buzzer != NULL) {

             cdev_init(buzzer,&buzzer_fops); /* 初始化 buzzer 结构 */

             buzzer->owner = THIS_MODULE;

             if(cdev_add(buzzer, devno, 1) != 0) { /* 增加 buzzer 到系统中 */

                    printk(KERN_ERR"add cdev error!\n");

             goto error;

      }

      }else {

             printk(KERN_ERR"cdev_alloc error!\n");

             return -1;

      }

      buzzer_class = class_create(THIS_MODULE, "buzzer_class");

      if(IS_ERR(buzzer_class)) {

             printk(KERN_INFO"create class error\n");

             return -1;

      }

      device_create(buzzer_class,NULL, devno, NULL, "buzzer");

      return 0;

      error:

      unregister_chrdev_region(devno,1); /* 释放已经获得的设备号 */

      return ret;

}



static void __exit buzzer_exit(void)

{

      cdev_del(buzzer);/* 移除字符设备 */

      unregister_chrdev_region(devno,1); /* 释放设备号 */

      device_destroy(buzzer_class,devno);

      class_destroy(buzzer_class);

}





MODULE_LICENSE("GPL");

module_init(buzzer_init);

module_exit(buzzer_exit);

MODULE_AUTHOR("Xiaoxin");

Makefile:

PWD := $(shell pwd)
ARCH=arm
CROSS_COMPILE=/home/goembed/B1/335x-B1-CROSS_COMPILE/usr/bin/arm-linux-gnueabihf-


obj-m += buzzer_drv.o

KDIR = /home/goembed/B4/project_kernel/335x-B1-LINUX/

all:
        make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
        arm-linux-gcc buzzer_test.c -o buzzer_test
clean:
        make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)  clean
        rm buzzer_test


buzzer_test.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include "buzzer_drv.h"
#define DEV_NAME "/dev/buzzer"

int main(int argc, char *argv[])
{
      int i;
      int fd = 0;
      fd = open (DEV_NAME, O_RDONLY);
             if(fd < 0) {
             perror("Open"DEV_NAME" Failed!\n");
             exit(1);
      }
      while(1){
             ioctl(fd,BUZZER_ON);
       printf("BUZZER_ON\n");
              sleep(1);
             ioctl(fd,BUZZER_OFF);
        printf("BUZZER_OFF\n");
             sleep(1);
      }
      close(fd);
      return 0;
}
~           


加载驱动: insmod buzzer_drv.ko

查看是否加载成功: ls /dev/buzz*  如果有buzzer(节点名),则加载成功

卸载: rmmod buzzer_drv 注意不要后缀名.ko













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值