说明:此部分代码目前还为公开,本文提供给拿到代码,准备做文件系统的人参考。
VSF最新代码里,增加了一个aio示例,把VSF里的各个功能都整合到一个项目中,当然,这样对MCU的资源要求也比较高,目前使用新塘的NUC442测试,以后会换为新塘的NUC480系列。
示例代码的usrapp.c里的usrapp_init_thread中,有一段代码用于安装文件系统。目前实现了2个文件系统,底层驱动分别是fakefat32_fs_op和vsffat_op,也就是fakefat32里的2个接口实现的文件系统,对应的内容完全一样。fakefat32_fs_op是通过vsfile_memfs接口来操作文件,而vsffat_op是通过fat文件系统驱动来操作。这2个文件系统分别安装在/msc_root和/msc_mal_root中。代码如下:
caller_pt->sm = pt->sm;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_addfile(caller_pt, evt, NULL, "msc_root", VSFILE_ATTR_DIRECTORY);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_getfile(caller_pt, evt, NULL, "/msc_root", &app->fs.file);
if (err) return err;
caller_pt->state = 0;
caller_pt->user_data = &app->mal.fakefat32;
vsfsm_pt_entry(pt);
err = vsfile_mount(caller_pt, evt, (struct vsfile_fsop_t *)&fakefat32_fs_op, app->fs.file);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_close(caller_pt, evt, app->fs.file);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_addfile(caller_pt, evt, NULL, "msc_mal_root", VSFILE_ATTR_DIRECTORY);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_getfile(caller_pt, evt, NULL, "/msc_mal_root", &app->fs.file);
if (err) return err;
usrapp.fs.fat_mal.size =
usrapp.mal.fakefat32.sector_number * usrapp.mal.fakefat32.sector_size;
caller_pt->state = 0;
caller_pt->user_data = &app->fs.fat_mal.mal;
vsfsm_pt_entry(pt);
err = vsfmal_init(caller_pt, evt);
if (err) return err;
caller_pt->state = 0;
caller_pt->user_data = &app->fs.fat;
vsfsm_pt_entry(pt);
err = vsfile_mount(caller_pt, evt, (struct vsfile_fsop_t *)&vsffat_op, app->fs.file);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_close(caller_pt, evt, app->fs.file);
if (err) return err;
实质上,以上代码只是建立虚拟目录,打开目录,安装文件系统,关闭目录。
对于文件系统的测试方法有2个,1个是通过telnet登陆命令行界面后,使用ls、cd、cat、pwd等命令访问。目前NUC442由于USBD接口的硬件BUG,所以不能稳定使用RNDIS来实现,需要外接一个ECM协议的USB网卡(比如r8152),然后会自动分配IP地址,可以从串口的dmesg中,看到IP地址,就可以使用putty来连接telnet接口了(使用raw模式)。dmesg串口日志如下:
cdc_ecm: vid0BDA pid8152 interface0
cdc_ecm: MAC is 00:E0:4C:36:21:32
cdc_ecm_event: NETWORK_CONNECTION Connected
......一些dhcp报文
dhcpc: 192.168.1.141
putty中,“Connect type”使用Raw,“Host Name(or IP Address)”填入设备分配到的IP地址,参照上面的日志,应该是192.168.1.141,Port使用23,点击“Open”了之后,就会出现命令行串口,然后使用命令“cat /msc_mal_root/Driver/Windows/VSFCDC.inf”,就会执行文件系统的操作了,当然也可以用cd和ls命令。命令行如下:
vsfshell 0.1 beta by SimonQian
https://github.com/versaloon/vsf
Using "help" for more information
>>>cat /msc_mal_root/Driver/Windows/VSFCDC.inf
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%PRVDR%
CatalogFile=VSFCDC.cat
......文件的其他内容
>>>ls
DIR(0):msc_mal_root
DIR(0):msc_root
>>>cd msc_mal_root
>>>ls
DIR(0):Driver
DIR(0):HttpRoot
>>>pwd
msc_mal_root
>>>cd Driver
>>>ls
DIR(0):.
DIR(0):..
DIR(0):Windows
>>>cd Windows
>>>ls
DIR(0):.
DIR(0):..
FIL(1558):VSFCDC.inf
>>>cat VSFCDC.inf
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
......文件的其他内容
另外还有一种简单的方法,在usrapp_init_thread中,使能以下代码:
#if 1
{
static uint8_t buf[2048];
static uint32_t rsize;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_getfile(caller_pt, evt, NULL, "/msc_mal_root/Driver/Windows/VSFCDC.inf", &app->fs.file);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_read(caller_pt, evt, app->fs.file, 0,
app->fs.file->size, buf, &rsize);
if (err) return err;
caller_pt->state = 0;
vsfsm_pt_entry(pt);
err = vsfile_close(caller_pt, evt, app->fs.file);
if (err) return err;
}
#endif
相当于fopen、fread和fclose。这样就不需要外部接USB网卡,直接就可以调试了。
aio示例代码中,文件系统相关的结构如图,仅供参考: