嵌入式 globalmem设备驱动ioctl()函数的实现

原创 2013年12月02日 14:56:17
 一、ioctl的简介

在文件操作结构体file_operations中有很多的对应的设备操作函数,这些函数是通用的设备操作函数,但有些设备的操作是特有的,文件操作结构体不会有对应的函数定义。这样ioctl函数就将这些没办法归类的函数放在ioctl函数中,通过指定的命令来实现对应的操作。所以,ioctl函数里面都实现了多个的对硬件的操作,通过应用层传入的命令来调用相应的操作。下图是应用层与驱动函数的ioctl之间的联系

二、ioctl的cmd分析。

1.函数参数分析int (*ioctl)(struct inode * node, struct file *filp, unsigned int cmd, unsignedlong arg);

1)inode和file:ioctl的操作有可能要修改文件的属性,或者访问硬件。要修改文件属性就要用到这两个结构体了,所以这里传来了它们的指针。

2)cmd我们自己定义的命令,下面我将用实现三个命令。

3)arg:用户程序传来的参数,可以是数值参数也可以是指针参数,下面的测试将都会出现。

2.cmd构成部分,cmd由幻数、序数、数据传输方向、数据大小四部分组成,和ioctl-number.txt这两个文档有对其说明。

1)幻数,是个0~0xff的数,占8bit(_IOC_TYPEBITS)。这个数是用来区分不同的驱动的,内核有一个文档给出一些推荐的或者已经被使用的幻数。

2)序数用这个数来给自己的命令编号,占8bit(_IOC_NRBITS),下面的测试程序从1开始排序。

3)数据传输方向占2bit(_IOC_DIRBITS)。涉及到要传参,需要向内核描述一下传输的方向,传输的方向是以应用层的角度来描述的。

3.返回值

1)如果传入的非法命令,ioctl返回错误号-EINVAL。

2)内核中的驱动函数返回值都有一个默认的方法,只要是正数,内核就会默认为确的返回,并把它传给应用层,如果是负值,内核就会认为它是错误返回值ioctl里面多个不同的命令返回值有可能是不同的,因此需要根据该函数的功能来决定返回值类型。

三、ioctl实现的驱动代码

1.定义头文件test_cmd.h,在头文件中定义了三个用于ioctl函数指令。定义如下:

#ifndef_TEST_CMD_H

#define_TEST_CMD_H

#define TEST_MAGIC'x'

#define TEST_MAX_NR3

#define TEST_CLEAR_IO(TEST_MAGIC,1)//自定义的清除命令

#define TEST_OFFSET_IO(TEST_MAGIC,2)//自定义的修改文件指针位置的命令

#defineTEST_KBUF_IO(TEST_MAGIC,3)//自定义的修改内核内存数据命令

#endif

structioctl_data{//用于测试的数据结构体

unsigned int size;

char buf[100];

};

2.ioctl函数修改的部分

static intglobalmem_ioctl(struct inode *inodep,struct file *filp,unsigned intcmd,unsigned long arg)

{

int ret;

struct globalmem_dev*dev=filp->private_data;

struct ioctl_data val;

 

if(_IOC_TYPE(cmd)!=TEST_MAGIC)return-EINVAL;

if(_IOC_NR(cmd)>TEST_MAX_NR)return-EINVAL;

switch(cmd){

case TEST_CLEAR://清零内存

memset(dev->mem,0,GLOBALMEM_SIZE);

filp->f_pos= 0;

printk(KERN_INFO"globalmem id set tozero\n");

break;

case TEST_OFFSET://修改文件指针位置

filp->f_pos+= (int)arg;

break;

case TEST_KBUF://修改kbuf

if(copy_from_user(&val, (structioctl_data *)arg, sizeof(struct ioctl_data)))

{

return - EFAULT;

}

memset(dev->mem,0,GLOBALMEM_SIZE);//初始化全局内存

memcpy(dev->mem,val.buf,val.size);//将内核数据结构体数据拷到全局内存中

filp->f_pos =0;

break;

default:

return -EINVAL;

}

return 0;

}

3.测试应用程序test.c

#include

#include

#include

#include

#include

#include

#include"test_cmd.h"

#include

int main()

{

int fd;

char buf[20]="Welcome toChina",receve[20]={'\0'};

struct ioctl_data test_data={

.size=10,

.buf="123456789"

};

fd = open("/dev/Mac",O_WRONLY);

if(fd < 0)

{

printf("open /dev/Mac error\n");

return 0;

}

write(fd,buf,20);

close(fd);

fd =open("/dev/Mac",O_RDONLY);

if(fd < 0)

{

printf("open /dev/Mac error\n");

return 0;

}

read(fd,receve,20);

printf("buf:%s\n",receve);

//ioctl(fd,TEST_CLEAR);

//ioctl(fd,TEST_OFFSET,-20);

ioctl(fd,TEST_KBUF,&test_data);

read(fd,receve,20);

printf("buf:%s\n",receve);

close(fd);

return 0;

}

4.Makefile文件

ifneq($(KERNELRELEASE),)

obj-m :=globalmem.o

else

KDIR:=/lib/modules/2.6.28/build

all:

make -C $(KDIR) M=`pwd` modules

clean:

-rm -f *.ko *.o *.mod.o *.mod.c *.symversModule.markers modules.order pt_test

endif

到此工作完成,运行测试即可。

linux 驱动-----字符设备globalmem驱动实现

一、开发环境     内核版本:linux-3.0     开发板:FL2440(nandflash:K9F1G08 128M)     编译器:arm-linux-gcc 4.3.2 ...
  • u011196227
  • u011196227
  • 2014年08月28日 16:57
  • 570

linux设备驱动之ioctl控制

大部分驱动除了具有读写的能力之外,还需要具有对硬件控制的能力。一。用户空间:ioctl 用户程序使用ioctl系统调用来控制设备。用户程序只是通过命令码告诉驱动程序想做什么,至于怎么解释这些命令和怎...
  • lincuiting06
  • lincuiting06
  • 2015年12月11日 16:43
  • 593

linux驱动程序ioctl函数用法

一、 什么是ioctl     ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数...
  • a1232345
  • a1232345
  • 2015年04月14日 17:58
  • 2000

嵌入式Linux设备驱动开发(二)

上一篇中介绍到设备驱动如何匹配设备以及绑定设备的,在Linux系统下进行注册,这里将继续介绍probe函数的功能。 5、probe函数 Probe()函数必须验证指定设备的硬件是否真的存在,pro...
  • chuhang_zhqr
  • chuhang_zhqr
  • 2016年03月10日 13:51
  • 1185

嵌入式Linux设备驱动开发之:按键驱动程序实例

11.6  按键驱动程序实例 11.6.1  按键工作原理 LED和蜂鸣器是最简单的GPIO的应用,都不需要任何外部输入或控制。按键同样使用GPIO接口,但按键本身需要外部的输入,即在驱动程序中要...
  • azhangyi188
  • azhangyi188
  • 2014年01月02日 13:14
  • 1440

应用调用驱动的ioctl函数

使用一套源码讲解如果在应用层去调用底层的函数,承接了前一篇的在底层建立可调用的ioctl的博客讲解。可以按照自己的想法随意改动代码添加进自己的工程,也可以按照步骤建立自己的一套ioctl应用。...
  • xuweiwei1860
  • xuweiwei1860
  • 2014年10月27日 19:40
  • 946

Linux驱动学习6(ioctl的实现)

一、ioctl功能简介 open、write函数的功能无非就是为了进行用户空间和内核空间的数据交换,而ioctl呢? 大部分驱动除了需要具备读写设备的能力之外,还需要对设备具有控制能力,比如要求设备报...
  • King_BingGe
  • King_BingGe
  • 2013年11月28日 14:33
  • 2344

ioctl---字符设备的控制技术

字符设备的控制 1. 字符设备控制理论     1.1 作用           大部分驱动程序除了需要提供读写设备的能力外,还需要具备控制设备的能力。比如:改变波特率     1.2 应用程...
  • coding__madman
  • coding__madman
  • 2016年05月09日 22:59
  • 1640

嵌入式设备驱动程序设计

设计一个程序,在用户空间的用户应用程序中产生20个随机数,通过内核空间的设备驱动程序按五行四列的排列输出,并显示能被5整除的数。 分析:要实现这个功能需要做以下工作: 1.编写嵌入式设备驱动程序:...
  • sanganqi_wusuierzi
  • sanganqi_wusuierzi
  • 2017年02月02日 00:04
  • 667

设备驱动的ioctl函数

驱动程序中除了需要具备读写的能力外,还需具备对硬件的控制能力。 在用户空间使用ioctl来控制设备,其原型如下 int ioctl(int fd,usnigned long cmd...) io...
  • z1179675084
  • z1179675084
  • 2013年04月26日 15:38
  • 849
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:嵌入式 globalmem设备驱动ioctl()函数的实现
举报原因:
原因补充:

(最多只允许输入30个字)