企业见习报告arm板蜂鸣器驱动开发.docx
《企业见习报告arm板蜂鸣器驱动开发.docx》由会员分享,可在线阅读,更多相关《企业见习报告arm板蜂鸣器驱动开发.docx(23页珍藏版)》请在冰豆网上搜索。
企业见习报告arm板蜂鸣器驱动开发
嵌入式系统开发技术
企业见习
专业:
计算机科学与技术
班级:
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:
...