打印

linux驱动中ioctl()的实现问题

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[20];

        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”,其中求大神指点,那里出问题了,谢谢!!!

TOP

嗯,你试着把
close(fd);
ioctl( fd, RAM_IOCTL_CLEAR );
这两句调换过来。

TOP

先谢谢您能回贴,问题我刚刚已解,原因: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[20] = { 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操作就能按我想的那样工作,


呵呵-- 谢谢您和大家观注,在此结贴

TOP