1 / 39

嵌入式设备驱动

嵌入式设备驱动. 陈文智 wzchen@cad.zju.edu.cn 浙江大学计算机学院 2005 年 4 月. 提纲. 1 、 Linux 下设备驱动程序简介 2 、设备驱动程序结构 3 、设备驱动实验 实验一:编写一个简单的驱动程序 实验二:设计和实现一个 KED&LED 驱动程序 实验三:静态编译驱动程序,连接到内核 实验四:使用中断方式的驱动程序设计. 1 、 Linux 下设备驱动程序简介. 系统调用是操作系统内核和应用程序之间的接口 设备驱动程序是操作系统内核和机器硬件之间的接口

jens
Download Presentation

嵌入式设备驱动

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 嵌入式设备驱动 陈文智 wzchen@cad.zju.edu.cn 浙江大学计算机学院 2005年4月

  2. 提纲 • 1、Linux下设备驱动程序简介 • 2、设备驱动程序结构 • 3、设备驱动实验 • 实验一:编写一个简单的驱动程序 • 实验二:设计和实现一个KED&LED驱动程序 • 实验三:静态编译驱动程序,连接到内核 • 实验四:使用中断方式的驱动程序设计

  3. 1、Linux下设备驱动程序简介 • 系统调用是操作系统内核和应用程序之间的接口 • 设备驱动程序是操作系统内核和机器硬件之间的接口 • Linux设备驱动的特点是可以以模块的形式加载各种设备类型 • 因为嵌入式设备往往具有大量的独有外设,开发人员需要把很多精力放在设备驱动方面

  4. 1.1 Linux设备的分类 • 字符设备 • 以字节为单位逐个进行I/O操作 • 字符设备中的缓存是可有可无 • 不支持随机访问 • 如串口设备/dev/cua0和/dev/cua1 • 块设备 • 块设备的存取是通过buffer、cache来进行 • 可以进行随机访问 • 例如IDE硬盘设备/dev/hda • 可以支持可安装文件系统 • 网络设备 • 通过BSD套接口访问

  5. 1.2 Linux设备文件 • Linux抽象了对硬件的处理,所有的硬件设备都可以作为普通文件一样来看待 • 可以使用和操作文件相同的、标准的系统调用接口来完成打开、关闭、读写和I/O控制操作 • 对用户来说,设备文件与普通文件并无区别

  6. 1.3 主设备号和次设备号 • 主设备号:标识该设备的种类,也标识了该设备所使用的驱动程序 • 次设备号:标识使用同一设备驱动程序的不同硬件设备 • 所有已经注册(即已经加载了驱动程序)的硬件设备的主设备号可以从/proc/devices文件中得到

  7. 1.4 Linux设备驱动代码的分布 • ~/block • ~/char • ~/cdrom • ~/pci • ~/scsi • ~/net • ~/sound 注:IDE接口的CD驱动位于drivers/block/ide-cd.c中,而SCSI CD驱动位于drivers/scsi/scsi.c中

  8. 1.5 Linux设备驱动程序的特点 • 设备驱动是内核的一部分,影响内核稳定 • 为内核或其从属子系统提供一个标准接口 • 使用标准的内核服务如内存分配、中断和等待队列等 • 大多数Linux设备驱动可以动态可加载 • Linux设备驱动程序可配置 • 驱动程序维护其控制的设备,该设备即使不存在也不影响系统的运行,此时设备驱动只是占用少量系统内存,不会对系统造成什么危害

  9. 2、设备驱动程序结构 • Linux的设备驱动程序与外界的接口可以分成三部分: • 与操作系统内核的接口 • 与系统引导的接口 • 与设备的接口 • Linux设备驱动程序的代码结构大致可以分为如下几个部分: • 驱动程序的注册与注销、设备的打开与释放、设备的读写操作、设备的控制操作、设备的中断和轮询处理。

  10. 2.1驱动程序的注册与注销 • 注册 • register_chrdev( );//在~fs/devices.c • register_blkdev( );//在~fs/block_dev.c • 注销 • unregister_chrdev( ) • unregister_blkdev( )

  11. 2.2 打开、释放、读、写、控制等

  12. Linux内核将通过file_operations结构访问驱动程序提供的函数 • 字符设备的读写直接使用函数read( )和write( ) • 块设备需要调用函数block_read( )和block_write( ) • ioctl( )的用法与具体设备密切关联,因此需要根据设备的实际情况进行具体分析

  13. 2.3 设备的轮询和中断处理 • 轮询 • 内核定期对设备的状态进行查询 • 消耗不少的内核资源 • 如果设备驱动被连接进入内核,这时使用轮询方式将会带来灾难性的后果 • 中断 • 设备驱动向内核注册其使用的中断 • 内核负责把硬件产生的中断传递给相应的设备驱动 • 设备驱动在其中断处理过程中做得越少越好

  14. 问题: • 如何查看设备驱动所对应的中断号及类型 ?

  15. 3、设备驱动试验 • 实验一:编写一个简单的驱动程序 • 实验二:设计和实现一个KED&LED实验 • 实验三:动态加载和静态编译驱动到内核 • 实验四:使用中断方式的驱动程序设计

  16. 实验一:编写简单的驱动程序(1) • 1) 任务: 在XSBase开发板上编写一个简单的字符设备驱动程序。该字符设备具备4个基本操作:xsbase_open()、xsbase_write()、 xsbase_read() 、xsbase_release(),实现向这个新建的字符设备先写入一些数据,然后再从这个设备中读取这些数据。

  17. 实验一:编写简单的驱动程序(2) • 2)主要数据结构和全局变量 • 系统~fs/devices.c的struc device_struct结构 • 创建一个xsbase.c文件,其中包含一些必要的头文件、宏和全局变量

  18. 实验一:编写简单的驱动程序(3) • 主要接口函数 • file_operations{ }结构的实例 注:这种结构的声明方法是一种标记化格式声明,便于移植。

  19. 实验一:编写简单的驱动程序(4) • xsbase_open()和xsbase_release()

  20. 实验一:编写简单的驱动程序(5) • xsbase_read()

  21. 实验一:编写简单的驱动程序(6) • xsbase_write()

  22. 实验一:编写简单的驱动程序(7) • 3)模块加载:是两种将驱动加入内核的方式之一 • 编写init_module() …… res = register_chrdev(0, "xsbase", &chr_fops); …… if(xsbase_major == 0) xsbase_major = res; • 编写cleanup_module() …… unregister_chrdev(xsbase_major, "xsbase"); ……

  23. 实验一:编写简单的驱动程序(8) • 4)驱动安装过程 • 新建xsbase.c文件,实现主要数据结构和函数接口。 • 编译生成xsbase.o • 把目标文件加载到内核 • 在Minicom中使用ZMODEM协议发送文件 • 执行

  24. 实验一:编写简单的驱动程序(9) • 创建一个设备文件 • 测试 • OVER

  25. 实验二:编写KED&LED驱动(1) • 在这个实验中,通过设计和实现一个KED&LED驱动程序,来控制目标板上的一组LED灯,在安装完驱动后,运行测试程序,就能点亮LED灯。

  26. 实验二:编写KED&LED驱动(2)

  27. 实验三:静态编译驱动到内核(1) • 在确定自己代码位置的前提下,建立自己的源码目录、文件、Makefile、Config.in等。 • 修改上层的config.in文件,把自己的驱动加入到内核配置系统中。 • 修改上层Makefile,把自己的程序加入到内核编译系统中。 • 确保自己的初始化函数被调用。 • drivers/char/mem.c中的chr_dev_init() 或drivers/block/ll_rw_blk.c中的blk_dev_init() • 用宏module_init来申明你的初始化函数

  28. 实验三:静态编译驱动到内核(2) • 驱动位置和目录结构

  29. 实验三:静态编译驱动到内核(3) • 修改配置文件 • 1)drivers/xsbase/Config.in

  30. 实验三:静态编译驱动到内核(4) • 2) arch/arm/config.in • 编写Makefile • 1)drivers/xsbase/Makefile

  31. 实验三:静态编译驱动到内核(5) • 2)drivers/Makefile • 3)Makefile

  32. 实验四:中断方式的驱动程序(1) • 注册中断处理程序 • 什么叫中断信号线(IRQ号)? • 何时请求IRQ号更合适? • 初始化时 • 设备第一次打开时

  33. 实验四:中断方式的驱动程序(2) • 编写中断处理程序

  34. 实验四:中断方式的驱动程序(3) • 中断处理机制的实现

  35. 实验四:中断方式的驱动程序(4) • 中断控制 这些函数更新可编程中断控制器(PIC)中指定中断的掩码,因而,这样就可以在所有的处理器上禁止或者启动 IRQ。对这些函数的调用是可以嵌套的——如果 disable_irq() 被成功调用两次,在 IRQ 真正重新打开之前,需要执行两次 enable_irq() 调用。

  36. 驱动设计中涉及的一些具体问题 • 用户空间和内核空间 • /proc文件系统

More Related