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

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

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

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

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

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 ;
}
else{
return -EBUSY;
}
} //文件关闭时,自动操作此函数,使用信号量控制其访问
static int s3c6410_pwm_close(struct inode *inode, struct file *file){
up(&lock); /* 释放信号量 */
return ;
} //文件中关于ioctl的操作
static long s3c6410_pwm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg){ switch ( cmd ) {
case PWM_IOCTL_START:
pwm_start();
break; case PWM_IOCTL_STOP:
pwm_stop();
break; default:
break;
} /* ----- end switch ----- */ return ;
} //文件操作的指针
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){
int ret;
init_MUTEX(&lock); /* 初始化信号量 */
ret = misc_register(&misc);
printk(DEVICE_NAME"\tinitialized\n");
return ret;
} //驱动的退出函数
static void __exit dev_exit(void){
misc_deregister(&misc);
printk(DEVICE_NAME"\texited\n");
} module_init(dev_init);
module_exit(dev_exit);

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

#include "pwm_fun.h"

void pwm_start(void){
unsigned int tmp;
tmp = ioread32(S3C64XX_GPFCON);
tmp &= ~(0x3U<<); /* 最高两位清零,保留其他位 */
tmp |= (0x2U<<); /* 最高两位设置为10,蜂鸣器发出尖叫声 */
iowrite32(tmp, S3C64XX_GPFCON);
} void pwm_stop(void){
unsigned tmp;
tmp = ioread32(S3C64XX_GPFCON);
tmp &= ~(0x3U<<); /* 最高两位清零,蜂鸣器停止尖叫 */
iowrite32(tmp, S3C64XX_GPFCON);
}

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

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank-f.h>
#include <mach/gpio-bank-k.h> #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)gcc
CFLAGS += -static
KPATH := /media/Source/Forlinx/android2.3_kernel_v1.
all: ioctl
make -C $(KPATH) M=$(PWD) modules
ioctl: ioctl.c
$(CC) $(CFLAGS) $^ -o $@
clean:
rm -rf *.o *.ko *.mod.c Module.* modules.* ioctl

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

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h> /*
* === FUNCTION ======================================================================
* Name: main
* Description: 对驱动程序进行测试
* =====================================================================================
*/
int main ( int argc, char *argv[] )
{
int file_handler = ;
int cmd = ;
int arg = ;
if (argc < )
{
printf("Usage: ioctl <DEVICE_NAME> <cmd> <arg>\n");
return EXIT_FAILURE;
}
cmd = atoi(argv[]);
arg = atoi(argv[]);
printf("dev:%s\n", argv[]);
printf("cmd:%d\n", cmd);
printf("arg:%d\n", arg);
file_handler = open(argv[], );
if (file_handler<)
{
printf("open %s failure.\n", argv[]);
}
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 #关闭蜂鸣器

〖Linux〗OK6410a蜂鸣器的驱动程序编写全程实录的更多相关文章

  1. Linux下的网卡驱动程序的编写过程(转)

    工作需要写了我们公司一块网卡的linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大家的喜爱.真希望她能在中国迅速成长.把程序文档贴出来,希 ...

  2. 转:Linux网卡驱动程序编写

    Linux网卡驱动程序编写 [摘自 LinuxAID] 工作需要写了我们公司一块网卡的Linux驱动程序.经历一个从无到有的过程,深感技术交流的重要.Linux作为挑战微软垄断的强有力武器,日益受到大 ...

  3. 11.ok6410之led驱动程序编写

    led驱动程序编写 本文主要包含三部分,led驱动程序led.c编写,编译驱动程序的makefile的编写,以及使用驱动程序的应用程序led_app的编写 一.led.c编写 #include < ...

  4. Linux驱动之按键驱动编写(中断方式)

    在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...

  5. Linux驱动之按键驱动编写(查询方式)

    在Linux驱动之LED驱动编写已经详细介绍了一个驱动的编写过程,接着来写一个按键驱动程序,主要是在file_operations结构中添加了一个read函数.还是分以下几步说明 1.查看原理图,确定 ...

  6. LCD驱动程序编写

    学习目标:编写LCD驱动程序,熟悉根据芯片手册分析时序图,配置寄存器,并测试LCD程序. 一.LCD驱动程序编写 步骤: 1)分配fb_info结构体 2)设置fb_info结构体 a. 固定参数 b ...

  7. Linux下PCI设备驱动程序开发 --- PCI驱动程序实现(三)

    三.PCI驱动程序实现 1. 关键数据结构 PCI设备上有三种地址空间:PCI的I/O空间.PCI的存储空间和PCI的配置空间.CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给 ...

  8. 【DSP开发】【Linux开发】Linux下PCI设备驱动程序开发

    PCI是一种广泛采用的总线标准,它提供了许多优于其它总线标准(如EISA)的新特性,目前已经成为计算机系统中应用最为广泛,并且最为通用的总线标准.Linux的内核能较好地支持PCI总线,本文以Inte ...

  9. 【转】android应用开发全程实录-你有多熟悉listview?---不错

    原文网址:http://www.cnblogs.com/noTice520/archive/2011/12/05/2276379.html 今天给大家带来<android应用开发全程实录> ...

随机推荐

  1. java内存模型知识点汇总

    1.像windows/linux这种操作系统中,自带jvm么?以方便java程序的运行? 答:是的,一般操作系统都自带jvm的.但不带jdk,也就是说java的运行环境有,但编译环境没有. 1.jav ...

  2. Sublimetext3将空格转换为Tab

    最近在学习Python,从网上粘贴的代码很多缩进都是空格,这样就会导致代码执行的时候报错,因为Python是依靠缩进来判断代码层次的.我的编辑器是Sublime Text 3看了一下,原来转换成Tab ...

  3. Android网络请求之OkHttp框架

    首先声明权限 <uses-permission android:name="android.permission.INTERNET"/> 在build.gradle中加 ...

  4. go语言基础之结构体成员的使用普通变量

    1.结构体成员的使用普通变量 示例: package main //必须有个main包 import "fmt" //定义一个结构体类型 type Student struct { ...

  5. Jump Game leetcode java

    题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...

  6. 你需要知道的、有用的 Python 功能和特点

    在使用Python多年以后,我偶然发现了一些我们过去不知道的功能和特性.一些可以说是非常有用,但却没有充分利用.考虑到这一点,我编辑了一些的你应该了解的Pyghon功能特色. 带任意数量参数的函数 你 ...

  7. 你应该了解的CSS语义化命名方式及常用命名规则

    CSS语义化命名 从上图我们可以大概看出这里有两种CSS的命名方式:1.结构化命名法:2.语义化命名法. 结构化命名法:根据页面中板块的位置而命名,如上图中的content-left,这时如果我们想把 ...

  8. Android4.2.2 Gallery2源码分析(4)——GLCanvas.java

    首先申明,找到这个类是在GLRootView.java中发现的线索.这是一个接口,源码中对该接口作了详细的说明: // // GLCanvas gives a convenient interface ...

  9. Ngxtop-Nginx日志实时分析利器

    ngxtop实时解析nginx访问日志,并且将处理结果输出到终端,功能类似于系统命令top,所以这个软件起名ngxtop.有了ngxtop,你可以实时了解到当前nginx的访问状况,再也不需要tail ...

  10. Linux command 系统快捷键

    群里有人问"问个问题,Linux 命令行有没有快捷键一下从行末会到行头?经常敲了很多命令发现忘加 sudo 了,然后把命令删了重新敲一遍". 自己还真不知道怎么操作,只知道历史命令 ...