procfs创建交互文件
procfs介绍
procfs
文件系统是内核中的一个特殊文件系统。它是一个虚拟文件系统: 它不是实际的存储设备中的文件,而是存在于内存中。procfs
中的文件是用来允许用户空间的程序访问内核中的某些信息,例如查看内核中注册的中断信息:
cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 5 0 0 0 IO-APIC 2-edge timer
1: 0 0 0 13 IO-APIC 1-edge i8042
8: 0 0 0 0 IO-APIC 8-edge rtc0
9: 0 368804 0 0 IO-APIC 9-fasteoi acpi
12: 0 0 143 0 IO-APIC 12-edge i8042
14: 0 0 0 0 IO-APIC 14-edge ata_piix
15: 0 0 0 0 IO-APIC 15-edge ata_piix
18: 0 0 0 0 IO-APIC 18-fasteoi uhci_hcd:usb2
19: 0 0 33 0 IO-APIC 19-fasteoi ehci_hcd:usb1
22: 0 0 0 0 IO-APIC 22-fasteoi virtio2
24: 0 936221 0 0 PCI-MSI 512000-edge ahci[0000:00:1f.2]
25: 0 0 0 22 PCI-MSI 81920-edge virtio0-config
26: 327418 0 0 0 PCI-MSI 81921-edge virtio0-input.0
27: 0 241094 0 0 PCI-MSI 81922-edge virtio0-output.0
28: 0 0 32 0 PCI-MSI 98304-edge virtio1-config
29: 0 0 0 116038 PCI-MSI 98305-edge virtio1-input.0
30: 52544 0 0 0 PCI-MSI 98306-edge virtio1-output.0
31: 0 0 0 0 PCI-MSI 487424-edge xhci_hcd
32: 0 5 0 0 PCI-MSI 524288-edge virtio3-config
33: 0 0 628 0 PCI-MSI 524289-edge virtio3-virtqueues
34: 2095 0 0 0 PCI-MSI 49152-edge prl_tg
35: 0 1052 0 0 PCI-MSI 516096-edge snd_hda_intel:card0
NMI: 0 0 0 0 Non-maskable interrupts
LOC: 4873373 6149246 6152313 5156109 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 0 0 0 0 Performance monitoring interrupts
IWI: 0 0 0 0 IRQ work interrupts
RTR: 0 0 0 0 APIC ICR read retries
RES: 234988 236899 225375 230700 Rescheduling interrupts
CAL: 2632929 2570121 2843690 2792553 Function call interrupts
TLB: 1183090 1370524 1324835 1302239 TLB shootdowns
TRM: 0 0 0 0 Thermal event interrupts
THR: 0 0 0 0 Threshold APIC interrupts
DFR: 0 0 0 0 Deferred Error APIC interrupts
MCE: 0 0 0 0 Machine check exceptions
MCP: 580 580 580 580 Machine check polls
ERR: 0
MIS: 0
PIN: 0 0 0 0 Posted-interrupt notification event
NPI: 0 0 0 0 Nested posted-interrupt event
PIW: 0 0 0 0 Posted-interrupt wakeup event
procfs主要接口
接口 | 函数原型 |
创建目录 | struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) |
创建文件 | struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops) |
添加一个procfs 文件实现例程
procfs
用来进行相关驱动信息的读取,还是建议使用debugfs
来做调试功能。
要为
procfs
创建接口,只需要调用proc_create
接口。读/写处理函数依附在
struct file_operations
结构体。卸载操作使用
remove_proc_entry
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
/*** 驱动信息 ***/
MODULE_LICENSE("Dual BSD/GPL");
#define DRIVER_NAME "MyDevice"
#define PROC_NAME "MyDevice_test"
/* procfs 测试变量 */
static char proc_test_string[16];
static int flag_read = 0;
/* /proc/MyDevice_test访问时调用的函数 */
static int mydevice_proc_open(struct inode *inode, struct file *file)
{
printk("mydevice_proc_open\n");
flag_read = 0;
return 0;
}
/* /proc/MyDevice_test read */
static ssize_t mydevice_proc_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
printk("mydevice_proc_read\n");
if (flag_read == 0) {
int len;
len = sprintf(buf, "%s\n", proc_test_string);
flag_read = 1;
return len;
} else {
return 0;
}
}
/* /proc/MyDevice_test write */
static ssize_t mydevice_proc_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
printk("mydevice_proc_write\n");
if (count > sizeof(proc_test_string)) count = sizeof(proc_test_string) - 1;
if (copy_from_user(proc_test_string, buf, count)) {
return -EFAULT;
}
proc_test_string[count] = '\0';
return count;
}
/* file_operations */
static struct file_operations mydevice_proc_fops = {
.owner = THIS_MODULE,
.open = mydevice_proc_open,
.read = mydevice_proc_read,
.write = mydevice_proc_write,
};
/* 加载 (insmod)时调用的函数 */
static int mydevice_init(void)
{
struct proc_dir_entry *entry;
printk("mydevice_init\n");
/* 创建 procfs */
entry = proc_create(PROC_NAME, S_IRUGO | S_IWUGO, NULL, &mydevice_proc_fops);
if (entry == NULL) {
printk(KERN_ERR "proc_create\n");
return -ENOMEM;
}
return 0;
}
/* 卸载(rmmod)时调用的函数 */
static void mydevice_exit(void)
{
printk("mydevice_exit\n");
/* procfs 卸载く */
remove_proc_entry(PROC_NAME, NULL);
}
module_init(mydevice_init);
module_exit(mydevice_exit);
加载模块后,该proc_create
函数会创建一个文件/proc/MyDevice_test
。S_IRUGO | S_IWUGO
与 0666
相同,为所有用户提供RW
访问权限。
作者:SteveChen 创建时间:2025-03-30 18:08
最后编辑:SteveChen 更新时间:2025-03-30 18:10
最后编辑:SteveChen 更新时间:2025-03-30 18:10