因此,驱动程序的设计,要求开发人员熟悉Linux的内核机制、驱动程序和用户级应用程序的接口关系、系统中对设备的并发操作,同时要求开发人员非常熟悉所开发硬件的工作原理。嵌入式Linux中的设备驱动程序有以下三个方面的特点。......
2023-11-19
用户应用程序调用设备的功能都是在设备驱动程序中定义的,也就是设备驱动程序中所定义的功能入口点函数(或称为功能接口函数)。这些设备的功能接口函数都被定义在<include/linux/fs.h>中的数据结构体里面。
struct file_operations{};
struct inode{};
struct file{};
编写设备驱动程序,很大一部分工作就是“填写”结构体中定义的函数。这是内核结构,不会出现在用户级的程序中。
1.file_operations{}结构体
在内核的内部,通过file_operations{}结构体提供文件系统的入口点函数,也就是访问设备驱动的功能接口函数。
在include//linux/fs.h>中所定义的file_operations{}结构体的结构如下:
在结构体file operations{}里,每一个成员的名字都对应着一个系统调用,对应着设备驱动程序所提供的入口点位置。在用户进程利用系统调用对设备文件进行操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个结构体相应的函数指针,接着把控制权交给该函数,这就是设备驱动程序的工作原理。
设备驱动程序所提供的入口点位置分别有以下几个:
(1)lseek。移动文件指针的位置,显然只能用于可以随机存取的设备。
(2)read进行读操作,参数buf为存放读取结果的缓冲区,count为所要读取的数据长度。返回值为负表示读取操作发生错误,否则返回实际读取的字节数。对于字符型,要求取的字节和返回实际读取字节数都必须是inode_>i_blksize的倍数。
(3)write。进行写操作,与read类似。
(4)readdir。取得目录入口点,只用于与文件系统相关的设备驱动程序。(www.chuimin.cn)
(5)select。进行选择操作,如果驱动程序没有提供select人口,select操作将会认为设备已经准备好进行任何的1/O操作。
(6)ioctl。进行读、写以外的其他操作,前面已有详细介绍。
(7)mmap。用于把设备的内容映射到地址空间,一般只有块设备驱动程序使用。
(8)open。打开设备准备进行I/O操作,返回O表示打开成功,返回负数表示失败。如果驱动程序没有提供open入,则只要/dev/driver文件存在就认为打开成功。
(9)release。关闭设备并释放资源。
一般编写设备驱动程序时并不一定要全部定义以上函数,只需定义对设备有意义的接口函数。例如,一个仅有输出功能的设备只要定义一个write()函数,一个仅有输入功能的设备只要定义一个read()函数。在大多数的嵌入式系统的开发中,一般仅仅实现其中几个关键的接口函数,如open、read、write、ioctl、release等。
在编写用gcc编译的设备驱动程序时,经常使用一种更为方便的结构体形式:
当用gcc命令编译上述结构体时,对于没有显式声明的结构体成员都被gcc初始化为NULL。
2.inode{}和file{}结构体
文件系统处理文件所需要的信息在inode(索引节点)数据结构体中。inode中保存了“页”结构,用于进行设备缓冲,当进行读、写操作时,系统首先检查是否有inode存在,然后检查是否已经获得其缓冲内容。若没有则请求,若已经存在,则把被写的“页”作上标记。
inode数据结构体提供了关于特别设备文件/dev/driver(这里假设设备名为driver)的信息。
fie结构主要是与文件系统对应的设备驱动程序使用。当然,其他设备驱动程序也可以使用。
有关ARM嵌入式系统原理与应用的文章
因此,驱动程序的设计,要求开发人员熟悉Linux的内核机制、驱动程序和用户级应用程序的接口关系、系统中对设备的并发操作,同时要求开发人员非常熟悉所开发硬件的工作原理。嵌入式Linux中的设备驱动程序有以下三个方面的特点。......
2023-11-19
上面介绍了字符设备驱动程序的重要的数据结构,那么如何设计一个字符设备驱动程序的数据结构?字符设备驱动程序的初始化流程一般可以用如下的过程来表示:定义相关的设备文件结构体[如file_operation()中的相关成员函数的定义]。向内核申请主设备号。内核提供了三个函数来注册一组字符设备编号,这三个函数分别是:alloc_chrdev_region()、register_chrdev_region()和register_chrdev()。所以在一般的字符设备驱动程序中,不会看到对cdev的操作。这里举出字符设备驱动程序的常见的两种编程架构。......
2023-11-19
对一个打开的文件而言,最常用到的就是对文件的读写操作,在Linux系统中,提供了系统调用函数实现文件的读写操作。读取文件数据时,文件的当前读写位置会向后移。以下几种读取文件数据情况下,返回的字节数会小于count值。......
2023-11-19
GPIO是一组可编程控制的引脚,由多个寄存器同时控制。应用程序都能够通过相应的接口使用GPIO。GPIO驱动主要作用就是读取GPIO口的内容,或者设置GPIO口的状态。GPIO与硬件体系密切相关,在Linux内核目录下的相关文件中我们可以发现针对不同硬件芯片的GPIO定义和使用方法,如本书涉及的S5PV210芯片Linux内核中也有相应的驱动程序支持。本章主要讲的就是如何使用Linux内核封装好的GPIO接口函数在驱动开发中需要操作GPIO时候的使用。......
2023-11-19
2.开发模式嵌入式系统本身不具备自举开发能力,即使设计完成以后用户通常也是不能对其中的程序功能进行修改的,必须有一套开发工具和环境才能进行开发,这些工具和环境一般是基于通用计算机上的软硬件设备以及各种逻辑分析仪、混合信号示波器等。表1.2常用嵌入式开发工具......
2023-11-19
Linux软件开发一直在Internet环境下讲行。Linux开发工作经常是在Linux用户决定共同完成一个项目时开始的。由于这个活跃的开发环境,新的以Linux为基础的软件功能日益强大,而且呈现爆炸式的增长态势。许多流行的Linux实用程序如C编译器、shell和编辑器都是GNU软件应用程序。Linux程序需要首先转化为低级机器语言即所谓的二进制代码以后,才能被操作系统执行。......
2023-11-19
GPIO属于字符设备,其驱动可以归类为Linux设备驱动的字符设备驱动。编写一个程序gpio_led.c,实现对实验箱CVT_A8上连接在GPIO端口的LED驱动程序,使得实验箱上的发光二极管轮流点亮,既常见的流水灯。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。函数分别为device ioctl并在模块初始化函数dev init中调用misc register函数进行注册ioctl操作函数实现。模块退出操作模块退出,必须删除设备驱动程序并释放占用的资源,使用unregister_chrdev删除设备驱动程序。......
2023-11-19
具体来说,嵌入式系统是以应用为中心、计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。可以这样认为,嵌入式系统是一种专用的计算机系统,作为装置或设备的一部分。通常,嵌入式系统是一个控制程序存储在ROM中的嵌入式处理器控制板。表1.1对比了通用计算机系统与嵌入式系统。......
2023-11-19
相关推荐