Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux内核读取函数_C_Linux_Linux Kernel_Kernel - Fatal编程技术网

C Linux内核读取函数

C Linux内核读取函数,c,linux,linux-kernel,kernel,C,Linux,Linux Kernel,Kernel,我正在尝试为我的内核程序创建一个读取函数。首先,用户必须输入一些数字(输入数字0停止输入)。数字输入已经为我完成了我的工作是使读取功能。读取功能必须跟踪输入的数字量,并且由于模块处于活动状态,因此具有输入数字的缓冲区。 我一直在从summer.c中读取缓冲区和字符数,以测试summer.c并打印它们 Summer.c代码: /* example of a character device using ioctl */ #include <linux/kernel.

我正在尝试为我的内核程序创建一个读取函数。首先,用户必须输入一些数字(输入数字0停止输入)。数字输入已经为我完成了我的工作是使读取功能。读取功能必须跟踪输入的数字量,并且由于模块处于活动状态,因此具有输入数字的缓冲区。 我一直在从summer.c中读取缓冲区和字符数,以测试summer.c并打印它们

Summer.c代码:

   /* example of a character device using ioctl 
    */

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/errno.h>
    #include <linux/fs.h>
    #include <asm/uaccess.h>
    #include "summer.h"

    #define BUF_LEN 80            /* Max length of the message from the device */

    /* the memory of the device*/
    int total;

    /* Global variables declared as staic, so are global within the file.*/
   static char *msg_Ptr;
   static char msg[BUF_LEN];

    /* called after the device is opened*/
    int device_open(struct inode *inode, struct file *file)
    {
    printk("\nsummer device is open\n");
    total = 0;

    // sprintf(msg);
    printk(msg);
    msg_Ptr = msg;

    return 0;
    }

    /* called after the device is closed
    */
    int device_close(struct inode *inode, struct file *file)
    {
    printk("\nsummer device is closed\n");
  return 0;
}

/* handling of ioctl events
*/
long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
  int number;
  switch(ioctl_num)
  {
    case SUMMER_SET:
      __get_user(number, (int*)ioctl_param);
      total += number;
      break;
    case SUMMER_GET:
      __put_user(total, (int*)ioctl_param);
      break;
  }
  return 0;
}

/* Read function */
static ssize_t device_read(struct file *filep, char *buffer, size_t length, loff_t *offset){

/* Number of bytes actually written to the buffer */
int bytes_read = 0;

/* If we're at the end of the message, return 0 signifying end of file */
if (*msg_Ptr == 0) return 0;

/* Actually put the data into the buffer */
while (length && *msg_Ptr) {

    /* The buffer is in the user data segment, not the kernel segment;
        *  assignment won't work. We have to use put_use which copies data from 
        *  the kernel data segment to the user data segment. */
    put_user(*(msg_Ptr++), buffer++);

    length--;
    bytes_read++;
}
/* Most read functions return the number of bytes put into the buffer */
return bytes_read;
}


/* table of event handlers of the device
*/
struct file_operations fops =
{
  read: device_read,
 // write: device_write, 
  open: device_open,
  release: device_close,
  unlocked_ioctl:  device_ioctl,
  compat_ioctl: device_ioctl
};

/* called after the kernelmodule is opened
*/
int init_module(void)
{
/* register the device
  ** after registration the device is known to linux by its major number
  ** example: mknod /dev/summer0 c 240 0
  ** this creates the device /dev/summer0
  ** which is a character device (c) with major number 240 and minor number 0
  */
  int retval = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
  if(retval < 0)
  {
    printk("character device not registered\n");
    return retval;
  }
  printk("summer kernel module loaded\n");
  return 0;
}

/* called after the module is closed
*/
void cleanup_module(void)
{
/* unregister the device
  */
  unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
  printk("summer kernel module unloaded\n");
}
/*使用ioctl的字符设备示例
*/
#包括
#包括
#包括
#包括
#包括
#包括“summer.h”
#定义设备消息的最大长度为80/*BUF_LEN*/
/*设备的内存*/
整数合计;
/*声明为staic的全局变量在文件中是全局的*/
静态字符*msg_Ptr;
静态字符msg[BUF_LEN];
/*在设备打开后调用*/
int device_open(结构索引节点*索引节点,结构文件*文件)
{
printk(“\n发送器设备已打开\n”);
总数=0;
//sprintf(msg);
printk(msg);
msg_Ptr=msg;
返回0;
}
/*在设备关闭后调用
*/
int device_close(结构索引节点*索引节点,结构文件*文件)
{
printk(“\n发送器设备已关闭\n”);
返回0;
}
/*ioctl事件的处理
*/
长设备ioctl(结构文件*文件,未签名的int ioctl_num,未签名的长ioctl_参数)
{
整数;
开关(ioctl_num)
{
案例集:
__获取用户(编号,(int*)ioctl\u参数);
总数+=数量;
打破
情况如下:
__put_user(总计,(int*)ioctl_参数);
打破
}
返回0;
}
/*读取函数*/
静态ssize\u t设备读取(结构文件*filep,字符*buffer,大小\u t长度,loff\u t*偏移量){
/*实际写入缓冲区的字节数*/
int bytes_read=0;
/*如果我们在消息末尾,则返回0表示文件结束*/
如果(*msg_Ptr==0),则返回0;
/*实际将数据放入缓冲区*/
while(长度和*msg_Ptr){
/*缓冲区位于用户数据段,而不是内核段;
*作业无效。我们必须使用put_use从中复制数据
*将内核数据段转换为用户数据段*/
put_user(*(msg_Ptr++),buffer++);
长度--;
字节读取++;
}
/*大多数读取函数返回放入缓冲区的字节数*/
返回读取的字节数;
}
/*设备的事件处理程序表
*/
结构文件\u操作fops=
{
读取:设备读取,
//写入:设备写入,
打开:设备\u打开,
释放:设备关闭,
解锁的ioctl:设备ioctl,
兼容ioctl:设备ioctl
};
/*在内核模块打开后调用
*/
int init_模块(void)
{
/*注册设备
**注册后,linux通过其主要编号知道该设备
**示例:mknod/dev/summer0 c 240 0
**这将创建设备/dev/summer0
**这是一个字符设备(c),主数字为240,次数字为0
*/
int retval=寄存器chrdev(主设备编号、设备名称和fops);
如果(返回值<0)
{
printk(“字符设备未注册\n”);
返回返回;
}
printk(“加载的夏季内核模块”);
返回0;
}
/*在模块关闭后调用
*/
空洞清理_模块(空洞)
{
/*注销设备
*/
取消注册chrdev(主要数量、设备名称);
printk(“夏季内核模块卸载\n”);
}
测试summer.c代码

/* example of use of a character device through ioctl
*/

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "../summer.h"

int main(void)
{
  int sum; 
  char* buffer;
  /* open character device   */
  int fd = open("/dev/summer0", O_RDWR);  // open device
  if(fd < 0)
  {
    printf("no device found\n");
    return;
  }
  /* read from device */
  int nc = read(fd,buffer,4,0);

  for(;;)
  {
    int num;
    printf("Number (exit with 0) = ");
    while(scanf("%d", &num) != 1)
      ;
    printf("-- %d --\n", num);
    if(num <= 0) break;

    /* use ioctl to pass a value to the character device     */
    ioctl(fd, SUMMER_SET, &num);
  }

  /* use ioctl to get a value from the character device   */
  ioctl(fd, SUMMER_GET, &sum);
  printf("Result = %d\n", sum);

  /* print num of chars + the buffer as a string with the amount of numbers read since the kernel is active. */
  printf("#char = %d\n", nc);
  printf("Buffer: %s\n" , buffer);

  close(fd);                         // close device
  return 0;
}
/*通过ioctl使用字符设备的示例
*/
#包括
#包括
#包括
#包括“./summer.h”
内部主(空)
{
整数和;
字符*缓冲区;
/*开放字符设备*/
int fd=open(“/dev/summer0”,O_RDWR);//打开设备
如果(fd<0)
{
printf(“未找到设备”);
返回;
}
/*从设备读取*/
int nc=读取(fd,缓冲器,4,0);
对于(;;)
{
int-num;
printf(“数字(以0退出)=”);
while(scanf(“%d”,&num)!=1)
;
printf(“--%d--\n”,num);

if(num这是一个老问题,但不想让它没有答案


在test summers.c文件中,您没有为缓冲区分配内存并将其传递给read函数。这可能是您没有正确获取返回值以及缓冲区没有填充所需数据的原因。

是否有不使用simple_read()的原因?我使用此阅读的原因是我在internet上找到了一个具有此功能的示例