Linuxドライバでprocノードを作成する方法(例)
linuxカーネルでスイッチング変数を作る3つの方法の1つ:procファイルシステム(その他参照[https://blog.csdn.net/peterbig/article/details/18273665]).
コードの例
test_proc.c
Makefile
インストール方法のコンパイル
test_proc.cとMakefileを統一フォルダに入れる $ make $ sudo insmod test_proc.ko $ echo “test” >/proc/ethercat/gfar_log $dmesg(コマンドを実行するとカーネル印刷情報が表示されます) 関数の説明作成関数 フォルダ関数の作成 削除関数(ノードまたはディレクトリを削除)
適用方法
Procノードの使用には、主にノードの作成と削除が含まれます.
1.ノードの作成
ノードを作成するための基本手順:
ノードを作成する一般的な3つの方法デフォルトでは/procパスで作成するにはproc_のみが必要ですcreateはノードを作成することができて、パラメータparentはNULLを伝えて、proc_を必要としませんmkdirはパスを作成します.例:proc_create(“myProc”, 0777, NULL, &igh_gen_proc_fops); /procの既存ディレクトリの下でパラメータnameパス名にノード名を付ける組合せ例を作成する:proc_create(“myDir/myProc”, 0777, NULL, &igh_gen_proc_fops); /procでディレクトリを作成してノードを作成するにはproc_を先に使用mkdirはノードディレクトリを作成し、proc_を使用します.create作成ノード上記のサンプルコード表示、proc_createのparentパラメータをprocにインポートするにはmkdirが返すインスタンス;
2.ノードの削除
ノードを作成する3つの方法に対応してノードを削除削除/procパス下のノードexitで関数remove_proc_entryはノードを削除します.procパスの下にあるので、親ディレクトリを削除する必要はありません.パラメータparentはNULLを送信します. myDir/myノードを削除する例:remove_proc_entry(“myDir/my”, IGH_EC_PROC_DIR"/"IGH_GEN_PROC_NAME, NULL); myDirは/procパスの下で、パラメータparentがNULLを送信します. 作成したフォルダとノードを削除するには、作成したノードを先に削除する必要があります.parentは親パスに転送され、フォルダremove_を削除します.proc_entry(IGH_GFAR_PROC_NAME, igh_gfar_proc_dir); remove_proc_entry(IGH_EC_PROC_DIR, NULL); 同様に、フォルダは/procの下にあるので、parentはNULLを伝えます.
注意:
コードの例
test_proc.c
#include
#include
#include
#include
#include
#include
#include
#define IGH_EC_PROC_DIR "ethercat"
#define IGH_GFAR_PROC_NAME "gfar_log"
static int igh_gfar_proc_show(struct seq_file *m, void *v);
static int igh_gfar_proc_open(struct inode *inode, struct file *file);
static ssize_t igh_gfar_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *f_pos);
static int igh_gfar_proc_init(void);
static void igh_gfar_proc_exit(void);
static int igh_gfar_proc_show(struct seq_file *m, void *v)
{
return 0;
}
static int igh_gfar_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, igh_gfar_proc_show, NULL);
}
static ssize_t igh_gfar_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *f_pos)
{
char *tmp = kzalloc((count+1), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
if (copy_from_user(tmp,buffer,count)) {
kfree(tmp);
return -EFAULT;
}
printk("%s Get user str :%s
", __func__, tmp);
kfree(tmp);
return count;
}
ssize_t igh_ec_proc_read(struct file *file, char __user *buf, size_t len, loff_t *off)
{
int len_copy, ret;
char data[32] = "1234566789";
// fl->f_pos , len
if ((file->f_pos + len) > strlen(data)) // len,
len_copy = strlen(data) - file->f_pos;
else
len_copy = len; // len, len
ret = copy_to_user(buf, data+file->f_pos, len_copy);
// ,
*off += len_copy - ret; // read/write off
return len_copy - ret;
}
static struct file_operations igh_gfar_proc_fops = {
.owner = THIS_MODULE,
.open = igh_gfar_proc_open,
.release = single_release,
.read = igh_ec_proc_read,
.llseek = seq_lseek,
.write = igh_gfar_proc_write,
};
struct proc_dir_entry *igh_gfar_proc_dir = NULL;
static int igh_ec_proc_init(void)
{
struct proc_dir_entry* file;
igh_gfar_proc_dir = proc_mkdir(IGH_EC_PROC_DIR, NULL);
if (igh_gfar_proc_dir == NULL) {
printk("%s proc create %s failed
", __func__, IGH_EC_PROC_DIR);
return -EINVAL;
}
file = proc_create(IGH_GFAR_PROC_NAME, 0777, igh_gfar_proc_dir, &igh_gfar_proc_fops);
if (!file) {
printk("%s proc_create failed!
", __func__);
return -ENOMEM;
}
return 0;
}
static void igh_gfar_proc_exit(void)
{
remove_proc_entry(IGH_GFAR_PROC_NAME, igh_gfar_proc_dir);
remove_proc_entry(IGH_EC_PROC_DIR, NULL);
}
static int __init my_init(void)
{
igh_ec_proc_init();
return 0;
}
static void __exit my_exit(void)
{
igh_gfar_proc_exit();
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("WXY");
MODULE_LICENSE("GPL");
Makefile
obj-m := test_proc.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
インストール方法のコンパイル
test_proc.cとMakefileを統一フォルダに入れる
struct proc_dir_entry *proc_create(
const char *name, umode_t mode, struct proc_dir_entry *parent,
const struct file_operations *proc_fops);
:
name:/proc/ 。 :"gfar_log", /proc/ demo
mode: 。 :0666 ,0444 ,0222
parent: , NULL( /proc )
proc_fops: file_operations
: proc
struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent);
:
name:
parent: , , proc , NULL
:
void remove_proc_entry(const char *name,
struct proc_dir_entry *parent);
:
name: proc 。
parent: 。 struct proc_dir_entry
適用方法
Procノードの使用には、主にノードの作成と削除が含まれます.
1.ノードの作成
ノードを作成するための基本手順:
ノードを作成する一般的な3つの方法
2.ノードの削除
ノードを作成する3つの方法に対応してノードを削除
注意:
read proc , cat read ,
0 loff_t*ppo ,
0 read 。