在proc下可以创建节点,driver可以echo或cat设备节点里的数据,和某些Module交互。
下面是实现的一个proc demo,代码如下:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
int age = 16;
char* name="jacky";
#define MAX_PROC_SIZE 20
static char proc_data[MAX_PROC_SIZE];
static struct proc_dir_entry *proc_write_entry;
static unsigned int proc_demo_value = 0;
static int read_proc_demo(char *buf,char **start,off_t offset,int count,int *eof,void *data)
{
printk(KERN_ALERT "read_proc_demo proc_demo_value=%d\n",proc_demo_value);
// 返回值表示是否一致读proc值
return 0;
}
static int write_proc_demo(struct file *file,const char *buf,int count,void *data)
{
printk(KERN_ALERT "write_proc_demo.... \n");
memset(proc_data, 0, MAX_PROC_SIZE);
if(count > MAX_PROC_SIZE)
count = MAX_PROC_SIZE;
if(copy_from_user(proc_data, buf, count)) //读取输入的参数
return -EFAULT;
char* threshold = NULL;
char* cur = proc_data;
unsigned int threshold_val;
//printk("proc_data = %s\n", proc_data);
threshold = strsep(&cur, ",");
//printk("cur = %s\n", cur);
printk("threshold = %s \n",threshold);
if(threshold == NULL){
printk("threshold == NULL\n");
return count;
}
if(threshold[0] == '\0'){
printk("threshold == empty value\n");
return count;
}
kstrtouint(threshold, 10, &threshold_val);
proc_demo_value = threshold_val;
// count表示写入的长度
return count;
}
static int proc_demo_open(struct inode *inode,struct file *filp)
{
printk(KERN_ALERT "proc_demo_open.... \n");
return 0;
}
static int proc_demo_close(struct inode *inode,struct file *filp)
{
printk(KERN_ALERT "proc_demo_close.... \n");
return 0;
}
//定义相关的操作函数
static const struct file_operations proc_demo_ops = {
.owner = THIS_MODULE,
.read = read_proc_demo,
.write = write_proc_demo,
.open = proc_demo_open,
.release= proc_demo_close,
};
//创建proc_demo节点
static int create_proc_demo_entry(void)
{
proc_write_entry = proc_create("proc_demo", 0666, NULL, &proc_demo_ops);
if(!proc_write_entry)
{
printk(KERN_INFO "Error creating proc entry: proc_demo");
return -ENOMEM;
}
printk(KERN_INFO "proc_demo proc initialized");
return 0;
}
static int __init hello_init(void)
{
printk(KERN_ALERT "hello driver insmod sucess age=%d, name=%s\n",age,name);
create_proc_demo_entry();
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "hello driver rmmod sucess \n");
//在rmmod的时候,拿掉proc entry
proc_remove(proc_write_entry);
}
//注册初始化linux驱动的函数
module_init(hello_init);
//注册退出linux驱动的函数
module_exit(hello_exit);
module_param(age,int,0644);
module_param(name,charp,0644);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mstar jacky.zhu<jacky.zhu@mstarsemi.com>");
加载驱动:
1|root@mangosteen:/data/local # insmod hello.ko
[ 249.692000] hello driver insmod sucess age=16, name=jacky
[ 249.692000] hello driver insmod sucess age=16, name=jacky
读取proc值:
root@mangosteen:/data/local # cat /proc/proc_demo
[ 282.868000] proc_demo_open....
[ 282.868000] read_proc_demo proc_demo_value=0
[ 282.872000] proc_demo_close....
[ 282.868000] proc_demo_open....
[ 282.868000] read_proc_demo proc_demo_value=0
[ 282.872000] proc_demo_close....
卸载驱动:
root@mangosteen:/data/local # rmmod hello.ko
[ 314.308000] hello driver rmmod sucess
[ 314.308000] hello driver rmmod sucess
再次读取proc值:
root@mangosteen:/data/local # cat /proc/proc_demo
/system/bin/sh: cat: /proc/proc_demo: No such file or directory
/system/bin/sh: cat: /proc/proc_demo: No such file or directory