嵌入式系统开发技术课程设计蜂鸣器驱动程序设计_第1页
嵌入式系统开发技术课程设计蜂鸣器驱动程序设计_第2页
嵌入式系统开发技术课程设计蜂鸣器驱动程序设计_第3页
嵌入式系统开发技术课程设计蜂鸣器驱动程序设计_第4页
嵌入式系统开发技术课程设计蜂鸣器驱动程序设计_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、蚌埠学院嵌入式系统开发技术课程设计专 业:电子信息科学与技术(嵌入式)班 级: 电子信息2班 学 号: 00000000000 姓 名: 设计题目: 蜂鸣器驱动程序设计 2014年9月目录1.绪论31.1概要31.2设计内容42.开发环境的搭建42.1redhat的安装42.2安装arm-linux-gcc交叉编译器92.3安装及编译linux-2.6.29-mini2440-20090708内核93.字符设备驱动相关知识93.1模块机制93.2字符设备开发基本步骤103.3主设备号和次设备号113.4实现字符驱动程序124.蜂鸣器原理144.1蜂鸣器的种类和工作原理144.2开发板上蜂鸣器原

2、理图分析154.3gpb0-0参数155.总体设计165.1设计思路165.2设计步骤166. 驱动及测试程序176.1beep.c176.2beep_tset.c217.运行结果及截图22综合设计总结与思考25 1.绪论1.1概要linux 驱动在本质上就是一种软件程序,上层软件可以在不用了解硬件特性的情况下,通过驱动提供的接口,和计算机硬件进行通信。 系统调用是内核和应用程序之间的接口,而驱动程序是内核和硬件之间的接口,也就是内核和硬件之间的桥梁。它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。 linux 驱动

3、程序是内核的一部分,管理着系统中的设备控制器和相应的设备。它主要完成这么几个功能:对设备初始化和释放;传送数据到硬件和从硬件读取数据;检测和处理设备出现的错误。 一般来说,一个驱动可以管理一种类型的设备。例如不同的 u 盘都属于 mass storage 设备,我们不需要为每一个 u 盘编写驱动,而只需要一个驱动就可以管理所有这些 mass storage 设备。 为方便我们加入各种驱动来支持不同的硬件,内核抽象出了很多层次结构,这些层次结构是 linux 设备驱动的上层。它们抽象出各种的驱动接口,驱动只需要填写相应的回调函数,就能很容易把新的驱动添加到内核。 一般来说, linux 驱动可以

4、分为三类,就是块设备驱动,字符设备驱动和网络设备驱动。块设备的读写都有缓存来支持,并且块设备必须能够随机存取。块设备驱动主要用于磁盘驱动器。 而字符设备的 i/o 操作没有通过缓存。字符设备操作以字节为基础,但不是说一次只能执行一个字节操作。例如对于字符设备我们可以通过 mmap 一次进行大量数据交换。字符设备实现比较简单和灵活。1.2设计内容本次设计是简单的字符设备驱动设计,基于mini2440的蜂鸣器的驱动设计。 2.开发环境的搭建2.1redhat的安装创建一个虚拟机:点击菜单栏file-new-virtual machine。点击下一步。选择typical选项。选择linux下的red

5、 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 lin

6、ux-2.6.29-mini2440-20090708.tgz使内核文件生效:cp config_mini2440_n35 .config使用make命令完成编译 3.字符设备驱动相关知识3.1模块机制linux提供了机制被称为模块(module)的机制 提供了对许多模块支持, 包括但不限于, 设备驱动每个模块由目标代码组成( 没有连接成一个完整可执行程序 )insmod 将模块动态加载到正在运行内核rmmod 程序移除模块linux内核模块的程序结构l module_init()-模块加载函数(必须) 通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成

7、模块的相关初始化工作l module_exit()-模块卸载函数(必须) 当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块装载函数相反的功能l module_license()-模块许可证声明(必须)模块许可证(license)声明描述内核模块的许可权限如果不声明license,模块被加载时,将收到内核被污染(kernel tainted)的警告l module_param()-模块参数(可选)模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量。l export_symbol()-模块导出符号(可选)内核模块可以导出符号(symbol,对应于

8、函数或变量)到内核其他模块可以使用本模块中的变量或函数l 其他一些声明module_xxxxx()-模块声明(可选)模块加载函数static int _init initialization_function(void) /* 初始化代码 */module_init(initialization_function); 模块卸载函数 static void _exit cleanup_function(void) /* 释放资源 */ module_exit(cleanup_function); 3.2字符设备开发基本步骤l 确定主设备号和次设备号l 实现字符驱动程序实现file_operati

9、ons结构体实现初始化函数,注册字符设备实现销毁函数,释放字符设备l 创建设备文件节点3.3主设备号和次设备号l 主设备号是内核识别一个设备的标识。整数(占12bits),范围从0到4095,通常使用1到255l 次设备号由内核使用,用于正确确定设备文件所指的设备。整数(占20bits),范围从0到1048575,一般使用0到255l 设备编号的内部表达dev_t类型(32位):用来保存设备编号(包括主设备号(12位)和次设备号(20位)从dev_t获得主设备号和次设备号:major(dev_t);minor(dev_t);将主设备号和次设备号转换成dev_t类型:mkdev(int majo

10、r,int minor); l 分配主设备号手工分配主设备号:找一个内核没有使用的主设备号来使用。#include int register_chrdev_region( dev_t first, unsigned int count, char *name );l 动态分配主设备号:#include int alloc_chrdev_resion(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);l 释放设备号void unregister_chrdev_region(dev_t first, unsigned

11、 int count);3.4实现字符驱动程序l cdev 结构体struct cdev struct kobject kobj; /* 内嵌的kobject 对象 */ struct module *owner; /*所属模块*/ struct file_operations *ops; /*文件操作结构体*/ struct list_head list; dev_t dev; /*设备号*/ unsigned int count; ;l file_operations 结构体字符驱动和内核的接口:在include/linux/fs.h定义字符驱动只要实现一个file_operations结

12、构体并注册到内核中,内核就有了操作此设备的能力。l file_operations的主要成员:struct module *owner: 指向模块自身open:打开设备release:关闭设备read:从设备上读数据write:向设备上写数据ioctl:i/o控制函数llseek:定位读写指针mmap:映射设备空间到进程的地址空间l ioctl函数为设备驱动程序执行“命令”提供了一个特有的入口点用来设置或者读取设备的属性信息。int ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long ar

13、g);l cmd 参数的定义不推荐用0x1,0x2,0x3之类的值linux对ioctl()的cmd参数有特殊的定义构造命令编号的宏:_io(type,nr)用于构造无参数的命令编号;_ior(type,nr,datatype)用于构造从驱动程序中读取数据的命令编号;_iow(type,nr,datatype)用于写入数据的命令;_iowr(type,nr,datatype)用于双向传输。type和number位字段通过参数传入,而size位字段通过对datatype参数取sizeof获得。 l ioctl函数模板int xxx_ioctl( struct inode *inode, stru

14、ct f ile *filp, unsigned int cmd, unsigned long arg) . switch (cmd) case xxx_cmd1: . break; case xxx_cmd2: . break; default: /*不能支持的命令 */ return - enotty; return 0; 3.5字符设备驱动结构 4.蜂鸣器原理 4.1蜂鸣器的种类和工作原理蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。多谐振荡器由晶体管或集成电路构成。当

15、接通电源后(1.515v直流工作电压),多谐振荡器起振,输出1.52.5khz的音频信号,阻抗匹配器推动压电蜂鸣片发声。 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。 有源蜂鸣器和无源蜂鸣器的区别:这个“源”字是不是指电源,而是指震荡源,即有源蜂鸣器内有振荡源而无源蜂鸣器内部没有振荡源。有振荡源的通电就可以发声,没有振荡源的需要脉冲信号驱动才能发声。4.2开发板上蜂鸣器原理图分析由原理图可以得知,蜂鸣器是通过gpb0 io口使用pwm信号驱动工作的,而g

16、pb0口是一个复用的io口,要使用它得先把他设置成tout0 pwm输出模式。4.3gpb0参数 5.总体设计5.1设计思路 linux设备驱动属于内核的一部分,linux内核的一个模块可以以两种方式被编译和加载: (1)直接编译进linux内核,随同linux启动时加载; (2)编译成一个可加载和删除的模块,使用insmod加载(modprobe和insmod命令类似,但依赖于相关的配置文件),rmmod删除。这种方式控制了内核的大小,而模块一旦被插入内核,它就和内核其他部分一样。 这次的蜂鸣器驱动就采用动态模块加载的方式5.2设计步骤 编写简单的字符设别驱动程序框架 编写控制蜂鸣器控制开关

17、函数 编译模块,生成.ko 编写用户层测试程序 编译用户层测试程序,生成可执行程序beep_test 将生成的.ko 模块和应用层测试程序 beep_test 下载到目标板 用 insmod 装载模块 创建设备节点 mknod /dev/beep c 253 0 运行用户层测试程序 beep_test#./beep_test如果你的 beep_test 的属性不是可执行的,可以用 chmod 777 beep_test 将其设置成可执行程序。6. 驱动及测试程序6.1beep.c#include#include#include#include#include#include#include#i

18、nclude#include#include#include#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define beep_major 201#define beep_st

19、art_cmd 0x0#define beep_stop_cmd 0x1static int beep_major=beep_major;static struct cdev beepdevs;static int beep_open(struct inode *inode,struct file *filp)return 0;static int beep_relesae(struct inode *inode,struct file *filp)return 0;static void beep_stop(void)s3c2410_gpio_cfgpin(s3c2410_gpb(0),s3

20、c2410_gpio_output);s3c2410_gpio_setpin(s3c2410_gpb(0),0);printk(stopn);static void beep_start(void)s3c2410_gpio_cfgpin(s3c2410_gpb(0),s3c2410_gpio_output);s3c2410_gpio_setpin(s3c2410_gpb(0),1);printk(startn);static int beep_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long a

21、rg)switch(cmd)case beep_start_cmd:printk(beep_stratn);beep_start();break;case beep_stop_cmd:printk(beep_stopn);beep_stop();break;default:printk(defaultn);break;return 0;static struct file_operations beep_remap_ops=.owner = this_module,.open =beep_open,.release = beep_relesae,.ioctl = beep_ioctl,;sta

22、tic void beep_setup_cdev(struct cdev *dev, int minor,struct file_operations *fops)int err,devno = mkdev(beep_major,minor);cdev_init(dev,fops);dev-owner = this_module;dev-ops = fops;err = cdev_add(dev,devno,1);if(err)printk(error %d adding beep %d n,err,minor);static int _init beep_init(void)int resu

23、lt;dev_t dev=mkdev(beep_major,0);if(beep_major)result= register_chrdev_region(dev,1,beep);elseresult=alloc_chrdev_region(&dev,0,1,beep);beep_major=major(dev);if(result0)printk(beep: unable to get major %d n,beep_major);return result;if(beep_major=0)beep_major=result;beep_setup_cdev(&beepdevs,0,&beep_remap_ops);printk(beep devices installed,with major %d,beep_major);return 0;static void _exit beep_exit()cdev_del(&beepdevs);unregister_chrdev_region(mkdev(beep_major,0),1);printk(beep device uninstalledn);module_author(xdq);module_license(gpl);module_init(beep_init);module_exit(beep_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论