- .mal.fakefat32.sector_size = 512,
- .mal.fakefat32.sector_number = 0x00001000,
- .mal.fakefat32.sectors_per_cluster = 8,
- .mal.fakefat32.volume_id = 0x0CA93E47,
- .mal.fakefat32.disk_id = 0x12345678,
- .mal.fakefat32.root[0].memfile.file.name= "ROOT",
- .mal.fakefat32.root[0].memfile.d.child = (struct vsfile_memfile_t *)fakefat32_root_dir,
这个是虚拟的FAT32文件系统的属性设置,无非就是设置一些扇区大小、数量,每簇扇区数,一些ID,和更目录结构位置。
- .usbd.rndis.param.CDCACM.CDC.ep_notify = 1,
- .usbd.rndis.param.CDCACM.CDC.ep_out = 2,
- .usbd.rndis.param.CDCACM.CDC.ep_in = 2,
- .usbd.rndis.param.mac.size = 6,
- .usbd.rndis.param.mac.addr.s_addr64 = 0x0605040302E0,
- .usbd.rndis.param.cb.param = &app,
- .usbd.rndis.param.cb.on_connect = app_rndis_on_connect,
- .usbd.cdc.param.CDC.ep_notify = 3,
- .usbd.cdc.param.CDC.ep_out = 4,
- .usbd.cdc.param.CDC.ep_in = 4,
- .usbd.cdc.param.CDC.stream_tx = (struct vsf_stream_t *)&app.usbd.cdc.stream_tx,
- .usbd.cdc.param.CDC.stream_rx = (struct vsf_stream_t *)&app.usbd.cdc.stream_rx,
- .usbd.cdc.param.line_coding.bitrate = 115200,
- .usbd.cdc.param.line_coding.stopbittype = 0,
- .usbd.cdc.param.line_coding.paritytype = 0,
- .usbd.cdc.param.line_coding.datatype = 8,
- .usbd.cdc.stream_tx.stream.op = &fifostream_op,
- .usbd.cdc.stream_tx.mem.buffer.buffer = (uint8_t *)&app.usbd.cdc.txbuff,
- .usbd.cdc.stream_tx.mem.buffer.size = sizeof(app.usbd.cdc.txbuff),
- .usbd.cdc.stream_rx.stream.op = &fifostream_op,
- .usbd.cdc.stream_rx.mem.buffer.buffer = (uint8_t *)&app.usbd.cdc.rxbuff,
- .usbd.cdc.stream_rx.mem.buffer.size = sizeof(app.usbd.cdc.rxbuff),
- .usbd.msc.param.ep_in = 5,
- .usbd.msc.param.ep_out = 5,
- .usbd.msc.param.scsi_dev = &app.mal.scsi_dev,
- .usbd.ifaces[0].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_RNDISControl_class,
- .usbd.ifaces[0].protocol_param = &app.usbd.rndis.param,
- .usbd.ifaces[1].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_RNDISData_class,
- .usbd.ifaces[1].protocol_param = &app.usbd.rndis.param,
- .usbd.ifaces[2].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMControl_class,
- .usbd.ifaces[2].protocol_param = &app.usbd.cdc.param,
- .usbd.ifaces[3].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_CDCACMData_class,
- .usbd.ifaces[3].protocol_param = &app.usbd.cdc.param,
- .usbd.ifaces[4].class_protocol = (struct vsfusbd_class_protocol_t *)&vsfusbd_MSCBOT_class,
- .usbd.ifaces[4].protocol_param = &app.usbd.msc.param,
- .usbd.config[0].num_of_ifaces = dimof(app.usbd.ifaces),
- .usbd.config[0].iface = app.usbd.ifaces,
- .usbd.device.num_of_configuration = dimof(app.usbd.config),
- .usbd.device.config = app.usbd.config,
- .usbd.device.desc_filter = (struct vsfusbd_desc_filter_t *)USB_descriptors,
- .usbd.device.device_class_iface = 0,
- .usbd.device.drv = (struct interface_usbd_t *)&core_interfaces.usbd,
- .usbd.device.int_priority = 0,
USB设备端,3种设备的设置,3个设备中CDC和RNDIS对应2个USB的接口,所以一共是5个USB的接口。这里做了这些接口的数据结构的初始化。并且,初始化了USB的config、interface以及描述符、底层驱动等结构。
- .usbd.rndis.param.netif.macaddr.size = 6,
- .usbd.rndis.param.netif.macaddr.addr.s_addr64 = 0x0E0D0C0B0AE0,
- .usbd.rndis.param.netif.ipaddr.size = 4,
- .usbd.rndis.param.netif.ipaddr.addr.s_addr = 0x01202020,
- .usbd.rndis.param.netif.netmask.size = 4,
- .usbd.rndis.param.netif.netmask.addr.s_addr = 0x00FFFFFF,
- .usbd.rndis.param.netif.gateway.size = 4,
- .usbd.rndis.param.netif.gateway.addr.s_addr = 0x01202020,
RNDIS设备的属性设,这个在简单不过了
- .vsfip.telnetd.telnetd.port = 23,
- .vsfip.telnetd.telnetd.session_num = dimof(app.vsfip.telnetd.sessions),
- .vsfip.telnetd.sessions[0].stream_tx = (struct vsf_stream_t *)&app.vsfip.telnetd.stream_tx,
- .vsfip.telnetd.sessions[0].stream_rx = (struct vsf_stream_t *)&app.vsfip.telnetd.stream_rx,
- .vsfip.telnetd.stream_tx.stream.op = &fifostream_op,
- .vsfip.telnetd.stream_tx.mem.buffer.buffer = (uint8_t *)&app.vsfip.telnetd.txbuff,
- .vsfip.telnetd.stream_tx.mem.buffer.size = sizeof(app.vsfip.telnetd.txbuff),
- .vsfip.telnetd.stream_rx.stream.op = &fifostream_op,
- .vsfip.telnetd.stream_rx.mem.buffer.buffer = (uint8_t *)&app.vsfip.telnetd.rxbuff,
- .vsfip.telnetd.stream_rx.mem.buffer.size = sizeof(app.vsfip.telnetd.rxbuff),te
telnetd的属性设置,这里设置了数据收发的流,这个流的另一端就是接到命令行组件的,基于telnetd的命令行界面,几乎不用什么代码,通过这些简单的设置就能够实现
- .shell.echo = false,
- .shell.stream_tx = (struct vsf_stream_t *)&app.vsfip.telnetd.stream_tx,
- .shell.stream_rx = (struct vsf_stream_t *)&app.vsfip.telnetd.stream_rx,
命令行界面的属性设置,telnet的客户端会自己回显,所以不需要shell的回显功能。另外就是链接shell的输入和输出流到telnetd的流。
- int main(void)
- {
- vsf_enter_critical();
- vsfsm_evtq_init(&app.pendsvq);
- vsfsm_evtq_set(&app.pendsvq);
- vsfhal_core_pendsv_config(app_on_pendsv, &app.pendsvq);
- vsfsm_init(&app.sm);
- vsf_leave_critical();
- vsfsm_evtq_set(NULL);
- while (1)
- {
- // no thread runs in mainq, just sleep in main loop
- vsfhal_core_sleep(SLEEP_WFI);
- }
- }
main函数,这里的while(1)里放的是非实时代码。
- static struct vsfsm_state_t *
- app_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
- {
- switch (evt)
- {
- case VSFSM_EVT_INIT:
- vsfhal_core_init(NULL);
- vsfhal_tickclk_init();
- vsfhal_tickclk_start();
- VSFPOOL_INIT(&app.vsftimer_pool, struct vsftimer_t, APPCFG_VSFTIMER_NUM);
- vsftimer_init((struct vsftimer_mem_op_t *)&vsftimer_memop);
- vsfhal_tickclk_config_cb(app_tickclk_callback_int, NULL);
- vsf_bufmgr_init(app.bufmgr_buffer, sizeof(app.bufmgr_buffer));
- // fs init: currently supported fs are non-block, so ugly pt code below
- {
- struct vsfile_t *file;
- VSFPOOL_INIT(&app.vfsfile_pool, struct vsfile_vfsfile_t, 2);
- vsfile_init((struct vsfile_memop_t *)&app_vsfile_memop);
- // create msc_root and httpd_root under root
- app.caller_pt.state = 0;
- vsfile_addfile(&app.caller_pt, 0, NULL, "msc_root", VSFILE_ATTR_DIRECTORY);
- // mount fakefat32 under /msc_root
- app.caller_pt.state = 0;
- vsfile_getfile(&app.caller_pt, 0, NULL, "/msc_root", &file);
- app.caller_pt.state = 0;
- app.caller_pt.user_data = &app.mal.fakefat32;
- vsfile_mount(&app.caller_pt, 0, (struct vsfile_fsop_t *)&fakefat32_fs_op, file);
- }
- // vsfip init
- {
- struct vsfip_buffer_t *buffer;
- int i;
- buffer = &app.vsfip.buffer_pool.buffer[0];
- for (i = 0; i < APPCFG_VSFIP_BUFFER_NUM; i++)
- {
- buffer->buffer = app.vsfip.buffer_mem[i];
- buffer++;
- }
- }
- VSFPOOL_INIT(&app.vsfip.buffer_pool, struct vsfip_buffer_t, APPCFG_VSFIP_BUFFER_NUM);
- VSFPOOL_INIT(&app.vsfip.socket_pool, struct vsfip_socket_t, APPCFG_VSFIP_SOCKET_NUM);
- VSFPOOL_INIT(&app.vsfip.tcppcb_pool, struct vsfip_tcppcb_t, APPCFG_VSFIP_TCPPCB_NUM);
- vsfip_init((struct vsfip_mem_op_t *)&app_vsfip_mem_op);
- // telnet stream innit
- STREAM_INIT(&app.vsfip.telnetd.stream_rx);
- STREAM_INIT(&app.vsfip.telnetd.stream_tx);
- vsfip_telnetd_start(&app.vsfip.telnetd.telnetd);
-
- // usbd cdc init
- STREAM_INIT(&app.usbd.cdc.stream_rx);
- STREAM_INIT(&app.usbd.cdc.stream_tx);
- vsfscsi_init(&app.mal.scsi_dev);
- vsfusbd_device_init(&app.usbd.device);
- #if defined(APPCFG_BUFMGR_SIZE) && (APPCFG_BUFMGR_SIZE > 0)
- vsfshell_init(&app.shell);
- #endif
- if (app.usb_pullup.port != IFS_DUMMY_PORT)
- {
- vsfhal_gpio_init(app.usb_pullup.port);
- vsfhal_gpio_clear(app.usb_pullup.port, 1 << app.usb_pullup.pin);
- vsfhal_gpio_config_pin(app.usb_pullup.port,
- app.usb_pullup.pin, GPIO_OUTPP);
- }
- app.usbd.device.drv->disconnect();
- vsftimer_create(sm, 200, 1, APP_EVT_USBPU_TO);
- break;
- case APP_EVT_USBPU_TO:
- if (app.usb_pullup.port != IFS_DUMMY_PORT)
- {
- vsfhal_gpio_set(app.usb_pullup.port,
- 1 << app.usb_pullup.pin);
- }
- app.usbd.device.drv->connect();
- break;
- }
- return NULL;
- }
APP初始化,其实也就是调用各个组件的初始化代码,所有组件初始化完成后,关闭USB的上拉,然后建立200ms定时器。
之后200ms到了时候,会发送定时器事件,然后重新使能USB上拉,系统就跑起来了。
- void app_rndis_on_connect(void *param)
- {
- struct vsfapp_t *app = (struct vsfapp_t *)param;
- vsfip_dhcpd_start(&app->usbd.rndis.param.netif, &app->usbd.rndis.dhcpd);
- }
一些回调函数,这里在RNDIS的on_connect响应中,启动dhcpd组件,并应用于usb的rndis的网络接口
其它代码,也基本上都是类似的简单代码,甚至不需要写任何USB端点初始化的代码(USB组件具备自动初始化各个端点的功能,用户只需要输入正确的描述符即可),系统就可以运行起来了。