參考資料:https://blog.csdn.net/rikeyone/article/details/103586453
seq_file系列函式是為了方便核心匯出資訊到sysfs、debugfs、procfs實現的。
seq_file的相關介面函式如下:
int seq_open(struct file *file, const struct seq_operations *op); int seq_release(struct inode *inode, struct file *file); ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos); int seq_write(struct seq_file *seq, const void *data, size_t len); loff_t seq_lseek(struct file *file, loff_t offset, int whence);
用到seq_file的方便之處在於,對於UMD和KMD之間的交換,熟悉的copy_to_user和copy_from_user函式,但是在使用的時候需要自己分配一塊buffer,seq_file系列操作函式就可以幫忙省去分配核心buffer的過程,舉一個demo例子:
#include <linux/module.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> static int demo_seq_show(struct seq_file *m, void *v) { int i; for (i = 1; i <= 10; i++) { seq_printf(m, "%d\n", i); // 將數字序列寫入到 seq_file 中 } return 0; } static int demo_seq_open(struct inode *inode, struct file *file) { return single_open(file, demo_seq_show, NULL); // 呼叫 single_open 函式 } static const struct file_operations demo_seq_fops = { .owner = THIS_MODULE, .open = demo_seq_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int __init demo_seq_init(void) { proc_create("demo_sequence", 0, NULL, &demo_seq_fops); // 建立名為 "demo_sequence" 的虛擬檔案 return 0; } static void __exit demo_seq_exit(void) { remove_proc_entry("demo_sequence", NULL); // 移除虛擬檔案 } module_init(demo_seq_init); module_exit(demo_seq_exit); MODULE_LICENSE("GPL");
應用測試demo:
#include <stdio.h> #include <stdlib.h> #define MAX_BUF_SIZE 1024 #define PROC_FILE_PATH "/proc/demo_sequence" int main() { FILE *file; char buffer[MAX_BUF_SIZE]; file = fopen(PROC_FILE_PATH, "r"); if (file == NULL) { perror("Error opening file"); return 1; } while (fgets(buffer, sizeof(buffer), file) != NULL) { printf("%s", buffer); } fclose(file); return 0; }
實際使用:
在驅動中,seq_file用於debug十分常見,例如需要獲取控制器的配置暫存器,就可以procfs或者debugfs使用seq_file作為一種核心debug手段