我有一个内核模块,我想将一些值传递给用户空间。有人建议我使用struct type来传递更多的值。 在内核空间中我有:
typedef struct data {
int val_delta;
int val_btn_status;
}data_t;
static ssize_t sample_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
{
int ret = 1;
int delta = 10;
data_t val;
val.val_btn_status = gpio_get_value( BTN );
val.val_delta = delta;
copy_to_user( buffer, &val, sizeof(data_t));
return( ret );
}
在用户空间中,如何将这两个值放入data_t结构中? 我还想在User Space中将data_t类型声明为:
typedef struct data {
int val_delta;
int val_btn_status;
}data_t;
int main(int argc, char **argv)
{
data_t str;
char *app_name = argv[0];
char *dev_name = "/dev/sample";
int fd = -1;
if ((fd = open(dev_name, O_RDWR)) < 0)
{
fprintf(stderr, "%s: unable to open %s: %s\n", app_name, dev_name, strerror(errno));
return( 1 );
}
x = read(fd, &str, 1);
return 0;
}
但我不喜欢这个,因为我不想在User Space和Kernel Space上重写相同的typedef,也许这个不起作用。还有其他解决方案吗?
答案 0 :(得分:1)
您可以将common struct
和dev_name
添加到标题中,并包含在驱动程序和用户空间程序中。
赞: data.h
#ifndef DATA_H
#define DATA_H
typedef struct data {
int val_delta;
int val_btn_status;
}data_t;
#define dev_name "/dev/sample"
#endif
同时更改
read(fd, &str, 1);
到
read(fd, &str, sizeof(data_t));
答案 1 :(得分:1)
首先,您需要了解copy_to_user()
def。
unsigned long copy_to_user ( void __user * to,
const void * from,
unsigned long n);
在您的示例中,sample_read()
函数应使用char __user *buffer
而不是char *buffer
。
将您的typedef struct data
定义放入头文件中,该文件可以包含在内核模块和用户程序中,而不是重新定义两次。
答案 2 :(得分:0)
您是否尝试过其他选项,例如将来自传感器的ECHO中断标记(我假设它将是一个中断)作为快速中断,因此它不会被同级别的其他人抢占。 或者为什么不将它放在处理器上最高的可用中断级别(在硬编码的中断级别之下)。 正如桑托什所说,必须有一个不同的原因来冻结。也许你看过你给定结构的对齐方式了吗?根据你的底层处理器的字长??