蜂鸣器驱动程序设计

  • 格式:doc
  • 大小:635.00 KB
  • 文档页数:23

蚌埠学院嵌入式系统开发技术课程设计专业:电子信息科学与技术(嵌入式)班级:电子信息2班学号:00000000000姓名:设计题目:蜂鸣器驱动程序设计2014年9月目录1.绪论 _________________________________________________________________3 1.1概要___________________________________________________________________ 31.2设计内容_______________________________________________________________ 42.开发环境的搭建 _______________________________________________________4 2.1Redhat的安装 ___________________________________________________________ 4 2.2安装arm-linux-gcc交叉编译器____________________________________________ 82.3安装及编译linux-2.6.29-mini2440-20090708内核 _____________________________ 83.字符设备驱动相关知识 _________________________________________________8 3.1模块机制_______________________________________________________________ 8 3.2字符设备开发基本步骤___________________________________________________ 9 3.3主设备号和次设备号____________________________________________________ 103.4实现字符驱动程序______________________________________________________ 114.蜂鸣器原理 __________________________________________________________13 4.1蜂鸣器的种类和工作原理________________________________________________ 13 4.2开发板上蜂鸣器原理图分析______________________________________________ 144.3GPB0-0参数____________________________________________________________ 145.总体设计 ____________________________________________________________15 5.1设计思路______________________________________________________________ 155.2设计步骤______________________________________________________________ 156. 驱动及测试程序 _____________________________________________________16 6.1beep.c _________________________________________________________________ 166.2beep_tset.c _____________________________________________________________ 207.运行结果及截图 ______________________________________________________21 综合设计总结与思考___________________________________________________231.绪论1.1概要linux 驱动在本质上就是一种软件程序,上层软件可以在不用了解硬件特性的情况下,通过驱动提供的接口,和计算机硬件进行通信。

系统调用是内核和应用程序之间的接口,而驱动程序是内核和硬件之间的接口,也就是内核和硬件之间的桥梁。

它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。

linux 驱动程序是内核的一部分,管理着系统中的设备控制器和相应的设备。

它主要完成这么几个功能:对设备初始化和释放;传送数据到硬件和从硬件读取数据;检测和处理设备出现的错误。

一般来说,一个驱动可以管理一种类型的设备。

例如不同的 U 盘都属于 mass storage 设备,我们不需要为每一个 U 盘编写驱动,而只需要一个驱动就可以管理所有这些 mass storage 设备。

为方便我们加入各种驱动来支持不同的硬件,内核抽象出了很多层次结构,这些层次结构是 linux 设备驱动的上层。

它们抽象出各种的驱动接口,驱动只需要填写相应的回调函数,就能很容易把新的驱动添加到内核。

一般来说, linux 驱动可以分为三类,就是块设备驱动,字符设备驱动和网络设备驱动。

块设备的读写都有缓存来支持,并且块设备必须能够随机存取。

块设备驱动主要用于磁盘驱动器。

而字符设备的 I/O 操作没有通过缓存。

字符设备操作以字节为基础,但不是说一次只能执行一个字节操作。

例如对于字符设备我们可以通过 mmap 一次进行大量数据交换。

字符设备实现比较简单和灵活。

1.2设计内容本次设计是简单的字符设备驱动设计,基于mini2440的蜂鸣器的驱动设计。

2.开发环境的搭建2.1Redhat的安装创建一个虚拟机:点击菜单栏File->New->Virtual machine。

点击下一步。

选择Typical选项。

选择Linux下的Red Hat Linux 填写虚拟机的命名和存储地址。

选择磁盘大小2.2安装arm-linux-gcc交叉编译器将 arm-linux-gcc-4.5.1.tgz复制到虚拟机的root目录下解压文件:tar zxvf arm-linux-gcc-4.5.1.tgz在bash_profile里添加路径:gedit ~/.bash_profiel路径 /root/usr/local/arm/4.5.1/binsource ~/.bash_profile 使更改生效2.3安装及编译linux-2.6.29-mini2440-20090708内核复制内核到root目录下解压内核文件 tar zxvf linux-2.6.29-mini2440-20090708.tgz使内核文件生效:cp config_mini2440_n35 .config使用make命令完成编译3.字符设备驱动相关知识3.1模块机制Linux提供了机制被称为模块(Module)的机制提供了对许多模块支持, 包括但不限于, 设备驱动每个模块由目标代码组成( 没有连接成一个完整可执行程序) insmod 将模块动态加载到正在运行内核rmmod 程序移除模块Linux内核模块的程序结构module_init()---模块加载函数(必须)通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成模块的相关初始化工作●module_exit()---模块卸载函数(必须)当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块装载函数相反的功能●MODULE_LICENSE()---模块许可证声明(必须)模块许可证(LICENSE)声明描述内核模块的许可权限如果不声明LICENSE,模块被加载时,将收到内核被污染(kernel tainted)的警告●module_param()---模块参数(可选)模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量。

●EXPORT_SYMBOL()---模块导出符号(可选)内核模块可以导出符号(symbol,对应于函数或变量)到内核其他模块可以使用本模块中的变量或函数●其他一些声明MODULE_XXXXX()---模块声明(可选)模块加载函数static int __init initialization_function(void){/* 初始化代码*/}module_init(initialization_function);模块卸载函数static void __exit cleanup_function(void){/* 释放资源*/}module_exit(cleanup_function);3.2字符设备开发基本步骤●确定主设备号和次设备号●实现字符驱动程序实现file_operations结构体实现初始化函数,注册字符设备实现销毁函数,释放字符设备●创建设备文件节点3.3主设备号和次设备号●主设备号是内核识别一个设备的标识。

整数(占12bits),范围从0到4095,通常使用1到255●次设备号由内核使用,用于正确确定设备文件所指的设备。

整数(占20bits),范围从0到1048575,一般使用0到255 ●设备编号的内部表达dev_t类型(32位):用来保存设备编号(包括主设备号(12位)和次设备号(20位))从dev_t获得主设备号和次设备号:MAJOR(dev_t);MINOR(dev_t);将主设备号和次设备号转换成dev_t类型:MKDEV(int major,int minor);●分配主设备号手工分配主设备号:找一个内核没有使用的主设备号来使用。

#include <linux/fs.h>int register_chrdev_region( dev_t first, unsigned int count, char *name );●动态分配主设备号:#include <linux/fs.h>int alloc_chrdev_resion(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);●释放设备号void unregister_chrdev_region(dev_t first, unsigned int count);3.4实现字符驱动程序●cdev 结构体struct cdev{struct kobject kobj; /* 内嵌的kobject 对象*/struct module *owner; /*所属模块*/struct file_operations *ops; /*文件操作结构体*/struct list_head list;dev_t dev; /*设备号*/unsigned int count;};●file_operations 结构体字符驱动和内核的接口:在include/linux/fs.h定义字符驱动只要实现一个file_operations结构体并注册到内核中,内核就有了操作此设备的能力。