10781| 1
|
[ESP8266/ESP32] ESP32 S2 做一个假U盘 |
ESP32 S2 支持 USB Device (实际上是 OTG ,但是厂家一直没有放出对于 USB Host 的支持,所以一般用户只能按照 Device 来使用)。对于 USB Device 来说,MassStorageDevice(缩写为 MSD)是我们通常能接触到的传输最快的设备。之前介绍过Arduino TinyUSB 库的使用,其中提供了一个 RAM Disk 的例子,是使用 PSRAM(2MBytes) 将自身模拟为一个1.5Mbytes大小FAT12格式的U盘。美中不足的是空间过小没有太多实用性。 这次介绍如何来将自身模拟为一个更大的U盘。从原理上来说,设备需要正确响应读取命令READ10,需要返回正确的内容。而对于 Windows来说,写入之后系统内部有缓存机制,设备无需真正存储写入的内容,用户也可以看到刚刚写入的内容。因此,我们可以将一个U盘中的内容写到 SPI ROM 中。只要U盘内容没有超过ESP32S2SPI 的大小,都是有机会来实现的。 第一步,制作U盘内容文件。 1. 磁盘管理器中创建一个 VHD 2. 我们创建一个 32MB 的虚拟磁盘,这里使用32MB的原因是我们希望格式化之后一个扇区512Bytes,如果创建为32MB那么Windows格式化最小的扇区是1024Bytes。 3. 创建之后这个盘是没有初始化,没有分区的 我们需要初始化之 推荐使用GPT分区 再创建一个 Simple Volume 推荐使用 FAT格式: 4. 上述操作之后系统中就多出来一个盘符: 5. 接下来需要使用工具来制作这个盘的镜像。我是用 HXD (HexEditor and Disk Editor )这个工具是免费的。需要以管理员权限启动之 需要选择 Physical Disks 中的64MB 的盘 使用 Save As 保存为文件 6.上述操作结束后,我们就有一个32MB大小的文件。之后在磁盘管理器中 Detach VHD 刚才创建的虚拟盘。 这个时候,我们可以看到2个文件,比如下面的 VHD 是我们刚才的虚拟硬盘文件,64MBDisk是上面硬盘的镜像。两者大部分的内容是相同,前者比后者在文件尾部稍微多了一些格式数据。 第二步,上面我们有了合适的磁盘镜像,接下来我们需要将这个数据转化为给 Arduino 使用的定义文件。为此编写一个 C# 程序,对文件以512Bytes为单位进行扫描。如果某一个512Bytes内出现不为0 的字节,那么就将整个512Bytes保存下来。 软件使用方法很简单,使用 open打开你要制作镜像的文件,然后就开始自动处理,处理完成后会将结果保存为你选中文件名+.h的文件中。比如,下面就是我处理前面提到的 32MB 磁盘的结果。对于一个空的磁盘,只有6144Bytes的有效信息(当前其中仍然有大量的0x00字节)。 生成的 .h 有两部分: 1.磁盘扇区定义,这里是有内容(不全为0x00)的全部扇区;
2.扇区索引,用于索引上面的内容。
举例,当设备收到访问 n号扇区的命令后,需要在 Index[] 中查找,如果无法找到,那么可以直接返回这个删除内容为全 0x00;如果能找到,那么再从获得的索引值中查找具体内容。举例如下:收到访问 0x3扇区的请求,然后就比较 Index[] 中每一项的值,结果发现没有等于 0x03 的,那么就直接返回全0.使用十六进制工具可以看到,0x600-0x7FF是全0. 另外一个例子,设备收到对 0x280 扇区的访问,我们可以在Index[]中第八项找到这个值,那么我们接下来就需要访问 0x280*512=0x50000
实际查看到的内容如下,可以看出是和上面相同的。 第三步,编写代码。我们可以使用 TinyUSB 的RamDisk代码,稍加修改就可以得到我们需要的程序。关键代码有两个地方: 1.返回USB MSD基本信息,一个是扇区个数,一个是扇区大小。比如,下面扇区个数为DISK_BLOCK_NUM每个扇区大小为DISK_BLOCK_SIZE,同样使用这两个信息我们也能得知磁盘大小(二者相乘即可)
2.处理READ10命令,在tud_msc_read10_cb()这个函数。Windows会发送请求,要求返回lba 扇区 offset 处长度为 bufsize 的内容(实际上 offset 一直为0),bufsize是我们需要填充的 Buffer 大小(实际上一直是一个扇区的大小)
实验使用的是一款带有2个 TypeC 口的 ESP32S2 开发板(特别注意,这个开发板2个USB口 VCC 是相互连接的,因此如果是在同一台电脑上使用不会有什么问题,但是如果在2台不同的电脑上同时使用USB可能出现电压不匹配的问题) 之后就能在ESP32S2 的 USB口上看到多出来一个U盘了: 测试一下写入速度(当然,因为我们没有实际的存储设备,所有写入的数据实际上都被丢掉了),最快能达到800K/S。 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed