linux c蜂鸣器驱动程序,〖Linux〗OK6410a蜂鸣器的驱动程序编写全程实录

最近在看一本书,受益匪浅,作者是李宁,下边是编写本次蜂鸣器的全程实录:

1. 了解开发板中的蜂鸣器

1) 查看蜂鸣器buzzer在底板中的管脚信息

cc4e251ee75956365abedcef033a4bbb.png

2) 查看蜂鸣器在总线中的信息

a1fc9749ce29c1843d8c4253f393d3e8.png

3) 翻看S3C6410芯片手册,查看GPF15相关信息

e793770787eaf2813b22fd190fd9d971.png

2. 在了解了开发板中蜂鸣器之后,编写代码对它进行控制。

由于蜂鸣器是通过PWM(脉冲宽度调制)进行开关控制的,故也称为PWM。

1) 编写pwm.c(包含Linux驱动模块的主要模型代码)

#include "pwm_fun.h"

static struct semaphore lock; /*创建信号量*/

//文件打开时,自动操作此函数,使用信号量控制其访问

static int s3c6410_pwm_open(struct inode *inode, struct file *file){if (!down_trylock(&lock)) /*使用信号量控制只能由一个进程打开*/{return 0;

}else{return -EBUSY;

}

}//文件关闭时,自动操作此函数,使用信号量控制其访问

static int s3c6410_pwm_close(struct inode *inode, struct file *file){

up(&lock); /*释放信号量*/

return 0;

}//文件中关于ioctl的操作

static long s3c6410_pwm_ioctl(struct file *filep, unsigned int cmd, unsigned longarg){switch( cmd ) {casePWM_IOCTL_START:

pwm_start();break;casePWM_IOCTL_STOP:

pwm_stop();break;default:break;

}/*----- end switch -----*/

return 0;

}//文件操作的指针

static struct file_operations dev_fops ={

.owner=THIS_MODULE,

.open=s3c6410_pwm_open,

.release=s3c6410_pwm_close,

.unlocked_ioctl=s3c6410_pwm_ioctl,

};//设备的属性

static struct miscdevice misc ={

.minor=MISC_DYNAMIC_MINOR,

.name=DEVICE_NAME,

.fops= &dev_fops,

};//驱动的入口函数

static int __init dev_init(void){intret;

init_MUTEX(&lock); /*初始化信号量*/ret= misc_register(&misc);

printk(DEVICE_NAME"initialized");returnret;

}//驱动的退出函数

static void __exit dev_exit(void){

misc_deregister(&misc);

printk(DEVICE_NAME"exited");

}

module_init(dev_init);

module_exit(dev_exit);

2) 编写pwm_fun.c(包含对蜂鸣器控制的主要代码)

#include "pwm_fun.h"

void pwm_start(void){

unsignedinttmp;

tmp=ioread32(S3C64XX_GPFCON);

tmp&= ~(0x3U<<30); /*最高两位清零,保留其他位*/tmp|= (0x2U<<30); /*最高两位设置为10,蜂鸣器发出尖叫声*/iowrite32(tmp, S3C64XX_GPFCON);

}void pwm_stop(void){

unsigned tmp;

tmp=ioread32(S3C64XX_GPFCON);

tmp&= ~(0x3U<<30); /*最高两位清零,蜂鸣器停止尖叫*/iowrite32(tmp, S3C64XX_GPFCON);

}

3) 编写pwm_fun.h(包含一些必须的头文件及宏定义信息)

#include #include#include#include#include#include#include#include#include#include#include#include#include#include

#define DEVICE_NAME "pwm_dev"

#define PWM_IOCTL_START 1

#define PWM_IOCTL_STOP 0

extern void pwm_start(void);extern void pwm_stop(void);

4) 编写Makefile文件(使编译过程自动完成)

obj-m :=pwm_driver.o

pwm_driver-objs :=pwm.o pwm_fun.o

PWD := $(shell pwd)

CROSS_COMPILE?= arm-none-linux-gnueabi-CC := $(CROSS_COMPILE)gccCFLAGS+= -static

KPATH := /media/Source/Forlinx/android2.3_kernel_v1.01all: ioctlmake -C $(KPATH) M=$(PWD) modules

ioctl: ioctl.c

$(CC) $(CFLAGS) $^ -o $@

clean:rm -rf *.o *.ko *.mod.c Module.* modules.* ioctl

5) 编写测试程序ioctl(用于对驱动程序的测试)

#include #include#include#include#include

/** === FUNCTION ======================================================================

* Name: main

* Description: 对驱动程序进行测试

* =====================================================================================*/

int main ( int argc, char *argv[] )

{int file_handler = 0;int cmd = 0;int arg = 0;if (argc < 4)

{

printf("Usage: ioctl ");returnEXIT_FAILURE;

}

cmd= atoi(argv[2]);

arg= atoi(argv[3]);

printf("dev:%s", argv[1]);

printf("cmd:%d", cmd);

printf("arg:%d", arg);

file_handler= open(argv[1], 0);if (file_handler<0)

{

printf("open %s failure.", argv[1]);

}

ioctl(file_handler, cmd, arg);

close(file_handler);return EXIT_SUCCESS;

3. 编写好源代码程序之后,交叉编译,上传至OK6410A开发板,进行测试

1) 配置好交叉编译工具链arm-none-linux-gnueabi-gcc之后,在终端输入make即可自动完成编译

2) OK6410A(Android2.3.4操作系统)通过USB线连接至PC端,通过adb上传至开发板:

adb push pwm_driver.ko /tmp/pwm_driver.ko

adb push ioctl /tmp/ioctl

3) 通过adb shell打开并控制OK6410A开发板,输入命令安装驱动模块:

adb shell

insmod /tmp/pwm_driver.ko

4) 测试蜂鸣器驱动程序

/tmp/ioctl /dev/pwm_dev 1 0 #打开蜂鸣器

/tmp/ioctl /dev/pwm_dev 0 0 #关闭蜂鸣器

1d5dd4062de31464e295170db5e9d83a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值