版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、嵌入式系统开发技术企业见习专 业: 计算机科学与技术 班 级: 2 011级计算机软件 学 号:姓 名:设计题目: 蜂鸣器驱动程序设计 2014年06月上海凡狄信息技术有限公司目 录1.绪论11.1概要11.2设计内容12.开发环境的搭建22.1Redhat的安装22.2安装arm-linux-gcc交叉编译器42.3安装及编译linux-2.6.35.7-Tiny210-20120301内核63.字符设备驱动相关知识83.1模块机制83.2字符设备开发基本步骤93.3主设备号和次设备号103.4实现字符驱动程序114.蜂鸣器原理134.1蜂鸣器的种类和工作原理134.2开发板上蜂鸣器原理图分
2、析135.总体设计145.1设计思路145.2设计步骤146. 驱动及测试程序166.1buzzer驱动代码166.2buzzer驱动 测试代码187.运行结果及截图208、Tiny210开发板调试22综合设计总结与思考23 1.绪论1.1概要 Linux是一套免费使用和自由传播的类 Unix操作系统,它主要用于基于 Intel x86系列 CPU的计算机上。Linux以它的高效性和灵活性著称。它能够在 PC计算机上实现全部的 Unix特性,具有多任务、多用户的能力。 Linux是在 GNU公共许可权限下免费获得的,是一个符合 POSIX标准的操作系统。 Linux操作系统软件包不仅包括完整的
3、 Linux操作系统,而且还包括了文本编辑器、高级语言编译器等应用软件。它还包括带有多个窗口管理器的 X-Windows图形用户界面,如同我们使用 Windows NT一样,允许我们使用窗口、图标和菜单对系统进行操作。 而linux驱动是直接和硬件打交道的软件程序。层次结构上,它处于操作系统和硬件之间。系统调用是操作系统内核与应用程序之间的接口,设备驱动程序是操作系统内核与机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件折本进行操作。设备驱动程序是内核的一部分,它主要完成这么几个功能:对设备初始化和释
4、放;传送数据到硬件和从硬件读取数据;检测和处理设备出现的错误。 一般来说, linux 驱动可以分为三类,就是块设备驱动,字符设备驱动和网络设备驱动。块设备的读写都有缓存来支持,并且块设备必须能够随机存取。块设备驱动主要用于磁盘驱动器。 1.2设计内容本次设计是简单的字符设备驱动设计,基于Tiny 210的蜂鸣器的驱动设计。2.开发环境的搭建2.1Redhat的安装使用VirtualBox创建一个虚拟机:点击菜单栏File->New->Virtual machine。填写虚拟机名称,选择系统类型和版本,然后点击下一步。配置虚拟机内存为1024M,然后点击下一步创建虚拟硬盘,下一步。
5、配置完成后的虚拟机配置242.2安装arm-linux-gcc交叉编译器1、下载文件:安装包:arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz2、开始安装 ,打开终端输入cd,进入home目录后,输入命令: tar xvzf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz如图:2.解压完成后在终端中输入cd ./opt/FriendlyARM/toolschain/4.5.1/bin/,然后pwd查看当前路径;3.修改环境变量,把交叉编译器的路径加入到PATH:利用tab键的补齐功能进入该路径。输入pwd命令,查看当前路径的绝对路径
6、/home/cf/ARM/opt/FriendlyARM/toolschain/4.5.1/bin如图:然后输入如下命令: vi /.bash_profile 修改下列PATHPATH=$PATH:$HOME/bin:/sbin:/opt/FriendlyARM/toolschain/4.5.1/bin然后输入如下命令,更新环境变量source /.bash_profile4、检查是否将路径加入到PATH:接下来利用命令 echo $PATH 查看环境变量是否添加成功,若环境变量中出现了刚才添加的路径就成功了。 5、测试是否安装成功$ arm-linux-gcc -v 输入命令会显示arm-l
7、inux-gcc信息和版本.2.3安装及编译linux-2.6.35.7-Tiny210-20120301内核复制内核到root目录下解压内核文件 tar zxvf linux-2.6.35.7-Tiny210-20120301.tgz使内核文件生效:cp config_Tiny210_n35 .config使用make命令完成编译解压内核文件 tar zxvf linux-2.6.35.7-20120301.tgz 使内核文件生效:cp mini210-tvp5150_linux_defconfig .config并且使用make命令完成编译编辑Makefile文件3.字符设备驱动相关知识3
8、.1模块机制Linux提供了机制被称为模块(Module)的机制 提供了对许多模块支持, 包括但不限于, 设备驱动每个模块由目标代码组成( 没有连接成一个完整可执行程序 )insmod 将模块动态加载到正在运行内核rmmod 程序移除模块Linux内核模块的程序结构l module_init()-模块加载函数(必须) 通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成模块的相关初始化工作l module_exit()-模块卸载函数(必须) 当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块装载函数相反的功能l MODULE_LI
9、CENSE()-模块许可证声明(必须)模块许可证(LICENSE)声明描述内核模块的许可权限如果不声明LICENSE,模块被加载时,将收到内核被污染(kernel tainted)的警告l module_param()-模块参数(可选)模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量。l EXPORT_SYMBOL()-模块导出符号(可选)内核模块可以导出符号(symbol,对应于函数或变量)到内核其他模块可以使用本模块中的变量或函数l 其他一些声明MODULE_XXXXX()-模块声明(可选)模块加载函数static int _init initialization
10、_function(void) /* 初始化代码 */module_init(initialization_function); 模块卸载函数 static void _exit cleanup_function(void) /* 释放资源 */ module_exit(cleanup_function); 3.2字符设备开发基本步骤l 确定主设备号和次设备号l 实现字符驱动程序实现file_operations结构体实现初始化函数,注册字符设备实现销毁函数,释放字符设备l 创建设备文件节点3.3主设备号和次设备号l 主设备号是内核识别一个设备的标识。整数(占12bits),范围从0到4095
11、,通常使用1到255l 次设备号由内核使用,用于正确确定设备文件所指的设备。整数(占20bits),范围从0到1048575,一般使用0到255l 设备编号的内部表达dev_t类型(32位):用来保存设备编号(包括主设备号(12位)和次设备号(20位)从dev_t获得主设备号和次设备号:MAJOR(dev_t);MINOR(dev_t);将主设备号和次设备号转换成dev_t类型:MKDEV(int major,int minor); l 分配主设备号手工分配主设备号:找一个内核没有使用的主设备号来使用。#include <linux/fs.h>int register_chrdev
12、_region( dev_t first, unsigned int count, char *name );l 动态分配主设备号:#include <linux/fs.h>int alloc_chrdev_resion(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);l 释放设备号void unregister_chrdev_region(dev_t first, unsigned int count);3.4实现字符驱动程序l cdev 结构体struct cdev struct kobject
13、 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结构体并注册到内核中,内核就有了操作此设备的能力。l file_operations的主要成员:struct modul
14、e *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 arg);l cmd 参数的定义不推荐用0x1,0x2,0x3之类的值Linux对ioctl()的cmd参数有特殊的定义构
15、造命令编号的宏:_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, struct f ile *filp, unsigned int cmd, unsigned long arg) . swit
16、ch (cmd) case XXX_CMD1: . break; case XXX_CMD2: . break; default: /*不能支持的命令 */ return - ENOTTY; return 0; 4.蜂鸣器原理4.1蜂鸣器的种类和工作原理蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。多谐振荡器由晶体管或集成电路构成。当接通电源后(1.515V直流工作电压),多谐振荡器起振,输出1.52.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。
17、 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。 有源蜂鸣器和无源蜂鸣器的区别:这个“源”字是不是指电源,而是指震荡源,即有源蜂鸣器内有振荡源而无源蜂鸣器内部没有振荡源。有振荡源的通电就可以发声,没有振荡源的需要脉冲信号驱动才能发声。4.2开发板上蜂鸣器原理图分析由原理图可以得知,蜂鸣器是通过GPD0 IO口使用PWM信号驱动工作的,而GPD0口是一个复用的IO口,要使用它得先把他设置成TOUT0 PWM输出
18、模式。5.总体设计5.1设计思路 Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载: (1)直接编译进Linux内核,随同Linux启动时加载; (2)编译成一个可加载和删除的模块,使用insmod加载(modprobe和insmod命令类似,但依赖于相关的配置文件),rmmod删除。这种方式控制了内核的大小,而模块一旦被插入内核,它就和内核其他部分一样。 这次的蜂鸣器驱动就采用动态模块加载的方式5.2设计步骤Ø 编写简单的字符设别驱动程序框架Ø 编写控制蜂鸣器控制开关函数Ø 编译模块,生成beep.koØ 编写用户
19、层测试程序Ø 编译用户层测试程序,生成可执行程序testØ 将生成的beep.ko 模块和应用层测试程序 test 下载到目标板Ø 用 insmod 装载模块Ø 创建设备节点 mknod /dev/beep c 250 0Ø 运行用户层测试程序 test#./test如果你的 test 的属性不是可执行的,可以用 chmod 777 test 将其设置成可执行程序。6. 驱动及测试程序6.1蜂鸣器驱动代码#include<linux/module.h>#include<linux/fs.h>/include file_o
20、perations#include<linux/cdev.h>#include<linux/device.h>#include<linux/types.h>#include<linux/init.h>#include<asm/io.h>/include ioread32,iowrite32;dev_t geek_num;struct cdev geek_cdev;/字符设备结构体/struct file_operations geek_ops;/unsigned int *address;/address for GPD_CONvoi
21、d beep_start(void)unsigned int data;address = ioremap(0xE02000A0,8);data = ioread32(address+1);data |= 0x1<<0;/bit0 set 1;iowrite32(data,address+1);void beep_stop(void)unsigned int data;address = ioremap(0xE02000A0,8);data = ioread32(address+1);data &= 0x1<<0;/bit0 set 0;iowrite32(da
22、ta,address+1);static int geek_open(struct inode *node,struct file *fp)unsigned int data ;/initate address = ioremap(0xE02000A0,8);data = ioread32(address);data &=0x1<<3;/bit3 set 0;data &=0x1<<2;/bit2 set 0;data &=0x1<<1;/bit1 set 0;data |=0x1<<0;/bit0 set 1;iowri
23、te32(data,address);printk("tgeek_openn");return 0;static int geek_release(struct inode *node,struct file *fp)printk("tgeek_releasen");return 0;static int geek_read(struct file *fp,char _user *buf,size_t count,loff_t *ppos)printk("tgeek_readn");return 0;static int geek_w
24、rite(struct file *fp,const char _user *buf,size_t count,loff_t *ppos)printk("tgeek_writen");return 0;static int geek_ioctl(struct inode *node,struct file *fp,unsigned int cmd,unsigned long ll )printk("tgeek_ioctln");switch(cmd)case 0:beep_stop();printk("beep_stop");brea
25、k;case 1:beep_start();printk("beep_start");break;default:printk("command not found!n");break;return 0;struct file_operations geek_ops =/文件描述符,.owner = THIS_MODULE,/.open = geek_open,.read = geek_read,.write = geek_write,.ioctl = geek_ioctl,.release=geek_release, ;static int _init
26、 beep_init(void)/初始化int major; /主设备号alloc_chrdev_region(&geek_num,0,1,"geek_beep");/ 设备号,次设备号,分支数,设备名称major = MAJOR(geek_num);printk("major:%d",major);cdev_init(&geek_cdev,&geek_ops);geek_cdev.ops = &geek_ops;/指向file_operationsgeek_cdev.owner = THIS_MODULE;cdev_ad
27、d(&geek_cdev,geek_num,1);/注册设备return 0;static void _exit beep_exit(void)unregister_chrdev_region(geek_num,1);/cdev_del(&geek_cdev);/删除module_init(beep_init);/加载module_exit(beep_exit);/卸载6.2蜂鸣器驱动 测试代码#include<stdio.h>#include<fcntl.h>int main()unsigned n=1;int fp;fp = open("/
28、dev/beep",O_RDWR);if(fp < 0)printf("Cant open the Dev!");return -1; read(fp,NULL,0);write(fp,NULL,0);printf("input time you want to beep:");scanf("%d",&n);while(n-)ioctl(fp,1,0);sleep(1);ioctl(fp,0,0);sleep(1);close(fp);return 0;7.运行结果及截图传输beep.ko,test测试程序,然
29、后使用ls命令查看文件。使用insmod beep.ko加载beep驱动,mknod /dev/beep c 250 0创建设备结点。最后使用./test命令运行测试程序8.Tiny210开发板调试(1)连接开发板电源。(2)用串口将PC和Tiny210开发板相连。(3)打开secureCRT软件,点击快速连接,配置端口协议:Serial 端口:com 6(看自己的端口号) 波特率:115200 数据位:8奇偶校验:none停止位:1勾掉RTS/CTS选项(4)点击连接(5)打开开发板电源(6)secureCRT软件会出现一些选项,选择b,root system(7)输入指令rz,将beep.
30、ko加载到根文件系统里,再输入指令,将buzzer测试程序加载到根文件系统。(8)在secureCRT里输入insmod beep.ko,将驱动程序加载到内核模块中。(9)在secureCRT里输入chmod 777 test,改变可执行程序的权限。(10)在secureCRT里输入./test。综合设计总结与思考为期一周的企业见习即将结束,在大三快要结束时学校给我们安排了这次企业见习非常有用。一方面是对我们这学期所开设的嵌入式linux应用开发的一次巩固,另一方面也让我们深入了解了嵌入式linux开发,让我们有机会动手亲自体验linux开发,为以后的实际工作奠定了良好的基础。同时也让我们知道了,linux开发并不是一件简单的事,并不是一门单纯的学科,需要综合领悟并贯通知识的能力,而且想精通linux开发并不是一朝一夕的事,需要极大的耐心与不懈的努力
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 医疗信息化标准制定-第1篇-洞察分析
- 虚拟现实工艺设计创新-洞察分析
- 网络犯罪治理创新-洞察分析
- 虚拟试妆技术-第1篇-洞察分析
- 药物释放动力学模型构建-洞察分析
- 虚拟现实计算器人机交互-洞察分析
- 系统集成测试与评估-洞察分析
- 二零二五版商业街区车位购置及共享服务合同2篇
- 2025年北师大新版九年级科学上册月考试卷
- 2025年北师大新版八年级物理下册阶段测试试卷含答案
- 服装板房管理制度
- 2024年县乡教师选调进城考试《教育学》题库及完整答案(考点梳理)
- 车借给别人免责协议书
- 河北省兴隆县盛嘉恒信矿业有限公司李杖子硅石矿矿山地质环境保护与治理恢复方案
- 第七章力与运动第八章压强第九章浮力综合检测题(一)-2023-2024学年沪科版物理八年级下学期
- 医疗机构诊疗科目名录(2022含注释)
- 微视频基地策划方案
- 光伏项目质量评估报告
- 八年级一本·现代文阅读训练100篇
- 2023年电池系统测试工程师年度总结及下一年计划
- 应急预案评分标准表
评论
0/150
提交评论