打印

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

[复制链接]
1060|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协议栈有几部分组成,结构如下:

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

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

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

.usbd.ifaces[0].class_protocol                        = (struct vsfusbd_class_protocol_t *)&vsfusbd_MSCBOT_class,
.usbd.ifaces[0].protocol_param                        = &usrapp.usbd.msc.param,
.usbd.config[0].num_of_ifaces                        = dimof(usrapp.usbd.ifaces),
.usbd.config[0].iface                                        = usrapp.usbd.ifaces,
.usbd.device.num_of_configuration                = dimof(usrapp.usbd.config),
.usbd.device.config                                                = usrapp.usbd.config,
.usbd.device.desc_filter                                = (struct vsfusbd_desc_filter_t *)usrapp_param.usbd.StdDesc,
.usbd.device.device_class_iface                        = 0,
.usbd.device.drv                                                = (struct vsfhal_usbd_t *)&vsfhal_usbd,
.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设备了:
vsfusbd_device_init(&app->usbd.device);
app->usbd.device.drv->connect();
if (app_hwcfg.usbd.pullup.port != VSFHAL_DUMMY_PORT)
        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接口的参数:
.usbd.msc.param.ep_in                                        = 3,
.usbd.msc.param.ep_out                                        = 3,
.usbd.msc.param.scsi_dev                                = &usrapp.mal.scsi_dev,

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


总结:


使用特权

评论回复

相关帖子

发新帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

vsf

27

主题

60

帖子

6

粉丝