您的位置:首页 > 其它

335xGPIO型蜂鸣器控制

2017-04-09 11:07 113 查看
转自: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: