ioctl、文件操作接口函数以及nand的升级模式的操作过程详解
概述
内核中驱动文件的操作通常是通过write和read函数进行的,但是很多时候再用户空间进行的操作或许不是内核中公共代码部分提供的功能,此时就需要使用一种个性化的方法进行操作--ioctl系统调用。
ioctl系统调用是一种用于设备控制的公共接口,主要分为两种,一种是用户空间使用的ioctl系统调用,函数原型为:
| int ioctl(int fd,unsigned long cmd,...); |
另一种是在内核空间使用的ioctl调用,函数原型为:
int (*ioctl)(struct inode *inode,struct file *filp,
unsigned int cmd,unsigned long arg);
本文中主要介绍在用户空间使用的ioctl。
知其然,知其所以然
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。
函数原型:
int ioctl(int fd, int cmd, ...);
其中fd就是用户程序打开设备时使用的open函数返回的文件标识符,cmd就是用户程序对设备的控制命令,至于后面的省略号,是可选参数,此参数的取值情况跟第二个参数有关。
函数的返回值,在传入非法命令式,Ioctl返回-EINVAL。
选择ioctl命令
为了防止对错误设备使用正确的命令,命令号应该在系统范围内唯一。从include/asm/ioctl.h头文件中,我们可以得出cmd为一个32位的无符号整数,被划分为4个段,具体表示如下:
| cmd |
direction
(bit31--bit30) |
size
(bit29--bit16)
|
type
(bit15--bit8)
|
number
(bit7--bit0)
|
| 所占位数 | 2 | 14 | 8 | 8 |
| 作用 | 命令:区别读/写 | 数据大小 | 幻数:表示设备类型 | 命令顺序序号 |
#define _IOC_NRBITS 8 //序数(number)字段的字位宽度,8bits
#define _IOC_TYPEBITS 8 //幻数(type)字段的字位宽度,8bits
#define _IOC_SIZEBITS 14 //大小(size)字段的字位宽度,14bits
#define _IOC_DIRBITS 2 //方向(direction)字段的字位宽度,2bits
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) //序数字段的掩码,0x000000FF
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) //幻数字段的掩码,0x000000FF
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) //大小字段的掩码,0x00003FFF
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) //方向字段的掩码,0x00000003
#define _IOC_NRSHIFT 0 //序数字段在整个字段中的位移,0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) //幻数字段的位移,8
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) //大小字段的位移,16
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) //方向字段的位移,30
/*
* Direction bits.
*/
#define _IOC_NONE 0U //没有数据传输
#define _IOC_WRITE 1U //向设备写入数据,驱动程序必须从用户空间读入数据
#define _IOC_READ 2U //从设备中读取数据,驱动程序必须向用户空间写入数据
/*
*_IOC 宏将dir,type,nr,size四个参数组合成一个cmd参数,如下图:
*
*/
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
/*
* used to create numbers
*/
//构造无参数的命令编号
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
//构造从驱动程序中读取数据的命令编号
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
//用于向驱动程序写入数据命令
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
//用于双向传输
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/*
*used to decode ioctl numbers..
*/
//从命令参数中解析出数据方向,即写进还是读出
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
//从命令参数中解析出幻数type
#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
//从命令参数中解析出序数number
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
//从命令参数中解析出用户数据大小
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
cmd参数在程序端由一些宏跟胡设备类型、序列号、传送方向、数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过switch{case A case B}结构进行相应的操作。
对于命名的规则可以参考Documentation/ioctl-number.txt.其中mtd设备的命名为:
'M' 01-16 mtd/mtd-abi.h conflict!
and drivers/mtd/mtdchar.c
通过上面的描述我们能够简单的了解到,ioctl命令能够为我们提供的便利。但是在实际应用中,ioctl会在某些情况下配合文件的相关操作命令完成想要的功能。
文件的操作中比较重要的一些操作主要包括open(),close(),lseek(),stat()等等的接口函数。
open函数用于打开文件,因为linux中一切皆文件的概念,所以我们可以将设备文件同普通文件一样使用正常的open函数进行打开。
close函数用于关闭之前打开的文件。
lseek函数用于确定文件的位置,包括三个参数SEEK_SET,SEEK_CUR,SEEK_END分别用于标识文件偏移值的起始位置分别在开始,当前位置或者文件末尾。
r\w函数用于文件的读写操作,
stat函数用于获取文件的相关信息,即结构体struct stat中的相关内容信息。
NAND Flash的相关知识
nand作为一种重要的存储设备被广泛的使用,作为基础知识的了解,可以通过访问URL:http://www.linux-mtd.infradead.org/
此处主要讲述使用yaffs2文件系统的情况下NAND Flash的一些特性。
YAFFS2文件系统
好马配好鞍,因此要更好的使用Nandflash这种存储介质,我们需要选择一种更加适合它物理特性的文件系统。
网上关于此方面的介绍很多,大家可以多进行翻阅集百家之言。此处只指出几点个人在实际的移植和开发过程中遇到的问题。
首先从实际的硬件结构上nand的存储分为两个部分,一个部分被称作data area;一个部分被称作spare area。这两个部分分别放置了不同的内容,一般在data area中存放实际的数据,而在spare area中存放了一些校验信息和FTL数据。在yaffs文件系统的挂载过程中会扫描这个spare area(oob)区,存放在这个区域的属于在yaffs2文件系统中称为FTL数据。这个通过读取此部分的数据和header page的数据确定数据的类型和文件的层次结构。如果这部分的数据是正确的,则系统能够正常的进行mount操作。
需要特别注意的是,要使用yaffs2文件系统,则需要将需要烧写的文件通过mkyaffs2imge工具进行操作,这个会在每一个page大小的数据之后产生FTL信息。因此,在实际数据的写入过程中需要特别注意将此两部分的数据进行区分处理。
ioctl、文件操作接口函数以及nand的升级模式的操作过程详解的更多相关文章
- 每天一个linux命令(文件操作):【转载】find 命令的参数详解
find一些常用参数的一些常用实例和一些具体用法及注意事项. 1.使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用.可以使用某种文件名模式来匹配文件 ...
- python 文件操作: 文件操作的函数, 模式及常用操作.
1.文件操作的函数: open("文件名(路径)", mode = '模式', encoding = "字符集") 2.模式: r , w , a , r+ , ...
- php中文件操作常用函数有哪些
php中文件操作常用函数有哪些 一.总结 一句话总结:读写文件函数 判断文件或者目录是否存在函数 创建目录函数 file_exists() mkdir() file_get_content() fil ...
- python 文件操作的函数
1. 文件操作的函数 open(文件名(路径), mode="?", encoding="字符集") 2. 模式: r, w, a, r+, w+, a+, r ...
- PHP文件操作功能函数大全
PHP文件操作功能函数大全 <?php /* 转换字节大小 */ function transByte($size){ $arr=array("B","KB&quo ...
- Linux 文件操作接口
目录 Linux 文件操作接口 C语言文件操作接口 C语言文件描述 fopen() r模式打开文件 w模式打开文件 a模式打开文件 其他模式类似 fclose() fwrite() fread() 系 ...
- C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解 ...
- (转)C# WebApi 接口返回值不困惑:返回值类型详解
原文地址:http://www.cnblogs.com/landeanfen/p/5501487.html 正文 前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi ...
- [转]C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
本文转自:http://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T c ...
随机推荐
- [K/3Cloud] 如何从被调用的动态表单界面返回数据
在需要返回数据的地方调用表单返回方法完成数据返回 this.View.ReturnToParentWindow(retData); 在调用界面的回调函数中取出返回结果的ReturnData即可使用. ...
- 编译kernel:内核makefile的作用
< 嵌入式linux应用完全开发手册 > 韦东山 内核Makefile的使命: 编译哪些内核文件? 读取各级子目录makefile, .config, auto.conf, Kbuild, ...
- 凡客副总裁崔晓琦离职 曾负责旗下V+商城项目_科技_腾讯网
凡客副总裁崔晓琦离职 曾负责旗下V+商城项目_科技_腾讯网 凡客副总裁崔晓琦离职 曾负责旗下V+商城项目 腾讯科技[微博]乐天2013年09月18日12:44 分享 微博 空间 微信 新浪微博 邮箱 ...
- HDU ACM 1066 Last non-zero Digit in N!
#include<iostream> using namespace std; int mod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2}; ...
- [LeetCode] Decode Ways [33]
题目 A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A ...
- BZOJ 1704: [Usaco2007 Mar]Face The Right Way 自动转身机( 贪心 )
贪心...先枚举k, 然后从左往右扫一遍, 发现位置p的牛的状态不符合就将 [p, p + k ) 的牛都转身, 假如p + k - 1 已经超过了最右边牛的位置那这个k就不符合要求. 符合要求的就可 ...
- 三种LVS负载均衡技术的优缺点----负载均衡调度算法
三种LVS负载均衡技术的优缺点归纳以下表: VS/NATVS/TUNVS/DR 服务器操作系统任意支持隧道多数(支持Non-arp) 服务器网络私有网络局域网/广域网局域网 服务器数目(100M网络) ...
- XP里面其实也讲究admin的执行权限
错误的方法:比如说,当前登录帐号cliff是管理员,此时直接运行cmd,输入: net user administrator 123 结果说这个用户找不到. --------------------- ...
- CVPapers论文整理工具-开源
一.工具介绍及运行实例 相信计算机视觉领域的同道中人都知道这个Computer Vision Resource网站, http://www.cvpapers.com/ 网页部分截图如下: 可以看到有 ...
- 开源OCR光学字符识别
纸张在 许多地方已日益失宠,无纸化办公谈论40多年,办公环境正限制纸山的生成.而过去几年,无纸化办公的概念发生了显着的转变.在计算机软件的帮助 下,包含大量重要管理数据和资讯的文档可以更方便的以电子形 ...