本帖最后由 vsf 于 2018-4-1 13:34 编辑
VSF应用实例--模拟U盘(1)USB设备端协议栈
VSF应用实例--模拟U盘(2)SCSI设备和块设备
VSF应用实例--模拟U盘(3)fakefat32模拟FAT32块设备
VSF中,SCSI设备就是可以执行SCSI命令流,并且返回应答流的设备。而块设备,就是通过块地址,按照固定大小访问的储存器设备。这里,块设备的定义比较宽泛,甚至显示器的显存也可以认为是一个块设备。
在模拟U盘中,由于MSC接口需要指定一个SCSI设备,用来执行PC发送过来的SCSI命令,而U盘的存储器,一般只是一个块设备,不具备直接执行scsi命令的能力。所以,这里就需要一个mal2scsi模块,功能为把mal块设备,转化为scsi设备。应用代码中的数据结构如下:
.mal.pbuffer[0] = usrapp.mal.buffer[0],
.mal.pbuffer[1] = usrapp.mal.buffer[1],
.mal.scsistream.mbuf.count = dimof(usrapp.mal.buffer),
.mal.scsistream.mbuf.size = sizeof(usrapp.mal.buffer[0]),
.mal.scsistream.mbuf.buffer_list = usrapp.mal.pbuffer,
对于scsi设备,定义max_lun(最大逻辑单元号),并且定义lun数组就可以了。每一个lun对应一个物理磁盘。每一个scsi的lun都需要具备执行scsi命令的能力。每一个lun需要定义3个参数,分别是op操作接口、stream流接口、param设备参数。这里,lun[0]磁盘,就是由mal2scsi模块的输出scsi设备,mal2scsi模块输入的是一个mal块设备。对于mal2scsi的块设备,流接口必须是vsf_scsistream_t,也就是上面的scsistream流。scsistream流定义了多缓冲,当然,只用一个缓冲也可以,如果用2个缓冲的话,就可以自动实现乒乓操作(scsi设备和mal块设备同时操作)。
mal2scsi参数设置:
.mal.mal2scsi.malstream.mal = &usrapp.mal.mal,
.mal.mal2scsi.cparam.block_size = 512,
.mal.mal2scsi.cparam.removable = false,
.mal.mal2scsi.cparam.vendor = "Simon ",
.mal.mal2scsi.cparam.product = "VSFDriver ",
.mal.mal2scsi.cparam.revision = "1.00",
.mal.mal2scsi.cparam.type = SCSI_PDT_DIRECT_ACCESS_BLOCK,
大部分参数只是一些信息参数,最关键的是malstream.mal接口,用于指向一个块设备。当然,从名字来看的话,这个块设备实际是用流的方式操作。当然,可以把模块当做黑盒子,只是做应用的话,不用管模块内部如何操作,只要知道模块的功能、接口等等信息即可。
应用代码:
vsfscsi_init(&app->mal.scsi_dev);
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初始化之前,初始化scsi设备即可。
基本上,VSF中的模块使用方法都是这样,定义数据结构,指定模块之间的链接关系。然后调用初始化或者应用的API接口。
总体模块结构增加为:
|