s3c2410的字符型设备驱动程序设计_第1页
s3c2410的字符型设备驱动程序设计_第2页
s3c2410的字符型设备驱动程序设计_第3页
s3c2410的字符型设备驱动程序设计_第4页
s3c2410的字符型设备驱动程序设计_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

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

文档简介

1、 福建工程学院 课程设计报告 实验课题: s3c2410的字符型设备驱动程序设计 指导老师:陈老师 日期:2011年5月24号1、 实验原理:1 Linux系统下驱动程序的相关概念: Linux系统中,设备驱动程序是操作系统内核的重要组成部分,它与硬件设备之间建立了标准的抽象接口。通过这个接口,用户可以像处理普通文件一样,对硬件设备进行打开(open)、关闭(close)、读写(read/write)等操作。通过分析和设计设备驱动程序,可以深入理解Linux系统和进行系统开发。Linux设备分为字符设备、块设备和网络设备。本课程设计研究字符型设备驱动程序设计。 Linux系统为每一个设备分配了

2、一个主设备号和 次设备号,主设备号标识设备对应驱动程序 ,次设备号标识具体设备的实例。例如一块开发板上有2个串口终端 / dev/ tty0, / dev/ tty1 ,它们的主设备号都是4,次设备号分别为0和1。每一类设备使用的主设备号是独一无二的,系统增加一个驱动程序就要赋予它一个主设备号,这一赋值过程在驱动程序的初始化过程中进行。2设备驱动程序的组成 设备驱动在加载时首先需要调用入口函数 init module ( ) ,该函数完成设备驱动的初始化工作 ,比如寄 存器置位、结构体赋值等一系列工作,其中最重要的一个工作就是向内核注册该设备 ,字符设备调用函数register_chrdev

3、完成注册。注册成功后 ,该设备获得了系统分配或向系统申请的主设备号、自定义的次设备号,并建立起与设备文件的关联。设备驱动在卸载时需要回收相应的资源 ,将设备的响应寄存器值复位并从系统中注销该设备。系统调用部分则是对设备的 操作过程 , 比如 open、read、write、ioctl等操作。设备驱动程序可以分成以下 3个主要部分: (1) 自动配置和初始化子程序。负责检测所需驱动的硬件设备是否存在以及是否能正常工作 ,这部分驱动程序仅在初始化时被调用一次。(2) 服务 I/O 就是请求子程序,是驱动程序的上半部分,这部分是系统调用的结果。 (3) 中断服务程序又称驱动程序的下半部分,设备在 I

4、/O请求结束或其他状态改变时产生中断。因为设备驱动程序一般支持同一类型的若干个设备 ,所以调用中断服务子程序时都带有一个或多个参数以唯一标识请求服务的设备。 3字符设备驱动程序中重要的数据结构和函数对于每个系统调用,驱动程序中都有一个与之对应的函数。对于字符设备驱动程序 ,这些函数集合在一个file_op erations类型的数据结构中,它定义了常见文件I/O 函数的入口.编写字符设备驱动程序就是为具体硬件的 file_ operations结构编写各个函数 ,大多数的驱动程序只是利用了其中的一部分 对于驱动程序中不提供的功能,把相应位置的值设为 NULL ) ,对于字符设备来说 ,要提供的

5、主要入口有: open ( ) 、release ( ) 、read ( ) 、write( ) 、lseek ( ) 、ioctl ( )等。本课程设计中用到的主要有 open ( )、read ( )、write( )、release ( )函数。int (*open)(struct inode*,struct file*); 该操作用来打开设备文件。int (*release)(struct inode*,struct file*); 该操作用来释放文件结构。ssize_t(*read)(structfile*,char_user*,size_t,loff_t*); 该操作用来从设备中读

6、取数据。ssize_t(*read)(structfile*,char_user*,size_t,loff_t*); 该操作发送数据给设备。4驱动程序的注册和卸载驱动程序有一个初始化函数 ,在安装驱动程序时会调用它。在初始化函数中会将驱动程序的 file_operations与主设备号一起向内核进行注册。对字符设备使用如下函数进行注册:int register_chrdev ( unsigned int major, const char* name, struct file_operations* fop s) ; 其中,major是为设备驱动程序向系统申请的主设备号,如果为 0则系统动态地

7、分配 l个主设备号, name是设备名。fop s是 file_operation s对各个调用入口点的说明。此函数返回0表示成功;返回 - 1是表示出 错;返回 - E INVAL 表示申请的主设备号非法;返回- EBU SY表示所申请的主设备号正在被其他设备驱动程序使用。模块在调用 rmmod 函数时被卸载 ,此时的入口点是 cleanup_module函数或宏 module_exit,并在其中完成对设备的注销。类似的,字符设备的卸载函数定义为:int unregister_chrdev ( unsigned int major, const char* name) ;2、 实验目的:了解

8、、掌握字符型驱动程序的设计过程、编译、加载以及测试过程,包括了解file_operation数据结构、驱动程序的注册与注销、makefile文件的编写。 3、 实验步骤:写入驱动程序源程序fakedev.c,本程序设计思维为设备输入一串字符,再输出同样的字符。设备驱动程序的主体流程为:module_init->fakedev_init_module->register_chrdev->fakedev_fops->fakkdev_open/release/read/write. 源代码fakedev.c#include <linux/config.h> /*预

9、定义和必要的头文件*/#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/types.h>#include <linux/proc_fs.h>#include <l

10、inux/fcntl.h>#include <linux/seq_file.h>#include <linux/cdev.h>#include <asm/uaccess.h>#define DEVICE_NAME "fake device"MODULE_LICENSE("Dual BSD/GPL"); /*用宏来声明该模块的许可协议*/struct fake_device /* 该设备其他的私有数据和信号量的信息的定义 */int usage;char *data;int new_msg;struct fake_

11、device fakedev; int fakedev_major = 200; /*指定设备主设备号为200*/ /*以下为file_operation数据结构*/static int fakedev_open(struct inode *inode, struct file *file) /*定义了fakedev_open即打开操作函数,这里函数定义为只打印一行消息*/ printk ("fakedev_device_open(%p,%p)n", inode, file); return 0;static int fakedev_release(struct inode

12、 *inode, struct file *file) /*定义了 fakedev_release即释放文件结构函数。*/static void fakedev_device_release(%p,%p)n", inode, file);static ssize_t fakedev_read(struct file *f,char *buf,int size,loff_t off) /*定义了 fakedev_read即从设备中读取数据的函数*/ int length;int count=size;if(count<0)return -EINVAL;if(fakedev.usa

13、ge)return -EBUSY;fakedev.usage=1;if(fakedev.data =0 )return 0;length = strlen(fakedev.data);if (length < count)count=length;copy_to_user(buf,fakedev.data,count+1);fakedev.new_msg=0;fakedev.usage=0;return count;static ssize_t fakedev_write(struct file *f,const char *buf,int size,loff_t off) /*定义fa

14、kedev_write函数即发送数据给设备函数*/ int count=size;if(count<0)return -EINVAL;if(fakedev.usage|fakedev.new_msg)return -EBUSY;fakedev.usage = 1;kfree(fakedev.data);fakedev.data = kmalloc(sizeof(char)*(count + 1),GFP_KERNEL);if(!fakedev.data)return -ENOMEM;copy_from_user(fakedev.data,buf,count + 1);fakedev.us

15、age = 0;fakedev.new_msg = 1;return count;struct file_operations fakedev_fops = /*定义该字符设备的具体文件操作,包括read、write、open、release*/.read = fakedev_read, .write = fakedev_write,.open = fakedev_open,.release = fakedev_release,;static int fakedev_init_module(void) /*定义fakedev_init_module,即字符设备向 系统注册函数*/ int re

16、sult;result = register_chrdev(fakedev(fakedev_major,DEVICE_NAME,&fakedev_fops);if (result < 0)return result;if (fakedev_major = 0)fakedev_major = result;printk(KERN_INFO "Register FAKEDEV.major-number=%dn",result);return 0;static void fakedev_cleanup_module(void) /*定义fake_exit_modul

17、e,即字符设备向系统注销函数*/ printk(KERN_INFO "Unregister FAKEDEVn");unregister_chrdev(fakedev_major, DEVICE_NAME);module_init(fakedev_init_module); /*包含了注册、注销两个函数的指针*/module_exit(fakedev_cleanup_module);Makefile文件:在linux2.6内核中,模块的编译需要配置过的内核代码,编译过程首先会到内核源码目录下,读取顶层的makefile文件,然后再返回模块代码所在目录进行编译.可根据网络上公开

18、的针对字符设备驱动程序的makefile模板进行该模块makefile文件设计。 Makefile文件# Makefile2.6ifneq ($(KERNELRELEASE),)#kbuild syntax. dependency relationshsip of files and target modules are listed here.obj-m := fakedev.o /*指定模块源文件*/elsePWD := $(shell pwd)KVER ?= $(shell uname -r)KDIR := /lib/modules/$(KVER)/build /*指定内核源码的路径*/

19、all : $(MAKE) -C $(KDIR) M=$(PWD)clean : rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versionsendif通过执行makefile来编译驱动程序的源文件fakedev.c,以得到可执行目标文件。截图如下:由截图可见:编译之后得到可加载模块fakedev.ko。fakedev源程序的测试程序fakedev_test.c。测试的例程:运行之前需要使用mkond命令来创建设备文件,然后执行不带参数的insmod,将上面编译得到的可加载模块fakedev.ko装载到内核。测试代码fakedev_test.c#include<

20、;stdio.h> /*所需头文件与预定义*/#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#define MAX_LENGTH 100int mian (int argc, char *argv)char strMAX_LENGTH;char p;printf("please enter the words(max char num:%d):n",MAX_LENGTH -1);p = fgets(str,MAX_LENGTH,stdin); /*接收控制台输入的一组字符串*/int fakedev_fd=open("/dev/fakedev",O_RDWR);/*通过open系统调用打开虚拟设 if (fakedev_fd=-1) 备并获得文件描述符fakedev_fd*/perror(&qu

温馨提示

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

评论

0/150

提交评论