proc的妙用

今天在在公司做网络驱动开发测试时,随机包出现收包计数停止的现象,当时怀疑是DMA rx buffer不足导致,想通过对比收发包正常和收发包不正常是DMA相关寄存器的情况。

后跟踪代码,若在收发包里面增加打印,必定回降低收发包性能,对比结果也就不准了,分析代码分析来分析去,最终发现做合适的就是采用proc。

  1 /*  
  2  * procfs_example.c: an example proc interface  
  3  *  
  4  * Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org)  
  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下编译。

posted @ 2017-10-24 22:18  haoxing990  阅读(594)  评论(0编辑  收藏  举报