VSF应用实例--模拟U盘(1)USB设备端协议栈

[复制链接]
1266|0
 楼主| vsf 发表于 2018-3-27 13:47 | 显示全部楼层 |阅读模式
本帖最后由 vsf 于 2018-4-1 13:34 编辑

VSF应用实例--模拟U盘(1)USB设备端协议栈
VSF应用实例--模拟U盘(2)SCSI设备和块设备
VSF应用实例--模拟U盘(3)fakefat32模拟FAT32块设备

使用MCU模拟U盘并不是什么新技术了,网上也可以找到不少示例demo,这里就介绍一下VSF构架中,模拟U盘的实现。

VSF中实现了一个通用的MCU USB设备端协议栈,可以比较方便的实现各种USB设备,并且,由于具备通用的底层usbd hal,所以协议栈和应用层代码可以做到硬件无关。要模拟U盘的话,就先要了解一下VSF中的USB设备端协议栈。

VSF中的USB协议栈有几部分组成,结构如下:
usbd.jpg
vsfhal_usbd是底层硬件抽象驱动接口,封装了不同MCU中的USB SIE的实现。
vsfusbd是VSF中的usbd协议栈,和底层硬件无关。
usbd协议栈之上,就是各种类驱动,比如CDC、HID等等。对于模拟U盘的话,使用的是MSC类驱动。
再高层就是应用层了,应用层基本只是定义USB相关的数据和结构,然后启动USB设备协议栈。

这里只介绍应用层相关的内容,要实现USB设备的话,应用层需要定义USB相关的描述符、USBD相关的数据结构、调用usbd协议栈初始化接口、控制USB的上拉使能。

其中,比较关键的是usbd相关的数据结构,下面是模拟U盘使用的usbd数据结构:
  1. struct
  2. {
  3.         struct
  4.         {
  5.                 struct vsfusbd_MSCBOT_param_t param;
  6.         } msc;
  7.         struct vsfusbd_iface_t ifaces[4];
  8.         struct vsfusbd_config_t config[1];
  9.         struct vsfusbd_device_t device;
  10. } usbd;

  11. .usbd.ifaces[0].class_protocol                        = (struct vsfusbd_class_protocol_t *)&vsfusbd_MSCBOT_class,
  12. .usbd.ifaces[0].protocol_param                        = &usrapp.usbd.msc.param,
  13. .usbd.config[0].num_of_ifaces                        = dimof(usrapp.usbd.ifaces),
  14. .usbd.config[0].iface                                        = usrapp.usbd.ifaces,
  15. .usbd.device.num_of_configuration                = dimof(usrapp.usbd.config),
  16. .usbd.device.config                                                = usrapp.usbd.config,
  17. .usbd.device.desc_filter                                = (struct vsfusbd_desc_filter_t *)usrapp_param.usbd.StdDesc,
  18. .usbd.device.device_class_iface                        = 0,
  19. .usbd.device.drv                                                = (struct vsfhal_usbd_t *)&vsfhal_usbd,
  20. .usbd.device.int_priority                                = 0xFF,


这里比较关键的是ifaces的定义,一个USB设备有几个接口,就会有几个ifaces,模拟U盘的话,只需要一个MSC接口,所以只有一个ifaces。
应用层定义一个接口的话,主要就是设置接口驱动需要的参数(protocol_param)、并且设置接口驱动指针(class_protocol)。
这里vsfusbd_MSCBOT_class就是已经实现好的MSCBOT接口驱动。
另外一个关键的,就是设置USB设备的各个描述符,这里就是desc_filter。
最后,就是和硬件相关的接口,drv(hal层的驱动接口)和int_priority(中断优先级)。

数据结构设置完成后,就只需要几行代码就可以启动USB设备了:
  1. vsfusbd_device_init(&app->usbd.device);
  2. app->usbd.device.drv->connect();
  3. if (app_hwcfg.usbd.pullup.port != VSFHAL_DUMMY_PORT)
  4.         vsfhal_gpio_set(app_hwcfg.usbd.pullup.port, 1 << app_hwcfg.usbd.pullup.pin);
这里就只是简单的初始化USB设备协议栈,调用hal层的connect接口,然后如果硬件有1.5K上拉的IO,则置位上拉IO。
然后,其他的就都交给USB设备协议栈来自动完成了,甚至包含USB的各个EP端口的初始化,都不需要用户参与。

这样的话,用于的应用就完全面向一个问题,就是要做什么。
对于模拟U盘,那就是要设置好MSC接口的参数:
  1. .usbd.msc.param.ep_in                                        = 3,
  2. .usbd.msc.param.ep_out                                        = 3,
  3. .usbd.msc.param.scsi_dev                                = &usrapp.mal.scsi_dev,

对于U盘来说,参数也只是设备对应的USB端点号,然后设置一个scsi设备(U盘的操作,都是通过scsi命令来实现的,实际上U盘就是一个scsi设备)。


总结: title1.png


vsf

27

主题

60

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部