没有合适的资源?快使用搜索试试~ 我知道了~
ioctl() 函数输入输出应用实例.doc
5星 · 超过95%的资源 需积分: 9 21 下载量 183 浏览量
2010-06-09
08:35:05
上传
评论
收藏 127KB DOC 举报
温馨提示
试读
16页
不多说了,这个资料绝对是网上介绍ioctl函数最好的,通过实例分析,跟让学习者从实践中学到知识
资源推荐
资源详情
资源评论
ioctl() 函数输入输出应用实例
实验内容:
分别在 PC 并口的 13 脚和 25 脚引出两条引线,LED 灯长脚(+) 接 PC 并口第 2 脚,短脚(-) 接 PC 并口 18 脚 。当加载驱动
程序后,启动测试应用程序,一开始会启动开启 LED 然后弹出等待输入信息并等待输入。这时接触两根金属引脚,1s 后
LED 关闭,然后再弹出第二次等待输入信息。再一次接触金属引脚,LED 灯以 0.5s 为周期开关 5 次。接着,弹出第三次
等待输入信息,在金属引脚接触后,LED 以 0.2s 为间隔开关。此时,如果再次接触金属引线,那么程序终止。
并口引脚定义说明:
1 选通 (STROBE 低电平) 10 确认 (ACKNLG 低电平)
2 数据位 0 (DATAO) 11 忙 (BUSY)
3 数据位 1 (DATA1) 12 却纸 (PE)
4 数据位 2 (DATA2) 13 选择 (SLCT)
5 数据位 3 (DATA3) 14 自动换行 (AUTOFEED 低电平)
6 数据位 4 (DATA4) 15 错误观点(ERROR 低电平)
7 数据位 5 (DATA5) 16 初始化成(INIT 低电平)
8 数据位 6 (DATA6) 17 选择输入 (SLCTIN 低电平)
9 数据位 7 (DATA7) 18-25 地线路(GND)
并口引脚定义图:
实验目的主要是熟悉 ioctl() 函数的使
用方法以及相关宏的使用。代码由 3 部分组成,一个公用头文件,一个设备驱程序,一个应用测试程序。
头文件 ioctl_test.h 内容:
引用
#ifndef _IOCTLTEST_H_
#define _IOCTLTEST_H_
#define IOCTLTEST_MAGIC 't'
typedefstruct{
unsigned long size;
unsigned char buff [128];
}__attribute__((packed)) ioctl_test_info;
#define IOCTLTEST_LEDOFF _IO (IOCTLTEST_MAGIC, 0)
#define IOCTLTEST_LEDON _IO (IOCTLTEST_MAGIC, 1)
#define IOCTLTEST_GETSTATE _IO (IOCTLTEST_MAGIC, 2)
#define IOCTLTEST_READ _IOR (IOCTLTEST_MAGIC, 3, ioctl_test_info)
#define IOCTLTEST_WRITE _IOW (IOCTLTEST_MAGIC, 4, ioctl_test_info)
#define IOCTLTEST_WRITE_READ _IOWR (IOCTLTEST_MAGIC, 5, ioctl_test_info)
#define IOCTLTEST_MAXNR 6
#endif
1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按
照实际占用字节数进行对齐,是 GCC 特有的语法。这个功能是跟操作系统没关系,跟
编译器有关,gcc 编译器不是紧凑模式的,我在 windows 下,用 vc 的编译器也不是紧凑
的,用 tc 的编译器就是紧凑的。例如:
在 TC 下:struct my{ char ch; int a;} sizeof(int)=2;sizeof(my)=3;(紧凑模式)
在 GCC 下:struct my{ char ch; int a;} sizeof(int)=4;sizeof(my)=8;(非紧凑模式)
在 GCC 下:struct my{ char ch; int a;}__attrubte__ ((packed)) sizeof(int)=4;sizeof(my)=5
2. __attribute__关键字主要是用来在函数或数据声明中设置其属性。给函数赋给属性的
主要目的在于让编译器进行优化。函数声明中的__attribute__((noreturn)),就是告诉编
译器这个函数不会返回给调用者,以便编译器在优化时去掉不必要的函数返回代码。
GNU C 的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Function
Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
__attribute__书写特征是:__attribute__前后都有两个下划线,并且后面会紧跟一对括
弧,括弧里面是相应的__attribute__参数。
__attribute__语法格式为:
__attribute__ ((attribute-list))
“ ”其位置约束:放于声明的尾部 ; 之前。
函数属性(Function Attribute):函数属性可以帮助开发者把一些特性添加到函数声明
中,从而可以使编译器在错误检查方面的功能更强大。__attribute__机制也很容易同非
GNU 应用程序做到兼容之功效。
GNU CC –需要使用 Wall 编译器来击活该功能,这是控制警告信息的一个很好的方式。
packed 属性:使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变
量是一字节对齐,对域(field)是位对齐。
如果你看过 GPSR 协议在 TinyOS 中的实现,你一定会注意到下面的语句:
typedef struct {
double x;
double y;
} __attribute__((packed)) position_t;
开始我们还可以理解,不久是定义一个结构体嘛!不过看到后面的语句,你可能就会一
’ 头雾水了, __attribute__((packed))’是什么东西?有什么作用?一连串的疑问马上就会
从你脑袋里冒出来。虽然这个对理解整个程序没有什么影响,但我不想让这些疑问一直
呆在我的脑子里,负担太重。省得以后念念不忘,而且也许有一天可以用的上呢。搞清
楚这个问题吧!
GNU C 的一大特色(却不被初学者所知)就是__attribute__机制。__attribute__可以设置
函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type
Attribute)。
__attribute__语法格式为:
__attribute__ ((attribute-list))
“ ”其位置约束为:放于声明的尾部 ; 之前。
packed 是类型属性(Type Attribute)的一个参数,使用 packed 可以减小对象占用的空
间。需要注意的是,attribute 属性的效力与你的连接器也有关,如果你的连接器最大只
支持 16 字节对齐,那么你此时定义 32 字节对齐也是无济于事的。
使用该属性对 struct 或者 union 类型进行定义,设定其类型的每一个变量的内存约束。
当用在 enum 类型定义时,暗示了应该使用最小完整的类型(it indicates that the smallest
integral type should be used)。
下面的例子中,my-packed-struct 类型的变量数组中的值会紧凑在一起,但内部的成员
变量 s “不会被 pack”,如果希望内部的成员变量也被 packed 的话,my-unpacked-struct 也
需要使用 packed 进行相应的约束。
struct my_unpacked_struct
{
char c;
int i;
};
struct my_packed_struct
{
char c;
int i;
struct my_unpacked_struct s;
}__attribute__ ((__packed__));
__attribute__机制的详细介绍请参考:
http://www.unixwiz.net/techtips/gnu-c-attributes.html
上面所用到的宏 _IO, _IOR, _IOW, IOWR 的详解如下:
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理
内容的值。cmd 除了可区别数字外,还包含有助于处理的几种相应信息。 cmd 的大小为 32
位,共分 4 个域:
bit31~bit30 2 “ ” 位为 区别读写 区,作用是区分是读取命令还是写入命令。
bit29~bit16 14 位为 "数据大小" 区,表示 ioctl() 中的 arg 变量传送的内存大小。
Bit15~bit08 8 “位为 魔数"(也称为"幻数") 区,这个值用以与其它设备驱动程序的 ioctl 命令
进行区别。
bit07~bit00 8 位为 "区别序号" 区,是区分命令的命令顺序序号。
“ ” 像命令码中的 区分读写区 里的值可能是 _IOC_NONE (0 值)表示无数据传输,
_IOC_READ (读) , _IOC_WRITE (写) , _IOC_READ|_IOC_WRITE (双向)。
内核定义了 _IO() , _IOR() , IOW() 和 _IOWR() 这 4 个宏来辅助生成上面的 cmd 。下面分析
_IO() 的实现,其它的类似。
在 asm-generic/ioctl.h 里可以看到 _IO() 的定义:
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
再看 _IOC() 的定义:
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
可见,_IO() 的最后结果由 _IOC() 中的 4 个参数移位组合而成。
再看 _IOC_DIRSHIT 的定义:
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
_IOC_SIZESHIFT 的定义:
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
_IOC_TYPESHIF 的定义:
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
_IOC_NRSHIFT 的定义:
剩余15页未读,继续阅读
资源评论
- lishi_19912012-12-27文章是挺不错 就是有点贵
shentuhongfeng
- 粉丝: 5
- 资源: 23
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功