linux驱动中ioctl()的实现问题
linux驱动中ioctl()的实现问题ram_ioctl.h文件
#define __RAM_IOCTL_H
#define RAM_IOCOMMAND_CLEAR 0x1a
#define RAM_IOCOMMAND_SET 0x1b
#define RAM_IOCOMMAND_MOVE 0x1c
#define RAM_IOCTL_MAGIC 'k'
#define RAM_IOCTL_NR_MIN RAM_IOCOMMAND_CLEAR
#define RAM_IOCTL_NR_MAX RAM_IOCOMMAND_MOVE
#define RAM_IOCTL_CLEAR _IO( RAM_IOCTL_MAGIC, RAM_IOCOMMAND_CLEAR )
#define RAM_IOCTL_SET _IO( RAM_IOCTL_MAGIC, RAM_IOCOMMAND_SET )
#define RAM_IOCTL_MOVE _IO( RAM_IOCTL_MAGIC, RAM_IOCOMMAND_MOVE)
#endif
ram.c文件中的ioctl()
static int ram_ioctl(struct block_device *bdev,fmode_t mode, unsigned int cmd, unsigned long arg)
{
int ret = 0;
if ( RAM_IOCTL_MAGIC != _IOC_TYPE( cmd ))
{
printk(KERN_ALERT "RamDeviceDriver: ioctype mismatch !\n");
return ret;
}
if ( ( RAM_IOCTL_NR_MIN > _IOC_NR( cmd ) ) || ( RAM_IOCTL_NR_MAX < _IOC_NR( cmd ) ) )
{
printk(KERN_ALERT "RamDeviceDriver: iocnr mismatch !\n");
return ret;
}
switch (cmd)
{
case RAM_IOCTL_CLEAR:
memset(ram_data_addr, 0, RAM_DATA_SIZE);
printk(KERN_ALERT "RamDeviceDriver:Success to clear memory !\n");
break;
case RAM_IOCTL_SET:
memset(ram_data_addr, arg, RAM_DATA_SIZE);
printk(KERN_ALERT "RamDeviceDriver:Success to set memory !arg = %ld\n",arg);
break;
case RAM_IOCTL_MOVE:
memcpy(ram_data_addr, ram_data_addr + MY_DATA_SIZE, MY_DATA_SIZE );
printk(KERN_ALERT "RamDeviceDriver:Success to move data !\n");
break;
default:
printk(KERN_ALERT "RamDeviceDriver:Unknown ioctl commd !\n");
return -EINVAL;
}
}
test.c文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ram_ioctl.h"
int main ( void )
{
int fd;
int ret;
char buf;
fd = open( "/dev/myram", O_RDWR );
if ( fd < 0 )
{
perror( " open" );
return -1;
}
ret = write( fd, "wensheng",10 );
if ( ret < 0 )
perror( "write" );
printf( "write %d byte\n", ret );
ioctl( fd, RAM_IOCTL_CLEAR );
close(fd);
fd = open( "/dev/myram", O_RDWR );
ret = read( fd, buf, 10 );
if ( ret < 0 )
perror( "read" );
printf ( "buf is :%s\n",buf );
close(fd);
return 0;
}
问题如下:
运行测试程序时,输出,write 10 byte
buf is :wensheng
查看dmesg信息 :RamDeviceDriver:Success to clear memory !
可以看出,程序已经成功写入了“wensheng”字符串,并通过ioctl( fd, RAM_IOCTL_CLEAR );调用驱动中的ioctl() 执行 memset(ram_data_addr, 0, RAM_DATA_SIZE);(其中ram_data_addr是申请得到的内核虚拟内存的起始地址,RAM_DATA_SIZE内存大小)输出:RamDeviceDriver:Success to clear memory !信息。那么我块设备应该已经全部置0,为什么之后却又可以成功读出“wensheng”,其中求大神指点,那里出问题了,谢谢!!! 嗯,你试着把
close(fd);
ioctl( fd, RAM_IOCTL_CLEAR );
这两句调换过来。 先谢谢您能回贴,问题我刚刚已解,原因:write(),read()为I/O操作,写入文件时,系统会先将要写入的数据写入缓冲区(这是为以提高读写速度),只有遇到close()时才将缓冲区数据写入实际文件(没查到很准确的资料,但大概是这个意思)。将程序中的ioctl操作单独执行,如下代码:#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ram_ioctl.h"
int main ( void )
{
int fd;
int ret;
char buf = { 0 };
unsigned long int arg = 0xFF;
fd = open( "/dev/myram", O_RDWR );
if ( fd < 0 )
{
perror( " open" );
return -1;
}
ret = write( fd, "wensheng123 \n",);
if ( ret < 0 )
perror( "write" );
printf( "write %d byte\n", ret );
/*if ( ioctl( fd, RAM_IOCTL_CLEAR ) < 0 )
{
perror( "ioctl error\n " );
return -1;
}
if ( ioctl( fd, RAM_IOCTL_SET , arg ) < 0 )
{
perror( "ioctl error123 \n" );
return -1;
}
*/
close( fd );
fd = open( "/dev/myram", O_RDWR );
ioctl( fd, RAM_IOCTL_SET, arg );
close( fd );
fd = open( "/dev/myram", O_RDWR );
ret = read( fd, buf, 20 );
if ( ret < 0 )
perror( "read" );
printf ( "buf is :%s\n", buf );
close( fd );
return 0;
}
这样我ioctl操作就能按我想的那样工作,
呵呵-- 谢谢您和大家观注,在此结贴
页:
[1]