企业见习报告arm板蜂鸣器驱动开发DOC.docx

上传人:b****8 文档编号:29358768 上传时间:2023-07-22 格式:DOCX 页数:27 大小:1.37MB
下载 相关 举报
企业见习报告arm板蜂鸣器驱动开发DOC.docx_第1页
第1页 / 共27页
企业见习报告arm板蜂鸣器驱动开发DOC.docx_第2页
第2页 / 共27页
企业见习报告arm板蜂鸣器驱动开发DOC.docx_第3页
第3页 / 共27页
企业见习报告arm板蜂鸣器驱动开发DOC.docx_第4页
第4页 / 共27页
企业见习报告arm板蜂鸣器驱动开发DOC.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

企业见习报告arm板蜂鸣器驱动开发DOC.docx

《企业见习报告arm板蜂鸣器驱动开发DOC.docx》由会员分享,可在线阅读,更多相关《企业见习报告arm板蜂鸣器驱动开发DOC.docx(27页珍藏版)》请在冰豆网上搜索。

企业见习报告arm板蜂鸣器驱动开发DOC.docx

企业见习报告arm板蜂鸣器驱动开发DOC

 

嵌入式系统开发技术

企业见习

 

专业:

计算机科学与技术

班级:

2011级计算机软件

学号:

姓名:

设计题目:

蜂鸣器驱动程序设计

 

2014年06月

目录

1.绪论1

1.1概要1

1.2设计内容1

2.开发环境的搭建2

2.1Redhat的安装2

2.2安装arm-linux-gcc交叉编译器4

2.3安装及编译linux-2.6.35.7-Tiny210-20120301内核6

3.字符设备驱动相关知识8

3.1模块机制8

3.2字符设备开发基本步骤9

3.3主设备号和次设备号10

3.4实现字符驱动程序11

4.蜂鸣器原理13

4.1蜂鸣器的种类和工作原理13

4.2开发板上蜂鸣器原理图分析13

5.总体设计14

5.1设计思路14

5.2设计步骤14

6.驱动及测试程序16

6.1buzzer驱动代码16

6.2buzzer驱动测试代码18

7.运行结果及截图20

8、Tiny210开发板调试22

综合设计总结与思考23

1.绪论

1.1概要

Linux是一套免费使用和自由传播的类Unix操作系统,它主要用于基于Intelx86系列CPU的计算机上。

Linux以它的高效性和灵活性著称。

它能够在PC计算机上实现全部的Unix特性,具有多任务、多用户的能力。

Linux是在GNU公共许可权限下免费获得的,是一个符合POSIX标准的操作系统。

Linux操作系统软件包不仅包括完整的Linux操作系统,而且还包括了文本编辑器、高级语言编译器等应用软件。

它还包括带有多个窗口管理器的X-Windows图形用户界面,如同我们使用WindowsNT一样,允许我们使用窗口、图标和菜单对系统进行操作。

而linux驱动是直接和硬件打交道的软件程序。

层次结构上,它处于操作系统和硬件之间。

系统调用是操作系统内核与应用程序之间的接口,设备驱动程序是操作系统内核与机器硬件之间的接口。

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

设备驱动程序是内核的一部分,它主要完成这么几个功能:

对设备初始化和释放;传送数据到硬件和从硬件读取数据;检测和处理设备出现的错误。

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

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

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

1.2设计内容

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

2.开发环境的搭建

2.1Redhat的安装

使用VirtualBox创建一个虚拟机:

点击菜单栏File->New->Virtualmachine。

填写虚拟机名称,选择系统类型和版本,然后点击下一步。

配置虚拟机内存为1024M,然后点击下一步

创建虚拟硬盘,下一步。

配置完成后的虚拟机配置

2.2安装arm-linux-gcc交叉编译器

1、下载文件:

安装包:

arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz

2、开始安装,打开终端输入cd,进入home目录后,

输入命令:

tarxvzfarm-linux-gcc-4.5.1-v6-vfp-20120301.tgz如图:

2.解压完成后在终端中输入cd./opt/FriendlyARM/toolschain/4.5.1/bin/,然后pwd查看当前路径;

3.修改环境变量,把交叉编译器的路径加入到PATH:

利用tab键的补齐功能进入该路径。

输入pwd命令,查看当前路径的绝对路径/home/cf/ARM/opt/FriendlyARM/toolschain/4.5.1/bin如图:

然后输入如下命令:

vi~/.bash_profile

修改下列PATH

PATH=$PATH:

$HOME/bin:

/sbin:

~/opt/FriendlyARM/toolschain/4.5.1/bin

然后输入如下命令,更新环境变量

source~/.bash_profile

4、检查是否将路径加入到PATH:

接下来利用命令echo$PATH查看环境变量是否添加成功,若

环境变量中出现了刚才添加的路径就成功了。

5、测试是否安装成功

$arm-linux-gcc-v输入命令会显示arm-linux-gcc信息和版本.

2.3安装及编译linux-2.6.35.7-Tiny210-20120301内核

复制内核到root目录下

解压内核文件tarzxvflinux-2.6.35.7-Tiny210-20120301.tgz

使内核文件生效:

cpconfig_Tiny210_n35.config

使用make命令完成编译解压内核文件tarzxvflinux-2.6.35.7-20120301.tgz

使内核文件生效:

cpmini210-tvp5150_linux_defconfig.config并且使用make命令完成编译

编辑Makefile文件

3.字符设备驱动相关知识

3.1模块机制

Linux提供了机制被称为模块(Module)的机制

提供了对许多模块支持,包括但不限于,设备驱动

每个模块由目标代码组成(没有连接成一个完整可执行程序)

insmod将模块动态加载到正在运行内核

rmmod程序移除模块

Linux内核模块的程序结构

●module_init()---模块加载函数(必须)

通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成模块的相关初始化工作

●module_exit()---模块卸载函数(必须)

当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块装载函数相反的功能

●MODULE_LICENSE()---模块许可证声明(必须)

模块许可证(LICENSE)声明描述内核模块的许可权限

如果不声明LICENSE,模块被加载时,将收到内核被污染(kerneltainted)的警告

●module_param()---模块参数(可选)

模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量。

●EXPORT_SYMBOL()---模块导出符号(可选)

内核模块可以导出符号(symbol,对应于函数或变量)到内核

其他模块可以使用本模块中的变量或函数

●其他一些声明MODULE_XXXXX()---模块声明(可选)

模块加载函数

staticint__initinitialization_function(void)

{

/*初始化代码*/

}

module_init(initialization_function);

模块卸载函数

staticvoid__exitcleanup_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(intmajor,intminor);

●分配主设备号

手工分配主设备号:

找一个内核没有使用的主设备号来使用。

#include

intregister_chrdev_region(dev_tfirst,unsignedintcount,char*name);

●动态分配主设备号:

#include

intalloc_chrdev_resion(dev_t*dev,unsignedintfirstminor,unsignedintcount,char*name);

●释放设备号

voidunregister_chrdev_region(dev_tfirst,unsignedintcount);

3.4实现字符驱动程序

●cdev结构体

structcdev

{

structkobjectkobj;/*内嵌的kobject对象*/

structmodule*owner;/*所属模块*/

structfile_operations*ops;/*文件操作结构体*/

structlist_headlist;

dev_tdev;/*设备号*/

unsignedintcount;

};

●file_operations结构体

字符驱动和内核的接口:

在include/linux/fs.h定义

字符驱动只要实现一个file_operations结构体

并注册到内核中,内核就有了操作此设备的能力。

●file_operations的主要成员:

structmodule*owner:

指向模块自身

open:

打开设备

release:

关闭设备

read:

从设备上读数据

write:

向设备上写数据

ioctl:

I/O控制函数

llseek:

定位读写指针

mmap:

映射设备空间到进程的地址空间

●ioctl函数

为设备驱动程序执行“命令”提供了一个特有的入口点

用来设置或者读取设备的属性信息。

intioctl(structinode*inode,structfile*filp,

unsignedintcmd,unsignedlongarg);

●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获得。

●Ioctl函数模板

intxxx_ioctl(structinode*inode,structfile*filp,unsignedintcmd,

unsignedlongarg)

{

...

switch(cmd)

{

caseXXX_CMD1:

...

break;

caseXXX_CMD2:

...

break;

default:

///*不能支持的命令*/

return-ENOTTY;

}

return0;

}

4.蜂鸣器原理

4.1蜂鸣器的种类和工作原理

蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。

  压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。

有的压电式蜂鸣器外壳上还装有发光二极管。

多谐振荡器由晶体管或集成电路构成。

当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。

  电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。

接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。

振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。

  有源蜂鸣器和无源蜂鸣器的区别:

这个“源”字是不是指电源,而是指震荡源,即有源蜂鸣器内有振荡源而无源蜂鸣器内部没有振荡源。

有振荡源的通电就可以发声,没有振荡源的需要脉冲信号驱动才能发声。

4.2开发板上蜂鸣器原理图分析

由原理图可以得知,蜂鸣器是通过GPD0IO口使用PWM信号驱动工作的,而GPD0口是一个复用的IO口,要使用它得先把他设置成TOUT0PWM输出模式。

5.总体设计

5.1设计思路

Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载:

(1)直接编译进Linux内核,随同Linux启动时加载;

(2)编译成一个可加载和删除的模块,使用insmod加载(modprobe和insmod命令类似,但依赖于相关的配置文件),rmmod删除。

这种方式控制了内核的大小,而模块一旦被插入内核,它就和内核其他部分一样。

这次的蜂鸣器驱动就采用动态模块加载的方式

5.2设计步骤

Ø编写简单的字符设别驱动程序框架

Ø编写控制蜂鸣器控制开关函数

Ø编译模块,生成beep.ko

Ø编写用户层测试程序

Ø编译用户层测试程序,生成可执行程序test

Ø将生成的beep.ko模块和应用层测试程序test下载到目标板

Ø用insmod装载模块

Ø创建设备节点

mknod/dev/beepc2500

Ø运行用户层测试程序test

#./test

如果你的test的属性不是可执行的,可以用chmod777test将其设置成可执行

程序。

6.驱动及测试程序

6.1蜂鸣器驱动代码

#include

#include//includefile_operations

#include

#include

#include

#include

#include//includeioread32,iowrite32;

dev_tgeek_num;

structcdevgeek_cdev;//字符设备结构体

//structfile_operationsgeek_ops;//

unsignedint*address;//addressforGPD_CON

voidbeep_start(void){

unsignedintdata;

address=ioremap(0xE02000A0,8);

data=ioread32(address+1);

data|=0x1<<0;//bit0set1;

iowrite32(data,address+1);

}

voidbeep_stop(void){

unsignedintdata;

address=ioremap(0xE02000A0,8);

data=ioread32(address+1);

data&=~0x1<<0;//bit0set0;

iowrite32(data,address+1);

}

staticintgeek_open(structinode*node,structfile*fp){

unsignedintdata;//initate

address=ioremap(0xE02000A0,8);

data=ioread32(address);

data&=~0x1<<3;//bit3set0;

data&=~0x1<<2;//bit2set0;

data&=~0x1<<1;//bit1set0;

data|=0x1<<0;//bit0set1;

iowrite32(data,address);

printk("\tgeek_open\n");

return0;

}

staticintgeek_release(structinode*node,structfile*fp){

printk("\tgeek_release\n");

return0;

}

staticintgeek_read(structfile*fp,char__user*buf,size_tcount,loff_t*ppos){

printk("\tgeek_read\n");

return0;

}

staticintgeek_write(structfile*fp,constchar__user*buf,size_tcount,loff_t*ppos){

printk("\tgeek_write\n");

return0;

}

staticintgeek_ioctl(structinode*node,structfile*fp,unsignedintcmd,unsignedlongll){

printk("\tgeek_ioctl\n");

switch(cmd){

case0:

{beep_stop();printk("beep_stop");}

break;

case1:

{beep_start();printk("beep_start");}

break;

default:

printk("commandnotfound!

\n");

break;

}

return0;

}

structfile_operationsgeek_ops=//文件描述符,

{

.owner=THIS_MODULE,//

.open=geek_open,

.read=geek_read,

.write=geek_write,

.ioctl=geek_ioctl,

.release=geek_release,

};

staticint__initbeep_init(void)//初始化

{

intmajor;//主设备号

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_operations

geek_cdev.owner=THIS_MODULE;

cdev_add(&geek_cdev,geek_num,1);//注册设备

return0;

}

staticvoid__exitbeep_exit(void)

{

unregister_chrdev_region(geek_num,1);//

cdev_del(&geek_cdev);//删除

}

module_init(beep_init);//加载

module_exit(beep_exit);//卸载

6.2蜂鸣器驱动测试代码

#include

#include

intmain(){

unsignedn=1;

intfp;

fp=open("/dev/beep",O_RDWR);

if(fp<0){

printf("CantopentheDev!

");

return-1;

}

read(fp,NULL,0);

write(fp,NULL,0);

printf("inputtimeyouwanttobeep:

");

scanf("%d",&n);

while(n--){

ioctl(fp,1,0);

sleep

(1);

ioctl(fp,0,0);

sleep

(1);

}

close(fp);

return0;

}

7.运行结果及截图

传输beep.ko,test测试程序,然后使用ls命令查看文件。

使用insmodbeep.ko加载beep驱动,mknod/dev/beepc2500创建设备结点。

最后使用./test命令运行测试程序

8.Tiny210开发板调试

(1)连接开发板电源。

(2)用串口将PC和Tiny210开发板相连。

(3)打开secureCRT软件,点击快速连接,配置端口

协议:

Serial

端口:

com6(看自己的端口号)

波特率:

115200

数据位:

8

奇偶校验:

none

停止位:

1

勾掉RTS/CTS选项

(4)点击连接

(5)打开开发板电源

(6)secureCRT软件会出现一些选项,选择b,rootsystem

(7)输入指令rz,将beep.ko加载到根文件系统里,再输入指令,将buzzer测试程序加载到根文件系统。

(8)在secureCRT里输入insmodbeep.ko,将驱动程序加载到内核模块中。

(9)在secureCRT里输入chmod777test,改变可执行程序的权限。

(10)在secureCRT里输入./test。

综合设计总结与思考

为期一周的企业见习即将结束,在大三快要结束时学校给我们安排了这次企业见习非常有用。

一方面是对我们这学期所开设的《嵌入式linux应用开发》的一次巩固,另一方面也让我们深入了解了嵌入式linux开发,让我们有机会动手亲自体验linux开发,为以后的实际工作奠定了良好的基础。

同时也让我们知道了,linux开发并不是一件简单的事,并不是一门单纯的学科,需要综合领悟并贯通知识的能力,而且想精通linux开发并不是一朝一夕的事,需要极大的耐心与不懈的努力。

此次企业见习学校给我们安排了南京易嵌教育公司的赵老师,我校与南京易嵌教育有着非常密切而融洽的合作,在去年这个时候学校同样请来了赵老师给我们指导企业见习。

做的项目是用C语言开发一个电话簿。

赵老师非常认真的为我们授课,答疑解惑。

并在设计中给了我们极大的指导性作用。

那次企业见习让我们对C语言有个更加深刻的认识,也了解了C语言的使用的灵活性与广泛性,为这次企业见习做了一个铺垫。

此次设计的题目是蜂鸣器驱动,蜂鸣器我们并不陌生,在单片机这门课程中我们已经了解了蜂鸣器的工

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1