代码阅读方法(自己总结地 厚厚)

 不知道大家是否看到几万行的代码是什么心情。 有人说过,阅读别人的代码是一种享受。下午的时候,泡上一壶好茶,坐在自己家的阳台上,阅读代码。嗯嗯,比看小说要有意思的多了。学习别人的思想,让自己的思维更敏捷。

在07年的第一篇有关技术的文章,把我自己读代码的经验和大家分享一下。

其实主要是做笔记,一个大的项目,或程序,估计几万行代码是下不来的。 就像谁也不能把金庸全集一口气看完一样。那么知道自己看到哪了,上下文如何衔接起来,就要靠记录了。你可以选择有笔纸,选择键盘敲,无所谓。

你可以选择用图,或用自己的大白话。自己习惯,和要适合自己大脑的思维方式来定。

我比较喜欢用图的,有助于逻辑思维的记忆和锻炼。

图大概有:

     --流程图;

     --时序图;

     --数据流图;

对于一个大的项目,一个也不能少。

前一段时间分析linux内核中的usb gadgetfs 驱动,相关文件有$(kernel)/device/usb/gadget/ inode.c和一个

USB官网上的用户态驱动usb.c。

下面是我的记录用的是“树形结构”(自己起的名字,呵呵),不是很全,仅提供思路,希望大家可以在代码中找到乐趣,思维更加灵敏。

这个是USB.C的:

int main (int argc, char **argv)
 |
 |/* random initial serial number */
 |
 | 接收控制参数;
 |
 | 改变路径到/dev/gadget;
 |
 |-- init_device (); /* 设备初始化 */
 | |
 | |-- autoconfig (); /* 自动配置端点 */
 | |     |
 | |     | 取得设备名称,信息;
 | |     |
 | |     | 设置端点地址,和端点名;
 | |     |-[R]
 | | 
 | |-- open (DEVNAME, O_RDWR); /* 打开设备文件 */
 | | 
 | | /* write full then high speed configs */
 | |-- static char *build_config (char *cp, const struct usb_endpoint_descriptor **ep); 
 | |  |         
 | |  | 一个cp指针指向buf, 用buf来存储个描述符;
 | |  |buf
 | | |      ________
 | | |     |                     |
 | | |     | config         |
 | | |     |                     |
 | | |     |interface     |
 | | |     |                     |
 | | |     | ep               |
 | | |     |________  |
 | | |
 | | |-[R]
 | |
 | | /* and device descriptor at the end */
 | |
 | |-- write (fd, &buf [0], cp - &buf [0]); /* write dev descriptor */
 | |
 | |--[return] 一个配置符齐全的fd;
 | 
 | 
 | /* control thread, handles main event loop  */ 
 |-- ep0_thread (&fd); /* 将init_device 后的fd 传给了它 */ 
 | |
 | |当有事件以信号的方式传递给它时,
 | |它是用wait等待的sigwait (&sigs, &tmp);
 | |
 | |然后利用switch(tmp)来处理不同类型的事件,然后做相应的控制
 | |
 | |/* loop */
 | | case GADGETFS_SETUP:
 | |  handle_control (fd, &event [i].u.setup);
 | |  
 | |    static void handle_control (int fd, struct usb_ctrlrequest *setup)
 | |     | |
 | |     | |- struct usb_ctrlrequest 
       | /*this structure is used to send control requests to a USB device.*/
       |
       | 处理标准的USB设备请求命令
       |
       |switch(setup->bRequest)
       | |
       | |
       | |case USB_REQ_SET_CONFIGURATION:
       | | if (setup->bRequestType != USB_DIR_OUT)
       | |  goto stall;
       | | if (verbose)
       | |  fprintf (stderr, "CONFIG #%d/n", setup->wValue);
       | |
       | | ...
       | | switch (setup->wValue) {
       | | case CONFIG_VALUE:
       | |  start_io (); /* 启动线程 */
       | |  break;
       | | case 0:
       | |  stop_io ();
       | |  break;
 

 


 

 


static void start_io ()
 |
 |除ep0外,其他2个端点是以线程的方式运行的,在这里启动2线程
 |
 |/*create source thread*/ /In/
 |
 |/*create sink thread*/  /Out/
 


/* source endpoint thread */
static void *simple_source_thread (void *param)
 |
 | 配置端点 source_open /* 一个可以配置端点的宏,在下面有它的实现 */
 |
 |--while(status > 0) {
   len = fill_in_buf (buf, sizeof buf);
  if (len > 0)
   status = write (source_fd, buf, len);
  }
 |
 |
 
/* sink endpoint thread */
static void *simple_sink_thread (void *param)
 |
 |配置端点 sink_open /* 一个可以配置端点的宏,在下面有它的实现 */
 |
 |--while{
  status = read (sink_fd, buf, sizeof buf);

  if (status < 0)
   break;
  status = empty_out_buf (buf, status);
  }
 |
 |
 |
 
 
 
 
 
 
 
 
 
#define source_open(name) /
 ep_config(name,__FUNCTION__, &fs_source_desc, &hs_source_desc)
#define sink_open(name) /
 ep_config(name,__FUNCTION__, &fs_sink_desc, &hs_sink_desc)
 
/* you should be able to open and configure endpoints
 * whether or not the host is connected
 */
static int
ep_config (char *name, char *label,
 struct usb_endpoint_descriptor *fs,
 struct usb_endpoint_descriptor *hs)
 |
 |
 |

 

这个是linux内核中的inode.c(gadgetfs的实现),不是很全,现在正在看。

/*
 * read kernel/driver/usb/gadget/inode.c
 *
 * gadgetfs gadget api
 *
 * date : 1-6-2007
 *
 */
[mynote]:
1.gadgetfs
2.dev_config
3.dev operation
4.ep_config
5.ep_peration
|
|-- register_filesystem (&gadgetfs_type)
|
| /* when __init module_init */
| /* gadgetfs_type object have a implant structure.*/
|-- struct file_system_type gadgetfs_type
|     |-- gadgetfs_get_sb
|
| /* when  "mount -t gadgetfs path /dev/gadget" ends up here
| will call gadgetfs_get_sb
| */
|--gadgetfs_get_sb
|    |
|    |//call a system call , register gadgetfs_fill_super to kernel.
|    |--get_sb_single (t, flags, opts, gadgetfs_fill_super)
|
| /* a main function, kernel will callback this function of inode.c  */
| 仅仅用于探测一个UDC的设备名字,然后在/DEV/GADGET/下建立如下文件节点
| 1.$CHIP
| 2.$ep0
| 3.$other ep
|-- gadgetfs_fill_super 
| |
 |1.
 |/* fake probe to determine $CHIP */
 |--(void) usb_gadget_register_driver (&probe_driver);
 |
 |  sturct usb_gadget_driver probe_driver
 |    | --gadgetfs_probe
 |    |   | 1.[input] usb_gadget device
 |    |   | 2.CHIP = gadget->name /* 将设备名称给CHIP */
 |
 |
 |/*[??note]when*/ dev_config
 |  |
 |  |/* triggers gadgetfs_bind(); then we can enumerate. */
 |         |--value = usb_gadget_register_driver (&gadgetfs_driver) 
 |
 |
 |2.
 | /*建立跟节点root inode*/
 | gadgetfs_make_inode
 |
 |3. 建立ep0节点文件
 | /* the ep0 file is named after the controller we expect;
        |       user mode code can use it for sanity checks, like we do.
 | */
 |
 |
 |4. 建立其他节点文件
 |/* other endpoint files are available after hardware setup,
 |    from binding to a controller.
 |*/
 
|
|

黏贴过来时,好像制表符没了,看起来有点丑。 那个,推荐用UltraEdit来记录。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值