2024年6月6日发(作者:)

28

卷第

4

期增刊

 

2007

4

仪 器 仪 表 学 报

ChineseJournalofScientificInstrument

Vol.28No.4

Apr.2007

 

嵌入式

Linux

GPIO

驱动程序的开发及应用

3

何 泉

,

贺玉梅

(

北京化工大学信息科学与技术学院 北京 

100029

)

摘 要

:

嵌入式

Linux

是一种适用于嵌入式系统的源码开放的占先式实时多任务操作系统

,

是目前操作系统领域中的一个热点

,

其重点与难点是驱动程序的开发。开发嵌人式

Linux

下的设备驱动程序

,

可以更好地利用新硬件特性

,

提高系统访问硬件的效

,

改善整个应用系统的性能。驱动程序修改非常方便

,

使应用系统非常灵活。本文简要论述了基于

ATMEL

公司嵌入式

ARM

处理器芯片的嵌入式

Linux

GPIO

驱动程序的开发原理及流程。

关键词

:

嵌入式

Linux;ARM;

驱动程序

;

设备文件

;GPIO

InvestigationandapplicationofGPIOdriverintheembeddedLinux

HeQuan,HeYuMei

(

SchoolofInformationScienceandTechnologyBUCT,Beijing100029,China

)

Abstract:EmbeddedLinux,whichisafullyreal

2

timekernelandapplicabletoembeddedsystems,hasbecomeahots

2

pingdevice

driversonembeddedLinuxcanhelpusingthenewdevices,andimprovingtheefficiencyofaccesstothenewdevices

erscanbechangedeasily,

2

persimplypointsouttheelementsandflowoftheGPIOdriverintheembeddedLinuxbasedontheARMprocessorof

ATMELsystem.

Keywords:embeddedLinux;ARM;driver;devicefile;GPIO

符设备、块设备和网络设备

[1]

。本设计中驱动的设备

1

 引  言

随着半导体技术的飞速发展

,

嵌入式产品已经广

泛应用于军事、消费电子、网络通信、工业控制等各个

领域

,

这是嵌入式系统发展的必然趋势。

Linux

操作

系统以其开放的源代码、内核稳定、功能强大、可裁减

等优点而成为当今流行的操作系统之一。嵌入式

Linux

继承了

Linux

的诸多优点

,

非常适用于嵌入式

系统。

设备驱动程序为应用程序屏蔽了硬件的细节

,

应用程序看来

,

硬件设备只是一个设备文件

,

应用程序

可以像操作普通文件一样对硬件设备进行操作。在嵌

入式

Linux

操作系统下有

3

类主要的设备文件类型

:

是基于

AT91RM9200

开发系统中的

GPIO

,

属于字

符设备

,

通过设备驱动的方式对其设置高、低电平。

设备驱动程序可以完成以下功能

:

对设备初始化

和释放

;

把数据从内核传到硬件和从硬件读取数据

;

读取应用程序传送给设备文件的数据和回送给应用

程序请求的数据

;

检测和处理设备出现的错误

[2]

2

 

ARM

处理器

AT91RM9200

简介

ATMEL

AT91RM9200

(

32

RISC

微处理

)

是一款高性能、低功耗、低成本的嵌入式

ARM

处理器。

AT91RM9200

ARM920T

内核和其它一

些外围接口器件组成

,

片内资源非常丰富

,

具有极高

 3基金项目

:

国家自然科学基金

(

60472044

)

、北京化工大学青年教师自然科学研究基金

(

QN0518

)

资助项目

© 1994-2010 China Academic Journal Electronic Publishing House. All rights reserved.

 

272

         仪 器 仪 表 学 报第

28

卷 

的集成度

,

非常适用于嵌入式系统应用。

它具有以下特性

:

内核运行于

180MHz

时性能

高达

200MIPS;16KB

的数据缓存

,16KB

的指令缓

,

具有写缓冲器

;

具有内存管理单元

MMU;

附加的

嵌入式存储器

,SRAM

16KB,ROM

128KB

[3]

3

 

GPIO

驱动程序的开发流程

驱动程序是指一组子程序

,

它屏蔽了底层硬件处

理细节同时向上层软件提供与硬件无关的接口

,

Linux

内核中占据极其重要的地位

,

是内核完成对物

理设备的控制操作的功能模块。设备驱动程序控制

操作系统和硬件设备之间的交互操作

,

是操作系统的

重要组成部分。对于一个特定的硬件设备来说

,

其对

应的设备驱动程序也是特定的。驱动程序在一个高

优先级的环境下工作

,

如果发生错误可能会引发严重

的问题。

3

1

1

 设备驱动模块化编程

字符设备是

Linux

设备中最简单和常见的设备

,

应用程序可以用与存取文件相同的系统调用来操作

它。字符设备驱动在初始化时通过在内核的

device_

struct

结构的

chrdevs

数组中添加一个设备号和由用

户自定义的设备文件名

,

对该设备进行标识。

Linux

以模块的形式加载设备

,

一个模块对应实

1

 设备驱动在内核中的挂接、卸载

和系统调用过程

2

 字符设备和内核的接口

现一个设备驱动

,

同时一个设备驱动对应一类设备

,

便于多个设备的协调工作也利于应用程序的开发和

扩展。设备驱动在加载时首先需要调用入口函数

init

_module

()

,

该函数完成设备驱动的初始化工作

,

比如

寄存器置位、结构体赋值等一系列工作。其中最重要

的一个工作就是向内核注册该设备

,

字符设备调用函

register_chrdev

()

完成注册。注册成功后

,

该设备

获得了系统分配或向系统申请的主设备号、自定义的

次设备号

,

并建立起与设备文件的关联。设备驱动在

卸载时需要回收相应的资源

,

将设备的响应寄存器值

复位并从系统中注销该设备。系统调用部分则是对

设备的操作过程

,

比如

open,read,write,ioctl

等操

作。图

1

就是将一个设备驱动模块动态挂载、卸载和

系统调用的全过程。

字符设备和内核的接口如图

2

所示。

3

1

2

 

file_operations

数据结构

每个设备驱动程序都对应一个

file_operations

数据结构

,file_operations

是定义在

的函数指针数组。在

file_operations

中定义一些与

此设备相关的功能函数

,

当用户进行系统调用时

,

自动使用驱动程序中特定的函数来实现具体的操作。

内核内部通过

file

结构识别设备

,

通过

file_oper

2

ations

数据结构提供文件系统的入口函数

,

也就是访

问设备驱动的函数。由于用户是通过设备文件同硬

件打交道

,

以系统调用的方式对设备文件进行操作

,

并通过完成

file_operations

中的函数指针来把系统

调用和驱动程序关联起来。在本设计中定义的

GPIO

_write

()

函数就是系统调用

write

指向的驱动函数

:

structfile_operationsGPIO_fops=

  

{

   

write:

(

void

(

3

))

GPIO_write,

  

};

3

1

3

 注册模块

Linux

,

为了操作系统区别不同驱动程序的

标识

,

任何设备都必须有一个主设备号。在本设计中

为设备指定分配一个设备号

,

由以下语句实现

:

staticintgmajor=254

retv=register_chrdev

(

gmajor,GPIO_name,

&GPIO_fops

)

© 1994-2010 China Academic Journal Electronic Publishing House. All rights reserved.

 第

4

期增刊何 泉等

:

嵌入式

Linux

GPIO

驱动程序的开发及应用

 

273

函数

register_chrdev

()

中定

,

用于向内核注册

GPIO

字符设备。其中

gmajor

参数用于传递我们指定的设备号

254,

如申请成功

,

register_chrdev

()

函数返回

0,

否则返回负值。

3

1

4

 注销模块

注销模块是和注册模块对应的操作

,

当卸载模块

,

系统将注销模块对应的设备

,

并释放主设备号

,

一操作可以在模块的清除函数中调用

unregister_

chrdev

()

函数来完成

,

由以下语句实现

:

retv=unregister_chrdev

(

gmajor,GPIO_name

)

;

unregister_chrdev

()

函数用于注销设备、释放主

设备号和设备文件名。参数包括要释放的主设备号

和对应的设备名

,

内核用这个设备名与主设备号参数

所对应的已注册设备进行比较

,

如不同

,

或是主设备

号超出了允许范围

,

则返回2

EINVAL

3

1

5

 写设备函数的具体实现

,

动态加载是指将设备驱动模块加载到内核中

,

系统启动的时候和内核一起启动

,

这样的方法在嵌入

Linux

系统中经常被应用。通常情况下设备驱动

的动态加载更为普遍

,

这样不必在调试过程中频繁启

动机器就可以完成驱动的开发工作。

编写简单测试程序来测试驱动程序

,

由于此

I/O

口的作用是用来驱动蜂鸣器

,I/O

口置

1

时蜂鸣器鸣

,

测试程序的目的是控制蜂鸣器的鸣叫次数及每次

鸣叫的持续时间

,

编译运行后得到预期效果。

5

 结  论

本文论述了嵌入式

Linux

GPIO

驱动程序的

基本原理和开发流程

,

经过测试后得到预期结果。在

驱动程序的开发中

,

驱动程序的作用在于提供机制

(

mechanism

)

,

而不是提供策略

(

policy

)

。优良的驱

动程序在保持稳定和提供较多功能的前提下要很好

的区分机制和策略。机制在于需要提供什么功能

,

策略在于如何使用这些功能

[5]

。因而

,

在驱动程序中

不涉及对设备的具体使用方法

,

这些问题留给应用程

序来处理。同时

,

嵌入式

Linux

必将能得到更加广泛

的应用。

  参考文献

[1]

 孙天泽

,

袁文菊

,

张海峰

.

嵌入式设计及

Linux

驱动开发

应用程序可以通过对文件进行操作

,

使得系统调

用和设备驱动的实现方法之间对应起来

,

具体的实现

函数就是

GPIO_write

()

,

该函数完成向特定设备的

数据传输。由以下语句实现

:

staticintGPIO_write

(

structfile

3

GPIO_file,

constchar

3

buf,intlen,loff_t

3

loff

)

设备驱动程序作为

Linux

内核的一部分

,

运行在

内核空间

,

而应用程序运行在用户空间

,

因此

,

如何在

内核空间和用户空间进行数据传输

,

是需要解决的问

[4]

。内核函数

copy_from_user

()

可以实现由用户

空间到内核空间的数据复制

,

实现了

write

系统调用

,

从用户空间复制到内核空间的数据最终会对硬件设

备进行操作。

指南———基于

ARM9

处理器

[M].

北京

:

电子工业出版

,2005.

[2]

 王多智

.

嵌入式

Linux

SRAM

驱动程序的开发及应用

[J].

微计算机信息

,2005,21

(

5

)

:73

2

75.

[3]

 

AT91RM9200datasheet[Z].

[4]

 李驹光

,

郑耿

,

江泽明

.

嵌入式

Linux

系统开发详解

[M].

4

 测试本驱动模块

登录到

Linux

系统下编写

makefile

文件并编译

模块

,

将生成的目标文件动态加载到目标系统的内核

北京

:

清华大学出版社

,2006.

[5]

 魏永明

.Linux

设备驱动程序

[M].

北京

:

中国电力出版

,2006.

© 1994-2010 China Academic Journal Electronic Publishing House. All rights reserved.