频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

Linux系统的硬件驱动程序编写原理

来源:天极网 作者:鲁锋 出处:巧巧读书 2007-09-28 进入讨论组
上一页 1 2 3 4 5 6 下一页 

  首先了解一下Linux的内核编程环境。我们知道每个Linux用户进程都在一个独立的系统空间中运行着,与系统区和其他用户进程相隔离。这样就保护了一个用户进程的运行环境,以免被其他用户进程所破坏。与这种情况正相反的是,设备驱动程序运行在内核模式,它们具有很大的自由度。
这些设备驱动程序都是被假设为正确和可靠的,它们是内核的一部分,可以处理系统中断请求和访问外围设备,同时它们有效地处理中断请求以便系统调度程序保持系统需求的平衡。所以设备驱动程序可以脱离系统的限制来使用系统区,比如系统的缓冲区等等。

  一个设备驱动程序同时包括中断和同步区域。其中中断区域处理实时事件并且被设备的中断所驱动;而同步区域则组成了设备的剩余部分,处理进程的同步事件。所以,当一个设备需要一些软件服务时,就发出一个"中断",然后中断处理器得到产生中断的原因同时进行相应的动作。

  一个Linux进程可能会在事件发生之前一直等待下去。例如,一个进程可能会在运行中等待一些写入硬件设备的信息的到来。其中一种方式是进程可以使用sleep()和wakeup()这两个系统调用,进程先使自己处于睡眠状态,等待事件的到来,一旦事件发生,进程即可被唤醒。举个例子来说:interruptible_sleep_on(&dev_wait_queue)函数使进程睡眠并且将此进程的进程号加到进程睡眠列表dev_wait_queue中,一旦设备准备好后,设备发出一个中断,从而导致设备驱动程序中相应的例程被调用,这个驱动程序例程处理完一些设备要求的事宜后会发出一个唤醒进程的信号,通常使用wake_up_interruptible(&dev_wait_queue)函数,它可以唤醒dev_wait_queue所示列表中的所有进程。

  特别要注意的是,如果两个和两个以上的进程共享一些公共数据区时,我们必须将之视为临界区,临界区保证了进程间互斥地访问公共数据。在Linux系统中我们可以使用cli()和sti()两个内核例程来处理这种互斥,当一个进程在访问临界区时可以使用cli()来关闭中断,离开时则使用sti()再将中断打开,就像下面的写法:

  cli()

   临界区

  sti()

除了以上这些,我们还得了解一下虚拟文件系统交换(VFS)的概念。

Linux系统的硬件驱动程序编写原理(图五)
          图6 虚拟文件系统交换

图6中的"文件操作结构"在/usr/include/linux/fs.h文件中定义,此结构包含了驱动程序中的函数列表。图上的初始化例程xxx_init()根据VFS和设备的主设备号来注册"文件操作结构"。
下面是一些设备驱动程序的支撑函数(具体使用方法详见Linux编程手册,使用man命令):

  add_timer()

  定时间一过,可以引发函数的执行;

  cli()

  关闭中断,阻止中断的捕获;

  end_request()

  当一个请求被完成或被撤销时被执行;

  free_irq()

  释放一个先前被request_irq()和irqaction()捕获的的中断请求;

  get_fs*()

  允许一个设备驱动程序访问用户区数据(一块不属于内核的内存区);

  inb(), inb_p()

  从一个端口读取一个字节,其中inb_p() 会一直阻塞直到从端口得到字节为止;

  irqaction()

  注册一个中断;

  IS_*(inode)

  测试inode是否在一个被mount了的文件系统上;

  kfree*()

  放先前被kmalloc()分配的内存区;

  kmalloc()

  分配大于4096个字节的大块内存区;

  MAJOR()

  返回设备的主设备号;

  MINOR()

  返回设备的次设备号;

  memcpy_*fs()

  在用户区和内核区之间复制大块的内存;

  outb(), outb_p()

  向一个端口写一个字节,其中outb_p()一直阻塞直到写字节成功为止;

  printk()

  内核使用的printf()版本;

  put_fs*()

  允许设备驱动程序将数据写入用户区;

  register_*dev()

  在内核中注册一个设备;

  request_irq()

  向内核申请一个中断请求IRQ,如果成功则安装一个中断请求处理器;

  select_wait()

  将一个进程加到相应select_wait队列中;

  *sleep_on()

  使进程睡眠以等待事件的到来,并且将wait_queue 入口点加到列表中以便事件到来时将进程唤醒;

  sti()

  和cti()相对应,恢复中断捕获;

  sys_get*()

  系统调用,得到进程的有关信息;

  wake_up*()

  唤醒先前被*sleep_on() 睡眠的进程;查看 http://www.qqread.com/data-structure/y205563.html 更多文章 更多内容请看系统优化大全系统安全设置系统安装手册专题,或进入讨论组讨论。
上一页 1 2 3 4 5 6 下一页 
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章