proc_create的一些疑问

qq347809617 2017-07-26 06:13:59
之前是使用create_proc_entry的,但是现在使用新的内核版本,只能使用proc_create了。在使用proc_create的时候,我发现在open的时候需要填充一个show函数,经过测试发现,在open之后,第一次调用read的时候,系统会自动调用这个show函数,然后之后继续read的时候,就不会调用这个show了。这个是什么原因?现在的问题是,我在内核中,大概需要传几K的数据到应用层,这个数据是一直在更新的,但是我在应用层只能在第一次读数据的时候读到内核的数据,之后就读不到了。这个如何解决?以下是部分内核代码

static int wifi_sniffer_read_func(char *seq)
{
int len = 0;
unsigned int idx = 0;
char page[256] = {0};

for(idx = 0;idx < wifi_info_current_cnt;idx++)
{
memset(page,0,sizeof(page));
len = 0;
len += sprintf(page + len,"%02x-%02x-%02x-%02x-%02x-%02x\t",
wifi_sniffer_infos[idx].src_mac[0],wifi_sniffer_infos[idx].src_mac[1],wifi_sniffer_infos[idx].src_mac[2],
wifi_sniffer_infos[idx].src_mac[3],wifi_sniffer_infos[idx].src_mac[4],wifi_sniffer_infos[idx].src_mac[5]);
len += sprintf(page + len,"%d\t",wifi_sniffer_infos[idx].rssi);
len += sprintf(page + len,"%d\t",wifi_sniffer_infos[idx].first_time);
len += sprintf(page + len,"%d\n",wifi_sniffer_infos[idx].last_time);
seq_printf(seq,"%s",page);
printk("len = %d,page = %s\n",len,page);

}
return len;
}
static int wifi_sniffer_show(struct seq_file *seq, void *v)
{
wifi_sniffer_read_func(seq);
return 0;
}
static int wifi_sniffer_open_func(struct inode *inode, struct file *file)
{
return(single_open(file, wifi_sniffer_show,NULL));
}
struct file_operations my_proc_fops = {
.open = wifi_sniffer_open_func,
//.read = wifi_sniffer_read,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
...全文
934 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq347809617 2017-07-28
  • 打赏
  • 举报
回复
非常感谢,目前已经解决了。
jklinux 2017-07-27
  • 打赏
  • 举报
回复
引用 2 楼 qq347809617 的回复:
已经带了这个file_operation了。
写了一个简单例子,供你参考:


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/fs.h>


ssize_t myread(struct file *fl, char __user *buf, size_t len, loff_t *off)
{
	static int n = 0;

	sprintf(buf, "n = %d\n", n++);

	return strlen(buf);
}

struct file_operations fops = {
	.read = myread,
};

struct proc_dir_entry *entry;

static int __init test_init(void)
{
	entry = proc_create("myproc", 0777, NULL, &fops);

	return 0;
}

static void __exit test_exit(void)
{
	remove_proc_entry("myproc", NULL);
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");


qq347809617 2017-07-27
  • 打赏
  • 举报
回复
已经带了这个file_operation了。
jklinux 2017-07-27
  • 打赏
  • 举报
回复
还是不行的话,看下http://m.blog.csdn.net/jklinux/article/details/72961626
jklinux 2017-07-27
  • 打赏
  • 举报
回复
肯定不能直接返回0,应是有个变量记录读出的数据长度,都读完了才返回0。 像写cdev一样的读函数。
qq347809617 2017-07-27
  • 打赏
  • 举报
回复
你指的是wifi_sniffer_read_func这个函数吗?如果这个函数直接return 0的话,那就什么也打印不出了啊?能说具体点吗?
jklinux 2017-07-27
  • 打赏
  • 举报
回复
read函数返回值为0就停了
qq347809617 2017-07-27
  • 打赏
  • 举报
回复
看log发现,在cat这个文件的时候,驱动这里一直在调用wifi_sniffer_read_func函数,导致一直打印停不下来。这个是哪里出问题了?
qq347809617 2017-07-27
  • 打赏
  • 举报
回复
已经按照你所说的方式改了,现在应用层可以读到数据,但是cat这个文件的时候,会一直循环打印内容,停不下了,这个怎么回事?

jklinux 2017-07-26
  • 打赏
  • 举报
回复
proc目录下的属性文件是这样的,打开一次就只能触发一次show函数的。你数据量大,需要多次读写的话应用带file_operations的函数创建属性文件了. struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops). 创建后,应就可以像cdev一样读写了

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧