嵌入式系统中设备控制函数实现的分析

发布者:MagicGarden最新更新时间:2012-03-24 来源: 微计算机信息 关键字:嵌入式  Linux  控制函数  驱动程序 手机看文章 扫描二维码
随时随地手机看文章

1 引言

在Linux系统中,所有的外部设备都被看作是目录/dev下的一个文件,也就是系统把外部设备当作特殊文件来处理,并为外部设备提供一种标准接口,使得系统像访问文件一样访问外部设备。在嵌入式Linux中,同样也是把外部设备当作文件来处理,应用程序通过调用标准的设备文件操作函数来打开、关闭、读取和控制设备,从事过Linux开发的人员都用到过上述设备控制函数,可它的实现机制很多开发人员并不清楚,所以开发过程中经常遇到一些难以解决的问题,为了便于理解整个实现过程,下面先分析设备驱动程序。

2 设备驱动程序
2.1驱动程序的功能

驱动程序设计是嵌入式Linux开发中十分重要的部分,驱动程序是应用程序与硬件之间的一个中间软件层,应该为应用程序展现硬件的所有功能,不应该强加其它的约束,对于硬件使用的权限和限制应该有应用程序层控制。要实现设备函数对外围设备的操作和控制,首先必须分析驱动程序的构成和实现原理。

2.2驱动程序的基本结构及实现

嵌入式Linux设备驱动程序都有一些共性,就是编写所有类型的驱动程序都通用的,操作系统提供给驱动程序的支持也大致相同。这些特性包括:

 2.2.1两个重要的函数

(1)设备的注册和初始化mydriver_init()函数
         static int mydriver_init(void){
         int i;
         …………
         i = register_chrdev(MYDRIVER_MAJOR,“mydriver”,& mydriver_fops);
         …………
            }
i = register_chrdev(MYDRIVER_MAJOR,“mydriver”,& amp; mydriver_fops); 这是一个驱动程序的精髓,当执行insmod命令时,这个函数实现3个功能:第一,申请主设备号;第二,在内核中注册设备的名字;第三,指定fops方法。其中所指定的fops方法就是用户对设备进行操作的方法,例如 read,write,open,release等.  

(2) 驱动清除mydriver_cleanup()函数
static void mydriver_cleanup(void)
{…………
unregister_chrdev(MYDRIVER_MAJOR,”mydriver”); 
 …………              }
该函数在执行rmmod的时候被调用,主要功能是卸载驱动程序.

2.2.2 file_operations 结构

每一个文件都有一个file的结构,在这个结构中有一个file_operations的结构体,这个结构体指明了能够对该设备文件进行的操作, 如何实现这些操作,是编写设备驱动程序大部分工作量所在。下面是本文所举示例的file_operations结构: 
      设备short_ch对应的fops方法是这样声明的: 
      struct file_operations short_fops = { 
      NULL, // short_lseek  
      short_read, 
      short_write, 
      NULL, // short_readdir  
      NULL, // short_poll  
      NULL, // short_ioctl  
      NULL, // short_mmap 
      short_open, 
      short_release, 
      NULL, // short_fsync 
      NULL, // short_fasync  
            }; 
其中NULL的项目就是不定义这个功能。可以看出short_ch设备只提供了read, write, open, release功能。其中write 功能在下面(3)中实现了,具体的实现函数起名为short_write。这些函数就是真正对设备进行操作的函数,不管实现的时候是多么的复杂,但对用户来看,就是这些常用的文件操作函数。

2.2.3文件操作函数的实现

为了便于阐述和分析,把核心空间中的一个长度为20的数组 tbuf[20]做为一个设备。通过用户程序对它实现open,read,write,close操作。这个设备的名字我称为short_ch。我们编写如下的函数,这个write函数可以向核心内存的一个数组里输入一个字符串。 
      int short_write (struct inode *inode, struct file *filp, const char *buf,
      int count){ 
      int retval = count; 
      extern unsigned char kbuf[20]; 
      if(count>20) 
      count=20; 
      copy_from_user(kbuf, buf, count); 
      return retval; 
      }  [page]

3设备函数的实现过程分析

在嵌入式Linux下对设备操作的时候,一般都会用到read、 write、llseek和ioctl 等函数,通过这些函数可以像使用文件那样使用外部设备。这些函数的实现过程基本上是类似的,下面以write函数为例来分析用户使用write函数怎么把数据写到设备里面去。 

3.1应用程序中函数的格式

用户程序中的write函数有三个参数,函数格式如下: 
write(int fd, char *buf, int count)
其中参数fd表示将对之进行写操作的设备文件打开时返回的文件描述符.参数buf是一个指向缓冲区的指针,该指针指向存放将写入文件的数据的缓冲区.参数count表示本次操作所要写入文件的数据的字节数.fd一般大于3,0-2被系统分配给了默认的终端设备.

3.2驱动程序中函数的格式 

上面驱动程序函数定义中我们看到驱动程序里的write函数有四个参数,函数格式如下: 
short_write (struct inode *inode, struct file *filp, const char *buf, int count) inode 是设备节点指针,其中有设备号等信息,它能够告诉操作系统应该使用哪一个设备驱动程序,filp指针中有fops信息,可以告诉操作系统相应的fops方法函数在那里可以找到,后两项参数和应用程序中的含义相同。 

3.3应用程序中函数和驱动程序中函数的参数传递

从上面可以知道两个函数参数个数不同,当应用程序的write函数执行时,是怎么调用驱动程序中相应的write函数的呢?其实关键是Linux系统内核中的相应函数 sys_write,这也是最不透明最不容易理解的地方. Linux 内核中sys_write的源代码: 
      asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count) 
      { ssize_t ret; 
      struct file * file; 
      struct inode * inode; 
      ssize_t (*write)(struct file *, const char *, size_t, loff_t *); // 指向驱动程序中的wirte函数的指针 
      lock_kernel(); 
      ret = -EBADF; 
      file = fget(fd); // 通过文件描述符得到文件指针  
      if (!file) 
      goto bad_file; 
      if (!(file->f_mode & FMODE_WRITE)) 
      goto out; 
      inode = file->f_dentry->d_inode; // 得到inode信息 
      ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, file->f_pos,count); 
      if (ret) 
      goto out; 
      ret = -EINVAL; 
      if (!file->f_op || !(write = file->f_op->write)) // 将函数开始时声明的write函数指针指向fops方法中对应的write函数 
      goto out; 
      down(&inode->i_sem); 
      ret = write(file, buf, count, &file->f_pos); // 使用驱动程序中的write函数将数据输入设备,注意看,这里就是四个参数了 
      up(&inode->i_sem); 
      out: 
      fput(file); 
      bad_file: 
      unlock_kernel(); 
      return ret; }
     从上面的函数功能可以看出, sys_write函数实现了应用程序中write向驱动程序中的short_write的参数传递过程,其中上述注释语句详细地阐述了参数由三个到四个的变化过程。

4结论

总的来说,设备函数的实现过程由下面几个步骤来完成: 

(1) 加载驱动程序。驱动程序中的初始化函数申请设备名和主设备号,这些可以在/proc/devieces目录中查看到。 (2)从/proc /devices中获得主设备号,驱动程序加载成功后建立设备节点文件。通过主设备号将设备节点文件和设备驱动程序联系在一起。设备节点文件中的file 属性中指明了驱动程序中fops方法实现的函数指针。 (3)用户程序使用open打开设备节点文件,这时操作系统内核知道该驱动程序工作了,就调用 fops方法中的open函数进行相应的工作。 (4)当用户使用write函数操作设备文件时,操作系统调用内核中的sys_write函数,该函数首先通过文件描述符得到设备节点文件对应的inode指针和filp指针。 (5)然后sys_write才会调用驱动程序中的write方法来对设备进行写的操作。用户的write函数和驱动程序的write函数通过系统调用sys_write联系到了一起。本文以设备文件操作控制函数write为例来阐述整个函数的调用过程,其它函数的过程基本相同,本文不再详述。

本文的创新点在于阐述了嵌入式应用程序中对外部设备操作控制函数的实现机制及具体过程的分析,在目前的文献中很少有具体的分析,是作者在具体开发过程中的经验总结。
本文有国家自然科学基金项目支持,项目编号:50677047。

参考文献:
[1]张林杰 ,朱晓丽。嵌入式 Linux下可插拔输入驱动机制研究, 微计算机信息, 2006第29期, 195-197
[2]杜博,方向忠。嵌入式Linux系统下I2C设备驱动程序的开发,  微计算机信息,2006第11期,31-34
[3] 李善平, 刘文峰等《 Linux内核2.4版源代码分析大全》, 机械工业出版社, 2002年1月第1版, 310-312
[4] 贾明, 严世贤。 《Linux下的C编程》,人民邮电出版社, 2001年11月第1版,   157-158
[5]魏永明等译,《LINUX 设备驱动程序》,中国电力出版社,2006年6月第1版,59-62

关键字:嵌入式  Linux  控制函数  驱动程序 引用地址:嵌入式系统中设备控制函数实现的分析

上一篇:一种嵌入式IPv4/IPv6双协议栈的实现
下一篇:Linux嵌入式视频直播监控系统

推荐阅读最新更新时间:2024-03-16 12:56

嵌入式OSEK配置器的设计与实现
随着汽车工业的快速发展,汽车对控制、通信、网络管理等方面的要求越来越高,基于32位微控制器的硬件平台、基于嵌入式实时操作系统的软件平台和基于CAN总线的网络通信平台逐渐成为当今汽车电子业的主流。 1 OSEK/VDX规范简介 在嵌入式实时操作系统方面,为了满足日益庞大、复杂的汽车电子控制软件的开发需要,实现应用软件的可移植性和不同厂商控制模块间的可兼容性,1993年德国汽车工业界联合推出了汽车电子的开放式系统及接口——OSEK/VDX规范(以下简称“OSEK规范”),旨在为汽车上的分布控制单元提供一个开放结构的工业标准。OSEK规范从实时操作系统(RTOS)、软件接口、通信和网络管理等方面对汽车电子控制软件开发平台作了较为全面
[嵌入式]
嵌入式处理器Nios II与液晶显示模块的接口及应用
  液晶显示器(LCD)由于具有工作电压低、功耗低、体积小、显示信息量大、寿命长、不产生电磁辐射污染、可以显示复杂的文字及图形等优点,液晶显示器已被广泛应用于各种仪器仪表、电子设备及控制领域中,成为测量结果显示和人机对话的重要工具。液晶显示器按其功能可分为笔段式和点矩阵式液晶显示器,后者又可以分为字符点阵式和图形点阵式液晶显示器。图形点阵式液晶显示器不仅可显示数字、字符等内容,还能显示汉字和任意图形。   本文是以240*128点阵型液晶显示模块MGL240128T为例。研究嵌入式Nios II软核处理器与液晶显示模块的接口和图形显示的编程技术。   1 Nios II软核处理器和SOPC设计   在2004年,Alter推
[嵌入式]
图形液晶显示模块在嵌入式系统中的应用
      图形点阵式液晶显示模块具有尺寸小、功耗低、寿命长、成本低、可显示各种图像与文本信息等优点,因此在各种仪器仪表、电子设备、移动通讯及家用电器中得到广泛的应用 。本文结合笔者在“便携式电力故障录波仪”项目中的实践经验,着重介绍如何把液晶显示模块应用做嵌入式DSP系统人机界面的问题,仅用四个按键相互配合,通过软件编程实现多层菜单和动态波形的显示。软件部分采用C语言编制,模块化设计,具有很强的可移植性,可以直接应用到其他的嵌入式系统中。 1. 模块的工作原理 1.1 基本功能         OCM4×8C液晶显示模块是128×64点阵的汉字图形型液晶显示模块,内置国标GB2312码简体中文字库(16×16点阵)、126个字
[嵌入式]
嵌入式系统中USB主机控制器的实现
  通用串行总线(USB)接口具有简单灵活、高带宽、易于扩展和热插拔等优点,它目前已成为数码设备的标准接口之一,小到U盘、MP3,大到数码相机、打印机,USB接口的身影无处不在。但我们目前所使用的USB移动设备多为USB的外设(Device) , 比如USB的移动硬盘、USB接口的数码相机,一般只能在PC上使用,即只能通过PC实现文件和数据的交换。   业界和用户的需求呼唤USB主机的嵌入式化,因此在嵌入式系统中实现USB主机功能成了USB设计领域的热点之一。   迄今为止,嵌入式USB主机的最大市场和增长点在移动消费电子设备领域, 比如PDA与USB记忆棒传递数据、MP3之间传递歌曲、数码相机连接打印机等。   嵌入式US
[单片机]
<font color='red'>嵌入式</font>系统中USB主机<font color='red'>控制</font>器的实现
用中断方式在嵌入式操作系统μC/OS-Ⅱ上实现多任务通信
引 言 当今,各种嵌入式的电子产品已经深入到我们生活的方方面面,嵌入式操作系统也已成为最热门的话题之一,其中免费型的实时操作系统μC/OS-Ⅱ因其可移植、可固化、可裁剪、可确定性等特点,已经成功的应用在很多商业产品上。在嵌入式操作系统中,对中断的处理分为两个部分:面向应用的编程接口部分和面向底层的处理部分,因为涉及这两部分的文件众多,关联复杂,对软硬件的熟悉程度要求较高,较之查询方式编写程序过程相应也要复杂一些,所以以往大多数应用都使用查询方式来进行数据通信。但使用中断方式可以提高处理器的工作效率以及提高对实时数据的处理实效,文章将着重讨论如何用中断方式在嵌入式操作系统μC/OS-Ⅱ上实现多任务通信。 S3C44B
[单片机]
用中断方式在<font color='red'>嵌入式</font>操作系统μC/OS-Ⅱ上实现多任务通信
基于tiny4412的Linux内核移植(支持device tree)(三)
平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)) 注意 继续上文。 到目前为止,板子已经可以起来了,接下来就可以针对板子的情况移植驱动程序了。
[单片机]
爱特梅尔和TimeSys为AT91CAP提供Linux支持
爱特梅尔公司 (Atmel® Corporation) 和 TimeSys® 公司联合宣布,将为爱特梅尔以 ARM9™ 为基础的 AT91CAP9 可定制微控制器提供嵌入式Linux® 支持,有助快速验证设计。TimeSys为CAP9 提供免费的2.6.23 内核Linux 板级支持包 (BSP)。而且,这款免费的BSP可升级为全面的 LinuxLink 订阅服务,从而提供功能强大的整套软件、工具和技术支持,以加快定制Linux平台的开发工作。 免费的 BSP 可让应用开发人员在 AT91CAP9A 开发板上进行快速 Linux 验证。开发板上的FPGA用于仿真定制逻辑的金属可编程模块 (Metal Programm
[新品]
一种基于ARM的嵌入式网关系统设计与实现
引 言 CAN(Controller Area Network)为控制器局域网络,CAN总线规范已经被国际标准化组织制订为国际标准ISO11898,并得到众多半导体器件厂商的支持,推出各种集成有CAN协议的产品。CAN属于总线式串行通信网络,由于其采用了许多新技术和独特的设计,低成本、高可靠性、实时性、灵活性、抗干扰能力强等特点,已被广泛应用于各个自动化控制系统中。在汽车电子、自动控制、电力系统等领域,CAN总线具有无可比拟的优越性。 以太网以其通信数据量大、传输速度快、开放性好、成本低等优点,弥补了现场总线通信速率低的缺陷,成为现阶段信息网络应用最广的局域网技术。用以太网直接进入工业控制领域,目前还存在一些问题,以太网的
[单片机]
一种基于ARM的<font color='red'>嵌入式</font>网关系统设计与实现
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved