ESP32 S2 上实现假U盘-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1081|回复: 4

ESP32 S2 上实现假U盘

[复制链接]
发表于 2022-3-4 16:59 | 显示全部楼层 |阅读模式
这次介绍的是在 Arduino 1.8.16 + ESP32 2.0.1 下实现假U盘的例子。特别强调:ESP32 Arduino 环境必须是 2.0.1, 更高的版本反倒有兼容问题。
u.png
实现的方法和之前的相同【参考1】:
1.     首先在本机做一个虚拟的256MB硬盘,然后在上面放置一个 200MB 的内容为全0x00的文件(太大的话,处理起来非常麻烦);
2.     将这个硬盘使用HXD做成镜像文件,然后使用工具扫描这个文件,将所有的不为0的内容写入.h文件中(这就是256MBDisk.bin.h文件的来源);
3.     这个文件中0x804到 0x8CC扇区内容,和0x902到 0x9CA扇区内容相同,因此在数组中删除后者内容,当有到这个扇区的请求时,用前者的内容替代,这样可以大大缩减编译后文件的体积;
4.     在代码中响应 onRead(),如果请求的LBA在.h文件中,就进行Buffer的填充;
5.     插入过程 Windows 有写入操作,因此必须响应 onWrite

完整代码如下:

  1. #include "USB.h"
  2. #include "USBMSC.h"
  3. #include "256MBDisk.h"

  4. #if ARDUINO_USB_CDC_ON_BOOT
  5. #define HWSerial Serial0
  6. #define USBSerial Serial
  7. #else
  8. #define HWSerial Serial
  9. //USBCDC USBSerial;
  10. #endif

  11. USBMSC MSC;

  12. uint32_t findLBA(uint32_t LBA) {
  13.   for (uint32_t i=0; i<415;i++) {
  14.       if (Index[i]==LBA) {
  15.           if (i>=205) {i=i-205+4;}
  16.           return i;
  17.         }
  18.     }
  19.   return 0xFFFFFF;  
  20. }
  21. static const uint32_t DISK_SECTOR_COUNT = 520192;

  22. static int32_t onRead(uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize){
  23.   //HWSerial.printf("MSC READ: lba: %u, offset: %u, bufsize: %u\n", lba, offset, bufsize);

  24.   uint32_t getLBA=0;
  25.   uint8_t *p;
  26.   p=(uint8_t *)buffer;
  27.   //HWSerial.printf("Buffer1 %X\n", buffer);
  28.   for (uint32_t i=0;i<bufsize/DISK_SECTOR_SIZE;i++) {
  29.      //HWSerial.printf("Check %u\n", lba+i);
  30.      getLBA=findLBA(lba+i);
  31.      //HWSerial.printf("getLBA %u %u\n", getLBA,lba+i);
  32.      if (getLBA!=0xFFFFFF) { //如果找到了
  33.         memcpy((void *)&p[i*DISK_SECTOR_SIZE], &msc_disk[getLBA][0], DISK_SECTOR_SIZE);
  34.         //HWSerial.printf("%u %u %u %u\n", msc_disk[getLBA][0],msc_disk[getLBA][1],msc_disk[getLBA][2],msc_disk[getLBA][3]);
  35.         //HWSerial.printf("Send %u\n", getLBA);
  36.         //HWSerial.printf("Buffer2 %X\n", (void *)&p[i*DISK_SECTOR_SIZE]);
  37.       } else {
  38.        //HWSerial.printf("Send all zero to %u\n", getLBA);
  39.         for (uint16_t j=0;j<DISK_SECTOR_SIZE;j++) {
  40.               p[i*DISK_SECTOR_SIZE+j]=0;
  41.           }
  42.          
  43.       }
  44.     }
  45.   return bufsize;
  46. }

  47. static bool onStartStop(uint8_t power_condition, bool start, bool load_eject){
  48.   HWSerial.printf("MSC START/STOP: power: %u, start: %u, eject: %u\n", power_condition, start, load_eject);
  49.   return true;
  50. }

  51. static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
  52.   if(event_base == ARDUINO_USB_EVENTS){
  53.     arduino_usb_event_data_t * data = (arduino_usb_event_data_t*)event_data;
  54.     switch (event_id){
  55.       case ARDUINO_USB_STARTED_EVENT:
  56.         HWSerial.println("USB PLUGGED");
  57.         break;
  58.       case ARDUINO_USB_STOPPED_EVENT:
  59.         HWSerial.println("USB UNPLUGGED");
  60.         break;
  61.       case ARDUINO_USB_SUSPEND_EVENT:
  62.         HWSerial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en);
  63.         break;
  64.       case ARDUINO_USB_RESUME_EVENT:
  65.         HWSerial.println("USB RESUMED");
  66.         break;
  67.       
  68.       default:
  69.         break;
  70.     }
  71.   }
  72. }

  73. static int32_t onWrite(uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){
  74.   HWSerial.printf("MSC WRITE: lba: %u, offset: %u, bufsize: %u\n", lba, offset, bufsize);
  75.   return bufsize;
  76. }
  77. void setup() {
  78.   HWSerial.begin(115200);
  79.   HWSerial.setDebugOutput(true);

  80.   USB.onEvent(usbEventCallback);
  81.   MSC.vendorID("ESP32");//max 8 chars
  82.   MSC.productID("USB_MSC");//max 16 chars
  83.   MSC.productRevision("1.02");//max 4 chars
  84.   MSC.onStartStop(onStartStop);
  85.   MSC.onRead(onRead);
  86.   MSC.onWrite(onWrite);
  87.   MSC.mediaPresent(true);
  88.   MSC.begin(DISK_SECTOR_COUNT, DISK_SECTOR_SIZE);
  89.   //USBSerial.begin();
  90.   USB.begin();
  91. }

  92. void loop() {
  93.   // put your main code here, to run repeatedly:
  94. }
复制代码
u2.png u3.png




参考:
1.     https://mc.dfrobot.com.cn/thread-309859-1-1.htmlESP32 S2 做一个假U盘



 楼主| 发表于 2022-3-4 17:03 | 显示全部楼层
实验用到的硬盘镜像文件
256MB.zip (486.97 KB, 下载次数: 2)

本文提到的完整代码(一个是有手工压缩的,一个是没有手工压缩的)
ESP32S2256DSK_compress.zip (79.02 KB, 下载次数: 4) ESP32S2256DSK_FullSize.zip (149.1 KB, 下载次数: 5)

发表于 2022-3-5 18:13 | 显示全部楼层
这个有意思!
 楼主| 发表于 2022-3-6 06:48 | 显示全部楼层

最近 esp32 的 arduino 支持库 usb 部分一直在改动,挺头疼的
发表于 2022-3-7 13:55 | 显示全部楼层
Zoologist 发表于 2022-3-6 06:48
最近 esp32 的 arduino 支持库 usb 部分一直在改动,挺头疼的

那就先不管他,等着稳定版
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:23 , Processed in 0.114146 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表