- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第6章 ARM LINUX驱动程序开发
第6章 LINUX驱动程序开发 嵌入式LINUX驱动程序介绍 最简单的内核模块举例 Linux驱动程序开发要点 字符设备驱动介绍 字符设备驱动开发实例 1 驱动程序的概念 驱动程序:是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,从应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。 1.1 驱动程序的组成及加载 驱动程序的组成: 驱动程序分三个主要部分 自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和能否正常工作等,此部分程序仅在初始化的时候被调用一次 服务于I/O请求的子程序,又称为驱动程序的上半部分,主要指作为系统调用执行的函数。 中断服务子程序,又称为驱动程序的下半部分。主要指负责处理中断请求的函数。 驱动程序加载的两种方式 作为内核一部分:把驱动程序作为linux内核一部分。需要修改linux的源码,重新编译linux内核。 作为可加载模块:独立编译驱动程序,然后利用相关命令动态加载驱动程序到linux内核。 1.2 驱动程序的作用 从嵌入式驱动开发人员角度看,它是直接操控硬件的软件,直接读写硬件寄存器来控制硬件 读写存储设备,如Flash,硬盘等 操作设备缓冲区设备 操作输入/输出设备,如键盘、打印机等 从嵌入式应用程序开发人员角度看,它为应用程序提供了访问硬件设备的应用编程接口API: 应用程序通过驱动程序安全有效地访问硬件设备 驱动程序隐藏了底层的细节,从而提高了软件的可移植性和可复用性 驱动程序文件节点可以方便的提供访问权限控制 1.3 驱动程序分类 Linux系统将设备驱动程序一般分为三类 字符设备:是能够象字节流(文件)一样被访问的设备,通过文件系统节点可以访问字符设备,例如/dev/tty1和/dev/lp1。字符设备驱动程序通常会实现open,close,read和write等系统调用函数。大多数字符设备仅仅是数据通道,只能顺序读写。而且数据不需要缓冲而且不以固定大小进行操作。 块设备:是指对其信息的存取以“块”为单位,如常见的光盘、硬磁盘等。块设备和字符设备一样可以通过文件系统节点来访问。不同之处是块设备通常以固定大小进行随机访问,且有数据缓冲。 网络设备:在Linux系统中是比较特殊的,通常是通过套接字Socket接口来实现。任何网络事务处理都是通过网络接口实现的。网络接口不象字符和块设备那样简单地映射到文件系统的节点上。Linux调用这些接口的方式是给它们分配一个独立的名字(如eth0),这样的名字在文件系统中并没有对应项。 2. 最简单的内核模块举例 一个最简单的“Hello World”模块程序:保存为hello.c #include linux/init.h #include linux/module.h #include linux/moduleparam.h MODULE_LICENSE(Dual BSD/GPL); static char *who = world; static int times = 1; module_param(times, int, S_IRUGO); module_param(who, charp, S_IRUGO); static int hello_init(void) { int i; for (i = 0; i times; i++) printk(KERN_ALERT (%d) Hello, %s!\n, i, who); return 0; } static void hello_exit(void) { printk(KERN_ALERT Goodbye, %s!\n,who); } module_init(hello_init); module_exit(hello_exit); 2. 最简单的内核模块举例 程序说明: 这个模块定义了两个函数 hello_init函数:初始化函数,在模块加载时被调用, 由moudle_init宏指定。 hello_exit:初始化函数,在模块卸载时调用,由module_exit宏指定。 MODULE_LICENSE宏:用来告知内核, 该模块带有一个自由的许可证。 module_param宏:用于定义模块的启动参数名称、类型以及权限。此例中定义了who和times两个参数。 printk函数:在 Linux 内核中定义,对模块可用 与 C 库函数 printf 的行为相似。 KERN_ALERT宏:是标记printk打印字符串优先等级。 KERN_ALERT表示需要立即执行的情况。共有8种消息等级,定义在include/linux/kernel.h文件中 2. 最
文档评论(0)