Linux 内核模块:kernel_write 函数有问题
Linux Kernel Module : Problem with kernel_write function
我在为 Linux 4.14.73 版本开发 LKM 时使用 kernel_write
函数时遇到问题。
这是我遇到问题的模块部分:
void change_led_state(char *led_path, int led_value)
{
printk("we are in change_led_state\n");
size_t len = sizeof(led_value);
char lpath[64];
ssize_t rk=0;
strncpy(lpath, led_path, sizeof(lpath) - 1);
lpath[sizeof(lpath) - 1] = '[=12=]';
f_led = filp_open(lpath, O_WRONLY , 0);
if (f_led == NULL) {
printk("Unable to access led\n");
return;
}
rk = kernel_write(f_led, led_value, len, &f_led->f_pos);
printk("rk = %d\n", rk);
filp_close(f_led, NULL);
}
rk 通常得到一个负值。我想应该是积极的。请问这个功能有什么问题吗?我该如何更正它?
有关更多信息,我有相同的代码,但在 user-space 程序中,它工作正常,我只是想将其替换为内核 space。这是用户 space 程序:
void change_led_state(char *led_path, int led_value)
{
char lpath[64];
FILE *led_fd;
strncpy(lpath, led_path, sizeof(lpath) - 1);
lpath[sizeof(lpath) - 1] = '[=13=]';
led_fd = fopen(lpath, "w");
if (led_fd == NULL) {
fprintf(stderr, "simplekey: unable to access led\n");
return;
}
fprintf(led_fd, "%d\n", led_value);
fclose(led_fd);
}
void reset_leds(void)
{
change_led_state(LED_PATH "/" green "/brightness", 0);
}
void eval_keycode(int code)
{
static int green_state = 0;
switch (code) {
case 260:
printf("BTN pressed\n");
// figure out red state
green_state = green_state ? 0 : 1;
change_led_state(LED_PATH "/" green "/brightness", green_state);
break;
default :
printf("Wrong Button was pressed\n");
break;
}
}
在主函数中,我只调用了 eval_keycode 函数,它就可以工作了。我犯了什么错误?
在你的通话中:
rk = kernel_write(f_led, led_value, len, &f_led->f_pos);
第二个参数应该是 char *
,但你传递的是 int
。
此外,当写入“/sys/class/leds/[device]/brightness”文件时,处理这个的代码需要一个指向十进制数字字符串的指针,以一些非数字字符结尾(例如换行符)或空终止符。
你需要"print"你的led_value
到一个char
数组作为十进制数,并将数组内容写入文件:
char led_valstr[20]; /* should be large enough */
len = scnprintf(led_valstr, sizeof(led_valstr), "%d\n", led_value);
rk = kernel_write(f_led, led_valstr, len, &f_led->f_pos);
(编辑:更正了对 scnprintf
的调用。)
我在为 Linux 4.14.73 版本开发 LKM 时使用 kernel_write
函数时遇到问题。
这是我遇到问题的模块部分:
void change_led_state(char *led_path, int led_value)
{
printk("we are in change_led_state\n");
size_t len = sizeof(led_value);
char lpath[64];
ssize_t rk=0;
strncpy(lpath, led_path, sizeof(lpath) - 1);
lpath[sizeof(lpath) - 1] = '[=12=]';
f_led = filp_open(lpath, O_WRONLY , 0);
if (f_led == NULL) {
printk("Unable to access led\n");
return;
}
rk = kernel_write(f_led, led_value, len, &f_led->f_pos);
printk("rk = %d\n", rk);
filp_close(f_led, NULL);
}
rk 通常得到一个负值。我想应该是积极的。请问这个功能有什么问题吗?我该如何更正它?
有关更多信息,我有相同的代码,但在 user-space 程序中,它工作正常,我只是想将其替换为内核 space。这是用户 space 程序:
void change_led_state(char *led_path, int led_value)
{
char lpath[64];
FILE *led_fd;
strncpy(lpath, led_path, sizeof(lpath) - 1);
lpath[sizeof(lpath) - 1] = '[=13=]';
led_fd = fopen(lpath, "w");
if (led_fd == NULL) {
fprintf(stderr, "simplekey: unable to access led\n");
return;
}
fprintf(led_fd, "%d\n", led_value);
fclose(led_fd);
}
void reset_leds(void)
{
change_led_state(LED_PATH "/" green "/brightness", 0);
}
void eval_keycode(int code)
{
static int green_state = 0;
switch (code) {
case 260:
printf("BTN pressed\n");
// figure out red state
green_state = green_state ? 0 : 1;
change_led_state(LED_PATH "/" green "/brightness", green_state);
break;
default :
printf("Wrong Button was pressed\n");
break;
}
}
在主函数中,我只调用了 eval_keycode 函数,它就可以工作了。我犯了什么错误?
在你的通话中:
rk = kernel_write(f_led, led_value, len, &f_led->f_pos);
第二个参数应该是 char *
,但你传递的是 int
。
此外,当写入“/sys/class/leds/[device]/brightness”文件时,处理这个的代码需要一个指向十进制数字字符串的指针,以一些非数字字符结尾(例如换行符)或空终止符。
你需要"print"你的led_value
到一个char
数组作为十进制数,并将数组内容写入文件:
char led_valstr[20]; /* should be large enough */
len = scnprintf(led_valstr, sizeof(led_valstr), "%d\n", led_value);
rk = kernel_write(f_led, led_valstr, len, &f_led->f_pos);
(编辑:更正了对 scnprintf
的调用。)