《嵌入式应用程序设计设备驱动》由会员分享,可在线阅读,更多相关《嵌入式应用程序设计设备驱动(24页珍藏版)》请在金锄头文库上搜索。
1、嵌入式应用程序设计嵌入式应用程序设计第八章嵌入式Linux设备驱动编程知识点回顾TCP/IP模型套接字TCP套接字编程UDP套接字编程设备驱动的基本概念Linux内核与驱动的关系Linux内核模块结构内核模块命令本次课内容本次课内容31.设备驱动概念是处理和操作硬件控制器的软件。驱动程序是内核的一部分,是操作系统内核与硬件设备的直接接口,驱动程序屏蔽了硬件的细节,完成以下功能:对设备初始化和释放;对设备进行管理,包括实时参数设置,以及提供对设备的操作接口;读取应用程序传送给设备文件的数据或者回送应用程序请求的数据;检测和处理设备出现的错误。8.1设备驱动编程基础设备驱动42.Linux系统的设
2、备分类字符设备通常指以字节为单位顺序读写的设备,如并口设备、虚拟控制台等。块设备通常指以块为单位随机读写的设备,如IDE硬盘、SCSI硬盘、光驱等。网络设备通常是指通过网络能够与其他主机进行数据通信的设备,如网卡等。8.1设备驱动编程基础设备驱动5举例:linux设备识别在linux中任何设备都是文件。所有设备的设备文件节点都在/dev目录下。#:lsal/dev3.设备驱动程序的特点内核代码内核接口内核机制和服务可装载可设置动态性8.1设备驱动编程基础设备驱动74.设备驱动程序与整个软硬件系统的关系8.1设备驱动编程基础设备驱动81.Linux的内核模块Linux内核采用可加载内核模块化设计
3、(Loadable Kernel Module,LKM)内核模块:是一些可以让操作系统内核在需要时载入和执行的代码。是一种目标对象文件,通常由一组函数和数据结构组成。内核的一个模块可以以两种方式被编译和加载。直接编译进Linux内核,随同Linux启动时加载;编译成一个可加载和删除的模块。8.1设备驱动编程基础内核模块编程98.1设备驱动编程基础内核模块编程 C语言程序 Linux内核模块运行 用户空间 内核空间入口 main() module_init()指定;出口 main() module_exit()指定; 编译 gcc c Makefile连接 ld insmod运行 直接运行 in
4、smod调试 gdb kdbug, kdb, kgdb等 2.Linux内核模块与应用程序的区别8.1设备驱动编程基础内核模块编程3.内核模块相关命令insmod module.oLoad the module注意,只有超级用户才能使用这个命令rmmod module Unload the modulelsmodList all modules loaded into the kernel这个命令和cat/proc/modules等价modprobe -r Load the module specified and modules it depends举例:模块相关命令lsmodinsmod
5、hello.ormmod hellomodprobe /lib/modules/linux版本号/modules.dep/etc/modprobe.confmodeproble r hello最简单的内核模块例子#include#include#includeMODULE_LICENSE(GPL);staticint_inithello_init(void)printk(“Hellokernel.n);return0;staticvoid_exithello_exit(void)printk(“byebye.n);module_init(hello_init);module_exit(hell
6、o_exit);生成makefile文件Makefile文件obj-m := hello.oall: make -C /usr/src/linux-2.4.20/ M=$(shell pwd) modulesclean:make -C /usr/src/linux-2.4.20/ M=$(shell pwd) modules clean编译装载过程$lshello.cMakefile$makemake-C/usr/src/linux-2.4.20/ M=/wu/char_8modules$lshello.chello.mod.chello.mode.ohello.omake.logMakefi
7、lemodules.order$sudoinsmodhello.o$dmesg|tail-1Hellokernel$lsmod|grephellohello12160$sudormmodhello$dmesg|tail-1byebye.不需要编写Makefile的方法gcc编译后加上-DMODULE-DLINUX参数例如:gcc-DMODULE-DLINUX-I/usr/src/linux-2.4.20/include-c-ohello.ohello.c注意:-I选项跟着Linux内核源代码中Include目录的路径。4.内核模块的程序结构一个Linux内核模块主要由以下几个部分组成。模块加载
8、函数(必须)模块卸载函数(必须)模块许可证声明(必须)模块参数(可选)模块导出符号(可选)模块作者等信息声明(可选)8.1设备驱动编程基础内核模块编程17staticint_initinitialization_function(void)/*初始化代码*/module_init(initialization_function);模块加载函数18staticvoid_exitcleanup_function(void)/*释放代码*/module_exit(cleanup_function);模块卸载函数19module_param(参数名,参数类型,参数读/写权限访问许可掩码)宏为模块声明一
9、个参数支持的参数类型byte,short,ushort,int,uint,long,ulong,bool,charp,invboolarray(module_param_array(name,type,nump,perm)例如:staticchar*str_param=LinuxModuleProgram;staticintnum_param=4000;module_param(num_param,int,S_IRUGO);module_param(str_param,charp,S_IRUGO);参数在模块加载时传递#insmodhello.otest=2模块参数20导出符号EXPORT_S
10、YMBOL(符号名);EXPORT_SYMBOL_GPL(符号名);模块声明与描述模块声明与描述MODULE_AUTHOR(author);MODULE_DESCRIPTION(description);MODULE_VERSION(version_string);MODULE_DEVICE_TABLE(table_info);MODULE_ALIAS(alternate_name);导出符号与模块声明与描述21#include#include#includestaticchar*whom=world;staticinthowmany=1;module_param(howmany,int,04
11、44);module_param(whom,charp,S_IRUGO);staticint_inithello_init(void)inti;for(i=0;ihowmany;i+)printk(“(%d)Hello,%sn”,i,whom);return0;staticvoid_exithello_exit(void)printk(Goodbyeworldn);MODULE_LICENSE(GPL);MODULE_DESCRIPTION(“Asimplemoduleprogram”);MODULE_VERSION(“V1.0”);MODULE_AUTHOR(“wdh);module_init(hello_init);module_exit(hello_exit);举例:带参数的内核模块sudoinsmodhello.ohowmany=10whom=Tom小结设备驱动概念Linux中设备驱动的分类内核模块的两种编译加载方式内核模块编程思考:改进前面程序