嵌入式linux驱动开发流程
嵌入式系统中,操作系统是通过各种驱动程序来驾驭硬件设备的。设备驱动程序是操作系统内核和硬件设备之间的接口,它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,可以像操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,完成以下功能:
◇ 驱动程序的注册和注销。
◇ 设备的打开和释放。
◇ 设备的读写操作。
◇ 设备的控制操作。
◇ 设备的中断和轮询处理。
Linux主要将设备分为三类:字符设备、块设备和网络设备。字符设备是指发送和接收数据以字符的形式进行,没有缓冲区的设备;块设备是指发送和接收数据以整个数据缓冲区的形式进行的设备;网络设备是指网络设备访问的BSD socket 接口。下面以字符设备为例,写出其驱动编写框架:
一、 编写驱动程序初始化函数
  驱动程序的初始化在函数xxx_init()中完成,包括对硬件初始化、中断函数、向内核注册驱动程序等。
  首先理解硬件结构,搞清楚其功能,接口寄存器以及CPU怎么访问控制这些寄存器等。
  其次向内核注册驱动程序。设备驱动程序可以直接编译进内核,在系统启动的时候初始化,也可以在需要的时候以模块的方式动态加载到内核中去。每个字符设备或是块设备都是通过register_chrdev()函数注册,调用该函数后就可以向系统申请主设备号,操作成功,设备名就会出现在/proc/devices里。
  此外,在关闭设备时,需要先解除原先设备的注册,需要有清除函数,在xxx_exit()中通过unregister_chrdev()函数在实现,此后设备就会从/proc/devices里消失。
  当驱动程序被编译成模块时,使用insmod加载模块,模块的初始化函数xxx_init()被调用,向内核注册驱动程序;使用rmmod卸载模块,模块的清除函数xxx_exit()被调用。
二、 构造file_operations结构中要用到的各个成员函数
  Linux操作系统将所有的设备都看成文件,以操作文件的方式访问设备。应用程序不能直接操作硬件,使用统一的接口函数调用硬件驱动程序,这组接口被成为系统调用。每个系统调用中都有一个与之对应的函数(open、release、read、write、ioctl等),在字符驱动程序中,这些函数集合在一个file_operations类型的数据结构中。以一个键盘驱动程序为例:
struct file_operations Key7279_fops =  
{
.open = Key7279_Open,  
.ioctl = Key7279_Ioctl,  
.release = Key7279_Close,
.read = Key7279_Read,
};
1、 设备的打开和释放
  打开设备是由open()函数来完成,在大部分设备驱动中open完成如下工作:
  ◇ 递增计数器
  ◇ 检查特定设备的特殊情况
  ◇ 初始化设备
  ◇ 识别次设备号
  释放设备由release()函数来完成。当一个进程释放设备时,其它进程还能继续使用该设备,只是该进程暂时停止对该设备的的使用,而当一个进程关闭设备时,其它进程必须重新打开此设备才能使用。Release完成如下工作:
◇ 递减计数
◇ 在最后一次释放设备操作时关闭设备
2、 设备的读写操作
  读写设备的主要任务就是把内核空间的数据复制到用户空间,或者是从用户空间复制到内核空间,也就是将内核空间缓冲区里的数据复制到用户空间的缓冲区中或者相反。字符设备使用各自的read()函数和write()函数来进行数据读写。
3、 设备的控制操作
大部分设备除了读写能力,还可进行超出简单的数据传输之外的操作,所以设备驱动也必须具备进行各种硬件控制操作的能力. 这些操作常常通过 ioctl 方法来支持。与读写操作不同,ioctl()的用法与具体设备密切相关。以键盘Key7279_Ioctl为例:
static int Key7279_Ioctl(struct inode *inode,struct file *file,unsigned int cmd, unsigned long arg)
{
switch(cmd)  
  {
  case Key7279_GETKEY:
return key7279_getkey();
  default:
  printk("Unkown Keyboard Command ID.\n");
  }
  return 0;
}
  cmd的取值及含义都与具体的设备有关,除了ioctl(),设备驱动程序还可能有其他控制函数,比如llseek()等。
  当应用程序使用open、release等函数打开某个设备时,设备驱动程序的file_operations结构中的相应成员就会被调用。
三、设备的中断和轮询处理
  对于不支持中断的设备,读写时需要轮询设备状态,以及是否需要继续进行数据传输。例如,打印机。如果设备支持中断,则可按照中断方式进行。
模块在使用中断前要先请求一个中断通道(或者 IRQ中断请求),并在使用后释放它。通过request_irq()函数来注册中断,free_irq()函数来释放。
四、驱动程序的测试
  对驱动程序的调试可以通过打印的方式来进行,就是通过在驱动程序中添加printk()打印函数,来跟踪驱动程序的执行过程,以此来判断问题。
  以上是我根据自己的学习总结的,可能写的比较简单,对于比较复杂的驱动函数,会添加更多的函数,但是大体的框架就是这样了。

基于操作系统的驱动就是在无操作系统下的硬件接口函数加上操作系统外套

实现一个嵌入式Linux设备驱动程序的大致流程如下:
(l)查看原理图,理解设备的工作原理。
(2)定义主设备号。设备由一个主设备号和一个次设备号来标识。主设备号唯一标识了设
备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅
由设备驱动程序解释,区分被一个设备驱动控制下的某个独立的设备。
(3)实现初始化函数。在驱动程序中实现驱动的注册和卸载。
(4)设计所要实现的文件操作,定义file--operations结构。
(5)实现所需的文件操作调用,如read,write等。
(6)实现中断服务,并用request--irq向内核注册,中断并不是每个设备驱动所必需的。
(7)编译该驱动程序到内核中,或者用insmod命令加载模块。
(8)测试该设备,编写应用程序,对驱动程序进行测试。

典型字符设备驱动编写框架:

1 编写硬件接口函数

2 建立文件系统与设备驱动程序间的接口,如:struct file_operations结构体

3 注册设备到chrdevfs全局数组中,注册或注销设备可以在任何时候,但一般在模块加载时注册设备,在模块退出时注销设备。(module_init();module_exit();)

4 以模块方式编译驱动源码,并将其加载到内核中

5 创建设备节点,mknode

6 编写应用程序访问底层设备

linux驱动开发流程的更多相关文章

  1. 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  2. 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  3. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  4. Linux内核(17) - 高效学习Linux驱动开发

    这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到 ...

  5. linux驱动开发重点关注内容--摘自《嵌入式Linux驱动模板精讲与项目实践》

    本文摘自本人拙著 <嵌入式Linux驱动模板精讲与项目实践> 初步看起来Linux设备驱动开发涉及内容非常多,而须要实现驱动的设备千差万别.事实上做一段时间驱动之后回首看来主要就是下面几点 ...

  6. 嵌入式Linux驱动开发日记

    嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...

  7. 【转】linux驱动开发的经典书籍

    原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书 ...

  8. Linux驱动开发 -- 打开dev_dbg()

    Linux驱动开发 -- 打开dev_dbg() -- :: 分类: LINUX linux设备驱动调试,我们在内核中看到内核使用dev_dbg来控制输出信息,这个函数的实质是调用printk(KER ...

  9. Linux驱动开发学习的一些必要步骤

      1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ...

随机推荐

  1. docker-compose volumes指令路径映射问题

    背景:最近在自学docker容器知识,在跟着<Docker - 从入门到实践>进行 docker-compose 搭建django/postgreSQL 实例.在搭建过程中由于自己操作失误 ...

  2. 多线程并发情况下 重复insert问题

    代码逻辑: if(数据不存在){ insert(); } 线程启动后,发现数据库表中有相同的记录 解决方案 synchronized同步代码块即加同步锁,synchronized同步代码块的功能: 当 ...

  3. 大数据学习——sqoop安装

    1上传  sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz 2解压 .bin__hadoop--alpha.tar.gz 3重命名 .bin__hadoop--al ...

  4. Neural Networks and Deep Learning

    Neural Networks and Deep Learning This is the first course of the deep learning specialization at Co ...

  5. Convolution Fundamental II

    Practical Advice Using Open-Source Implementation We have learned a lot of NNs and ConvNets architec ...

  6. 九度oj 题目1207:质因数的个数

    题目描述: 求正整数N(N>1)的质因数的个数. 相同的质因数需要重复计算.如120=2*2*2*3*5,共有5个质因数. 输入: 可能有多组测试数据,每组测试数据的输入是一个正整数N,(1&l ...

  7. resetlogs报错 ORA-00392

      alter database open resetlogs或者 alter database open resetlogs upgrade报错:ORA-00392     在rman restor ...

  8. [luoguP1053] 篝火晚会(贪心 + 乱搞)

    传送门 假设第一个位置是1,那么枚举它的左右两边是谁,有两种情况,然后可以递推求出序列. 然后可以贪心,两个序列有多少个不同的数,答案就是多少,具体为啥,yy一下即可 然后就是判断递推求出的序列和目标 ...

  9. BZOJ 2431: [HAOI2009]逆序对数列【dp】

    Description 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那么逆序 ...

  10. Nastya Studies Informatics

    Nastya Studies Informatics   time limit per test 1 second   memory limit per test 256 megabytes   in ...