简体   繁体   English

sysfs中的kstrtoint用于C内核模块

[英]kstrtoint in sysfs for c kernel module

Hi I am trying to use a kobject to write to a int array from sysfs. 嗨,我正在尝试使用kobject从sysfs写入int数组。 So the input is a char* and a size variable. 所以输入是一个char *和一个size变量。 I cant seem to get this to work however. 我似乎无法使它工作。 My expected input is "num1 num2 num3 " 我的预期输入是"num1 num2 num3 "

static ssize_t pids_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) {

int num_count = 0;
int i = 0;
int result = 0;
int cur_pid = 0;
char *dst;
char *ddst;

printk(KERN_INFO "GPIO_DEGUG: enter");

dst = buf;
ddst = buf;

printk(KERN_INFO "GPIO_DEGUG:  size of buffer %d ",count);


while(ddst < (buf + sizeof(size_t)*count)) {
ddst ++;
if (ddst[0] == ' ') {
   result = kstrtoint(dst,10,&cur_pid);
   dst=ddst+1;

   printk(KERN_INFO "GPIO_DEGUG: kstrtoint suceeded %d ",cur_pid);
   printk(KERN_INFO "GPIO_DEGUG: kstrtoint suceeded res: %d ",result);
   pids[num_count] = cur_pid;
   num_count += 1;
   }
}

for(i=0;i<num_count;i++) {
    printk(KERN_INFO "GPIO_TEST: pid: %d \n", pids[i]);
}
printk(KERN_INFO "GPIO_DEBUG: leaving\n");
return count;                                         
}

When I echo "100 " > /sys/vt/vt7/pids I get 当我echo "100 " > /sys/vt/vt7/pids我得到

[ 2765.712770] GPIO_DEGUG: enter 
[ 2765.724468] GPIO_DEGUG:  size of buffer 5 
[ 2765.735101] GPIO_DEGUG: kstrtoint suceeded 0 
[ 2765.746526] GPIO_DEGUG: kstrtoint suceeded res: -22 
[ 2765.757746] GPIO_DEBUG: leaving 

I suppose this is an argument error any help would be nice, thanks. 我想这是一个参数错误,任何帮助都很好,谢谢。

Function kstrtoint expects full string to contain single integer value . 函数kstrtoint期望完整的字符串包含单个整数值 The only exception is a newline character at the end of the string: 唯一的例外是字符串末尾的换行符:

The string must be null-terminated, and may also include a single newline before its terminating null. 该字符串必须以null结尾,并且在终止null之前还可以包含一个换行符。

As you can see, string "100 " doesn't fit for that requirement: it contains exceeded space. 如您所见,字符串“ 100”不符合该要求:它包含超出的空间。

For parse only part of the string as an integer, you may use simple_strtol : 要仅将字符串的一部分解析为整数,可以使用simple_strtol

long val = simple_strtol(dst, &ddst, 10);
if(ddst == ddst) {/* Parsing has been failed. */};

While this function is marked as an obsolete, there is still some code in the kernel which uses it. 虽然此功能被标记为已过时,但内核中仍有一些使用它的代码。

Another possibility is to use sscanf . 另一种可能性是使用sscanf It expects fixed number of integers in the string, but it is an usual situation with attributes: having complex representation of the attributes is not recommended : 它期望字符串中的整数个数固定,但这是带有属性的常见情况: 不建议使用复杂的属性表示形式

The conventions for sysfs state that each attribute should contain a single, human-readable value; sysfs的约定规定,每个属性应包含一个人类可读的值; if you have a lot of information to return, you may want to consider splitting it into multiple attributes. 如果您要返回的信息很多,则可能需要考虑将其拆分为多个属性。

( Linux Device Drivers 3, chapter 14 ). Linux设备驱动程序3,第14章 )。

The kstrtoint function is defined here: kstrtoint函数在此处定义:

http://lxr.free-electrons.com/source/lib/kstrtox.c#L245 http://lxr.free-electrons.com/source/lib/kstrtox.c#L245

If you notice the last value of *res defined in the function is the value you wish to use. 如果您注意到函数中定义的* res的最后一个值是您希望使用的值。 In your case cur_pid should be the value in which you want to print, the result should always be zero if it was successful. 在您的情况下, cur_pid应该是您要在其中打印的值,如果成功,结果应始终为零。 I would suggest checking result to make sure that the conversion has succeeded. 我建议检查结果以确保转换成功。

This should work: 这应该工作:

int cur_pid, result;
char *dst = NULL;

cur_pid = result = 0;
dst = buf;

result = kstrtoint(dst, 10, &cur_pid);
if (result)
     printk(KERN_INFO "GPIO_DEGUG: kstrtoint suceeded res: %d ", cur_pid);
else
     printk(KERN_INFO "ERROR");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM