分类: LINUX
2007-08-22 14:13:16
图大概有:
--流程图;
--时序图;
--数据流图;
对于一个大的项目,一个也不能少。
前一段时间分析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.
|*/
|
|
转自:http://blog.csdn.net/freedom1013/archive/2007/01/08/1476682.aspx