1. 程式人生 > >proc的妙用

proc的妙用

llb term over oar 網絡 moved jiffies .org working

今天在在公司做網絡驅動開發測試時,隨機包出現收包計數停止的現象,當時懷疑是DMA rx buffer不足導致,想通過對比收發包正常和收發包不正常是DMA相關寄存器的情況。

後跟蹤代碼,若在收發包裏面增加打印,必定回降低收發包性能,對比結果也就不準了,分析代碼分析來分析去,最終發現做合適的就是采用proc。

  1 /*  
  2  * procfs_example.c: an example proc interface  
  3  *  
  4  * Copyright (C) 2001, Erik Mouw ([email protected])  
  5  *  
  6  * This file accompanies the procfs-guide in the Linux kernel  
7 * source. Its main use is to demonstrate the concepts and 8 * functions described in the guide. 9 * 10 * This software has been developed while working on the LART 11 * computing board (http://www.lartmaker.nl), which was sponsored 12 * by the Delt University of Technology projects Mobile Multi-media
13 * Communications and Ubiquitous Communications. 14 * 15 * This program is free software; you can redistribute 16 * it and/or modify it under the terms of the GNU General 17 * Public License as published by the Free Software 18 * Foundation; either version 2 of the License, or (at your
19 * option) any later version. 20 * 21 * This program is distributed in the hope that it will be 22 * useful, but WITHOUT ANY WARRANTY; without even the implied 23 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 24 * PURPOSE. See the GNU General Public License for more 25 * details. 26 * 27 * You should have received a copy of the GNU General Public 28 * License along with this program; if not, write to the 29 * Free Software Foundation, Inc., 59 Temple Place, 30 * Suite 330, Boston, MA 02111-1307 USA 31 * 32 */ 33 34 #include <linux/module.h> 35 #include <linux/kernel.h> 36 #include <linux/init.h> 37 #include <linux/proc_fs.h> 38 #include <linux/jiffies.h> 39 #include <asm/uaccess.h> 40 41 42 #define MODULE_VERS "1.0" 43 #define MODULE_NAME "procfs_example" 44 45 #define FOOBAR_LEN 8 46 47 struct fb_data_t { 48 char name[FOOBAR_LEN + 1]; 49 char value[FOOBAR_LEN + 1]; 50 }; 51 52 53 static struct proc_dir_entry *example_dir, *foo_file, 54 *bar_file, *jiffies_file, *symlink; 55 56 57 struct fb_data_t foo_data, bar_data; 58 59 60 static int proc_read_jiffies(char *page, char **start, 61 off_t off, int count, 62 int *eof, void *data) 63 { 64 int len; 65 66 len = sprintf(page, "jiffies = %ld\n", 67 jiffies); 68 69 return len; 70 } 71 72 73 static int proc_read_foobar(char *page, char **start, 74 off_t off, int count, 75 int *eof, void *data) 76 { 77 int len; 78 struct fb_data_t *fb_data = (struct fb_data_t *)data; 79 80 /* DON‘T DO THAT - buffer overruns are bad */ 81 len = sprintf(page, "%s = ‘%s‘\n", 82 fb_data->name, fb_data->value); 83 84 return len; 85 } 86 87 88 static int proc_write_foobar(struct file *file, 89 const char *buffer, 90 unsigned long count, 91 void *data) 92 { 93 int len; 94 struct fb_data_t *fb_data = (struct fb_data_t *)data; 95 96 if(count > FOOBAR_LEN) 97 len = FOOBAR_LEN; 98 else 99 len = count; 100 101 if(copy_from_user(fb_data->value, buffer, len)) 102 return -EFAULT; 103 104 fb_data->value[len] = \0; 105 106 return len; 107 } 108 109 110 static int __init init_procfs_example(void) 111 { 112 int rv = 0; 113 114 /* create directory */ 115 example_dir = proc_mkdir(MODULE_NAME, NULL); 116 if(example_dir == NULL) { 117 rv = -ENOMEM; 118 goto out; 119 } 120 /* create jiffies using convenience function */ 121 jiffies_file = create_proc_read_entry("jiffies", 122 0444, example_dir, 123 proc_read_jiffies, 124 NULL); 125 if(jiffies_file == NULL) { 126 rv = -ENOMEM; 127 goto no_jiffies; 128 } 129 130 /* create foo and bar files using same callback 131 * functions 132 */ 133 foo_file = create_proc_entry("foo", 0644, example_dir); 134 if(foo_file == NULL) { 135 rv = -ENOMEM; 136 goto no_foo; 137 } 138 139 strcpy(foo_data.name, "foo"); 140 strcpy(foo_data.value, "foo"); 141 foo_file->data = &foo_data; 142 foo_file->read_proc = proc_read_foobar; 143 foo_file->write_proc = proc_write_foobar; 144 145 bar_file = create_proc_entry("bar", 0644, example_dir); 146 if(bar_file == NULL) { 147 rv = -ENOMEM; 148 goto no_bar; 149 } 150 151 strcpy(bar_data.name, "bar"); 152 strcpy(bar_data.value, "bar"); 153 bar_file->data = &bar_data; 154 bar_file->read_proc = proc_read_foobar; 155 bar_file->write_proc = proc_write_foobar; 156 157 /* create symlink */ 158 symlink = proc_symlink("jiffies_too", example_dir, 159 "jiffies"); 160 if(symlink == NULL) { 161 rv = -ENOMEM; 162 goto no_symlink; 163 } 164 165 /* everything OK */ 166 printk(KERN_INFO "%s %s initialised\n", 167 MODULE_NAME, MODULE_VERS); 168 return 0; 169 170 no_symlink: 171 remove_proc_entry("bar", example_dir); 172 no_bar: 173 remove_proc_entry("foo", example_dir); 174 no_foo: 175 remove_proc_entry("jiffies", example_dir); 176 no_jiffies: 177 remove_proc_entry(MODULE_NAME, NULL); 178 out: 179 return rv; 180 } 181 182 183 static void __exit cleanup_procfs_example(void) 184 { 185 remove_proc_entry("jiffies_too", example_dir); 186 remove_proc_entry("bar", example_dir); 187 remove_proc_entry("foo", example_dir); 188 remove_proc_entry("jiffies", example_dir); 189 remove_proc_entry(MODULE_NAME, NULL); 190 191 printk(KERN_INFO "%s %s removed\n", 192 MODULE_NAME, MODULE_VERS); 193 } 194 195 196 module_init(init_procfs_example); 197 module_exit(cleanup_procfs_example); 198 199 MODULE_AUTHOR("Erik Mouw"); 200 MODULE_DESCRIPTION("procfs examples"); 201 MODULE_LICENSE("GPL");

驅動編譯腳本Makefile文件如下:

1    obj-m += proc.o
2        CURRENT_PATH:=$(shell pwd)
3            LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build
4    all:
5            $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
6    clean:
7           rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

本人是在ubuntu10.04下編譯。

proc的妙用