版本协议

GPL 3.0

标签
标准版
#第六届立创电赛#UEFI Shell 助手

创建时间:2年前

1204 1

视频

描述

<div class="document"> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">注:* 为必填项</p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><strong><span style="color: #0093e6;">请在报名阶段填写 ↓</span></strong></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 1、项目功能介绍</h3> <hr class="horizontal-splitline normal-bold-2"> <p><span>正常情况下,双机之间共享文件只是小事一桩,但是当我们身处</span> UEFI Shell <span>下面的时候,这就会变得非常麻烦。而这样的场景,对于开发</span> UEFI Shell Application<span>是非常常见的。通常只能每次编译之后使用</span>U<span>盘拷贝</span>EFI <span>文件到目标机上再执行。显而易见需要将</span>U<span>盘插来插去无法麻烦。之前我的解决方法是购买一个</span> USB<span>切换器,这样只用按键即可来回切换节省了插拔的动作。但是这样的方法仍然很麻烦,切换之后</span>U<span>盘可能无法识别。最终萌生了写一个辅助设备的想法。</span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*2、项目属性</h3> <hr class="horizontal-splitline normal-bold-2"> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">原创项目,首次公开</span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 3、开源协议</h3> <hr class="horizontal-splitline normal-bold-2"> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">GPL3.0开源协议</span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">注:利他即利己,请认真阅读下述内容。</span></p> <ol style="line-height: 1.8;"> <li class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-hanging-indent-1.6em" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">拥抱开源,赋予项目无限价值。建议项目核心功能开源80%以上;</span></li> <li class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-hanging-indent-1.6em" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">若某一部分功能不可替代且删掉之后项目无法解决对应的问题,则这一部分实现的功能就是项目的核心功能;比如设计了一台电子负载且设计了一款上位机软件监控功率变化,则电子负载为核心功能,上位机软件为辅助功能;比如电子负载中使用了一款隔离485模块与上位机通信,则此485模块实现的通讯功能为辅助功能;</span></li> <li class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-hanging-indent-1.6em" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">项目应选择适合自己的<span style="text-decoration: underline;"><a href="/posts/98fdb2accd754af7b51990790db3b47a" target="_blank">开源协议</a></span>,若项目引用其他开源项目,应注明来源并遵循原作者的开源协议规定;原创项目推荐使用GPL3.0开源协议;</span></li> <li class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-hanging-indent-1.6em" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">直接引用开源项目的原电路或原代码实现的功能不可作为自己项目的核心功能、使用市场上通用模块直接实现的功能不可作为自己项目的核心功能。</span></li> </ol> <p style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><strong><span style="color: #0093e6;">请在竞赛阶段填写 ↓</span></strong></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*4、硬件部分</h3> <hr class="horizontal-splitline normal-bold-2"> <p><span>最终的方案是:对于运行</span>UEFI Shell<span>的目标机,辅助设备将自身模拟为</span>U<span>盘,所有的</span> UEFI <span>都会支持这样的设备,就不必加载额外的驱动。同时模拟</span>U<span>盘上放置一个</span> UEFI Shell <span>的程序,这样对于没有内置</span> UEFI Shell <span>的目标机也会省去查找制作启动盘之苦。对于</span> UEFI Shell <span>的目标机,数据读写也是发生在</span>U<span>盘上的。另外一端,使用串口来进行通讯。</span></p> <p><span>选择的硬件是</span> ESP32 S2<span>,因为这款模块速度足够快,内存也挺大,支持</span> USB Device<span>,同时自带了</span>2MB <span>的</span>pSRAM<span>,这样我们可以将需要交换的数据放置在</span>pSRAM <span>上。串口芯片选择了</span> CH340B<span>,价格适中,最高波特率</span> 2,000,000<span>。同时</span>B <span>这个后缀的</span> CH340<span>内置了</span> eePROM <span>可以写入自定义的数据,这样方便我们直接编写自动识别串口的</span>Windows<span>端代码。</span></p> <p> </p> <p> </p> <p><span>为了达成目标,首先开始硬件电路的设计。</span></p> <p>1.ESP32-S2 <span>最小电路部分如下,</span>3.3V<span>供电,预留</span>GPIO0 <span>和</span>EN <span>两个按键用于下载(自动下载,一些特别情况才需要手工触发下载)。</span></p> <p> </p> <p><span><img src="//image.lceda.cn/pullimage/gM60uuOQRMsft4khFwte3xww4nGRB2g5e0lh4dd7.png" alt=""></span></p> <p>2<span>.</span> ASM1117 5V <span>转</span>3.3V <span>供电。</span></p> <p><span><img src="//image.lceda.cn/pullimage/WVzlF0qs6uyHj6gKFEXWjSwCcAMBsAv4EBZzJgzS.png" alt="" width="1146" height="673"></span></p> <p>3.CH340B USB<span>转串口,提供程序下载和</span>Windows<span>通讯功能。其中的</span>LED2 <span>是</span>CH340B <span>提供的状态灯,当有发送时,这个</span>LED<span>会亮。</span></p> <p><span><img src="//image.lceda.cn/pullimage/XlL3C0zhydcyLa8UEBKLN8NcBrUNEziP1lxxtNrS.png" alt="" width="1179" height="455"></span></p> <p>4.<span>下面的电路配合</span> CH340 <span>转出来的</span> DTR<span>和</span> RTS <span>实现自动下载的功能。</span></p> <p><span><img src="//image.lceda.cn/pullimage/gQ286C218hi1uWnefBY0dyFB1s1GqxkQpN6STPB8.png" alt=""></span></p> <p>5.<span>这是</span>U<span>盘端口的</span>USB-B <span>型母头接口。这里预留一个跳线,正常使用时,上面没有跳线,被测机和工作机</span>5V <span>是分开的,这是为了避免两者</span>5V <span>电压不同电流倒灌的情况。如果你想将这个设备当作启动</span> UEFI Shell<span>的</span>U<span>盘,可以将这里安装跳线。</span></p> <p><span><img src="//image.lceda.cn/pullimage/jUm7DXCdudvSeTucYs9olK7ozWtfsQDhO0BIK4kR.png" alt="" width="587" height="389"></span></p> <p>6.<span>最后是一个预留,用于</span> Debug <span>的串口。</span></p> <p><span><img src="//image.lceda.cn/pullimage/3Vw2OGQKymQLfZ4KhFFojlVcfy9gljlnYeD3Zk08.png" alt="" width="1300" height="552"></span></p> <p><span>最终</span> PCB <span>设计如下:</span></p> <p> <img src="//image.lceda.cn/pullimage/WtAPfB2b1obZfBrcKPRu4AUoYjKpfEjhxEfheFMd.png" alt="" width="494" height="740"></p> <p>3D <span>预览如下:</span></p> <p> <img src="//image.lceda.cn/pullimage/7g0iVFmSMA97r49StK8BPNpU9r9ipJHKGEyLqmza.png" alt="" width="650" height="821"></p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*5、软件部分</h3> <hr class="horizontal-splitline normal-bold-2"> <p><span>接下来就是软件设计了。</span></p> <p><span>首先,介绍一下连接被测机的</span>U<span>盘代码的设计。这里包含了</span>2<span>部分的功能,一个是模拟</span>U<span>盘,另外一个是和</span>pSRAM <span>的交互。</span></p> <p>1.      <span>模拟</span>U<span>盘。为了实现这个功能,首先制作一个磁盘镜像。具体方法是在</span> Disk Management <span>中使用</span> Create VHD <span>功能创建一个虚拟硬盘。</span></p> <p><img src="//image.lceda.cn/pullimage/C3H6kuyKtvfFngNYrSbEm2a6AwVtvQNDUV8JjmuP.png" alt="" width="417" height="420"></p> <p> </p> <p>        Create VHD</p> <p> </p> <p><img src="//image.lceda.cn/pullimage/Yqi3wo9VxgDUJEif84i5eqQufobBaITskGghwkWg.png" alt="" width="480" height="589"></p> <p>   <span>设定</span> 32MB <span>大小</span></p> <p><span>上述操作完成后,系统中就出现了一个</span> 32MB <span>大小的未格式化磁盘。</span></p> <p> </p> <p><img src="//image.lceda.cn/pullimage/6SagcH7jloG5pGpedmIV9b8zMcg5pM2jApJfqQHb.png" alt="" width="947" height="555"></p> <p><span>这里推荐使用</span> Disk Genius <span>来创建分区:</span>16MB GPT <span>分区,</span>FAT16  Sector512Bytes<span>。就是说,前面</span> 16MB <span>我们开启</span>FAT <span>分区暴露出来,后面</span> 16MB <span>的空间我们用其中的</span> 2MB<span>来作为数据交换空间使用。这样的好处是:</span></p> <p>1.<span>可以用作</span> UEFI <span>启动盘,我们也可以将一些工具直接放置在上面;</span></p> <p>2.<span>数据交换空间放在未分区的位置可以避免操作系统的缓存机制;</span></p> <p><img src="//image.lceda.cn/pullimage/ZH9eB5l4kEBfu48WeS3pTnhGkbJW8RnEwEC0RUuj.png" alt=""></p> <p><span>上述做好了之后我们需要将这个硬盘制作为镜像文件,这里使用一个免费软件</span> HxD<span>。特别注意需要用管理员权限启动。</span></p> <p><img src="//image.lceda.cn/pullimage/f3IdXiC2FTFSU57XjVS0OoYFSr1lfTJdo7bZ9jIA.png" alt=""></p> <p>Tools->Open Disk <span>中选择中这个磁盘</span></p> <p><img src="//image.lceda.cn/pullimage/9fGQleQyIW1iMD7sedeogr8nJwOBD6GsCsAeA0tZ.png" alt="" width="674" height="526"></p> <p><span>之后使用</span> File->Save As <span>保存为一个文件即可。</span></p> <p><img src="//image.lceda.cn/pullimage/Pk9KFv7LnVEXmDHLnZ0OyXeAORxNsyiygkTxRNmO.png" alt="" width="1066" height="474"></p> <p><span>通过这个磁盘镜像文件我们可以完整的模拟这个磁盘,当有读取命令到来时,我们可以根据命令中给出来的偏移返回文件中的内容即可。接下来的问题是:我们需要找到一种方法来进行“压缩”,因为这个镜像文件有</span>64MB <span>大小,而</span>ESP32 S2<span>只有</span>4MB <span>的空间。经过观察可以发现,镜像文件中大部分内容都是</span>00<span>,因此这里采用的方法是:以</span>512<span>字节为单位,用程序扫描生成的镜像文件,如果内容不为</span>0<span>就记录下来,否则抛弃。</span></p> <p> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt pap-left-indent-1.6em" style="line-height: 1.8;"><span>处理之后的结果是</span> .h <span>文件,其中有</span>2<span>个数组,一个是不同扇区的数据定义,示例如下:</span></p> <p>const unsigned char Sector[1704][512]  = {</p> <p>{</p> <p>//No. 0 Sector: 0x0</p> <p>0x33,0xC0,0x8E,0xD0,0xBC,0x00,0x7C,0x8E,0xC0,0x8E,0xD8,0xBE,0x00,0x7C,0xBF,0x00,</p> <p>0x06,0xB9,0x00,0x02,0xFC,0xF3,0xA4,0x50,0x68,0x1C,0x06,0xCB,0xFB,0xB9,0x04,0x00,</p> <p>0xBD,0xBE,0x07,0x80,0x7E,0x00,0x00,0x7C,0x0B,0x0F,0x85,0x0E,0x01,0x83,0xC5,0x10,</p> <p>0xE2,0xF1,0xCD,0x18,0x88,0x56,0x00,0x55,0xC6,0x46,0x11,0x05,0xC6,0x46,0x10,0x00,</p> <p>0xB4,0x41,0xBB,0xAA,0x55,0xCD,0x13,0x5D,0x72,0x0F,0x81,0xFB,0x55,0xAA,0x75,0x09,</p> <p>………….}</p> <p>………………</p> <p>{</p> <p>//No. 1702 Sector: 0xffff</p> <p>0x45,0x46,0x49,0x20,0x50,0x41,0x52,0x54,0x00,0x00,0x01,0x00,0x5C,0x00,0x00,0x00,</p> <p>0x2B,0xC1,0xF0,0x2A,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,</p> <p>0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,</p> <p>0xDE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x6F,0xFB,0x30,0xB9,0xEC,0x2D,0x4A,</p> <p>……..}};</p> <p><span>另外一个是扇区索引,例如:</span></p> <p>int SPIRomIndex[1703]= {0x0,0x1,0x2,0x80,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x101,0x102,0x103,0x104,0x105,0x106,</p> <p>0x107,0x180,0x1A0,0x1A1,0x1A2,0x1A3,0x1A4,0x1A5,0x1A6,0x1A7,0x1A8,0x1A9,0x1AA,0x1AB,0x1AC,0x10AD,0x1AE,</p> <p>0x1AF,0x1B0,0x1B1,0x1B2,0x1B3,0x1B4,0x1B5,0x1B6,0x1B7,0x1B8,0x1B9,0x1BA,0x1BB,0x1BC,0x1BD,0x1BE,0x1BF,</p> <p>0x1C0,0x1C1,0x1C2,0x1C3,0x1C4,0x1C5,0x1C6,0x1C7,0x1C8,0x1C9,0x1CA,0x1CB,0x1CC,0x1CD,0x1CE,0x1CF,0x1D0,</p> <p>……..}</p> <p><span>比如,当前命令要访问</span> 0 <span>号扇区,那么首先在</span>SPIRomIndex<span>中搜索</span> 0<span>,</span> <span>可以在第一个位置找到,意思是</span>Sector[0][512] <span>就是</span>0<span>号扇区的内容;例如,命令要求访问</span> 0x03 <span>扇区,而</span>SPIRomIndex[]<span>中没有等于</span>3<span>的值,因此直接返回全</span>0x00 <span>的数据即可;再例如,命令中要访问</span> 0x80 <span>扇区,而</span>SPIRomIndex[3]==0x80<span>,因此,我们需要的数据在</span>Sector[3] <span>中,通过这样的方法,我们在一个</span>4.4MB <span>的文件中,定义了</span> 32MB<span>磁盘镜像的数据。对应的代码是:</span></p> <p>int32_t IsInRomSector(uint32_t lba) {</p> <p>      for (int32_t i = 0; i < sizeof(SPIRomIndex)/sizeof(int); i++) {</p> <p>        if (lba == SPIRomIndex[i]) {</p> <p>          return i;</p> <p>        } else if (lba < SPIRomIndex[i]) {</p> <p>          return 0xFFFFFFFF;</p> <p>        }</p> <p>      }</p> <p>      return 0xFFFFFFFF;</p> <p>}</p> <p> </p> <p><span>另外,在</span> ESP32 S2 <span>中将对于</span>U<span>盘</span>32896 <span>到</span>32896+4094<span>扇区上的读写全部发送到</span> pSRAM<span>上。我们使用了</span> pSRAM <span>上第</span>2<span>个到</span>4094<span>个扇区用于存储数据,原因是</span>pSRAM<span>虽然有</span> 2MB <span>大小,但是起始和结尾处存在有用的数据,不能使用。因此,实际使用的</span> pSRAM <span>大小是</span> 2*1024*1024-2*512 <span>字节。这部分的代码如下:</span></p> <p>// Callback invoked when received READ10 command.</p> <p>// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.</p> <p>int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)</p> <p>{</p> <p>  (void) lun;</p> <p>  //uint8_t* addr = &msc_disk[lba * 512] + offset;</p> <p>  //memcpy(buffer, addr, bufsize);</p> <p>    log_v("read lba %X, offs: %d, bufs %d", lba, offset,bufsize);</p> <p>  if (lba==32896+4096) {</p> <p>      memset(buffer,0,512);</p> <p>      memcpy(buffer,&StoreInfo,sizeof(StoreInfo));</p> <p>      return bufsize;</p> <p>    }</p> <p>  // <span>如果读取发生在特定范围那么就在</span> psRam<span>上读取</span> </p> <p>  if ((lba<32896+4094)&&(lba>=32896)) {</p> <p>      memcpy(buffer,&psRam[(lba-32896)*512+512],bufsize);</p> <p>      return bufsize;</p> <p>    }</p> <p>  uint32_t SectorIndex = IsInRomSector(lba);</p> <p>  if (SectorIndex != 0xFFFFFFFF) {</p> <p>     memcpy(buffer, &Sector[SectorIndex][0], bufsize);</p> <p>     log_v("reply %d", SectorIndex);</p> <p>  } else {</p> <p>     memset(buffer,0, bufsize);</p> <p>     log_v("reply all 0");</p> <p>  }</p> <p> </p> <p>  return bufsize;</p> <p>}</p> <p> </p> <p>// Callback invoked when received WRITE10 command.</p> <p>// Process data in buffer to disk's storage and return number of written bytes</p> <p>int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)</p> <p>{</p> <p>  (void) lun;</p> <p> </p> <p>  if (lba==32896+4096) {</p> <p>      memcpy(&StoreInfo,buffer,sizeof(StoreInfo));</p> <p>      return bufsize;</p> <p>    }</p> <p>  // <span>如果写入发生在特定范围那么就在</span> psRam<span>上写入</span> </p> <p>  if ((lba<32896+4094)&&(lba>=32896)) {</p> <p>      memcpy(&psRam[(lba-32896)*512+512],buffer,bufsize);</p> <p>      return bufsize;</p> <p>    }   </p> <p> </p> <p>  return bufsize;</p> <p>}</p> <p><span>为了传输文件,设计一个结构体保存文件信息,定义如下</span>:</p> <p>typedef struct</p> <p>{</p> <p>  unsigned long Signatures;  // Offset:0-3 //"LABZ"</p> <p>  unsigned long length;      // Offset:4-7</p> <p>  char          ver[4];      // Offset:8-11</p> <p>  unsigned long mono;        // Offset:12-15</p> <p>  char          filename[32];//Offset:16-47</p> <p>  char          reserved[16];//Offset:48-63</p> <p>} StoreInfo_struct;</p> <p><span>其中包括了文件的大小,名称信息,此外还预留了</span> ver<span>作为版本信息,</span>mono<span>是预留的一个单增数值,二者目前还没有用途。这个结构体是放置在</span>ESP32 S2 <span>模拟</span>U<span>盘的</span>32896+4096=36,992<span>(偏移</span>  0x121 0000<span>)位置上的。在上面的代码中也可以看到对此的特殊处理。</span></p> <p><span>接下来介绍串口访问的设计,相对于前面</span>U<span>盘,这部分复杂得多,数据的收发都必须使用</span>Checksum<span>来进行校验。这部分的设计如下:</span></p> <p> </p> <p><span><img src="//image.lceda.cn/pullimage/UAyQJq4IzlyddmNnpZ7K2wsfclfb1brxS2ORJtuU.png" alt=""></span></p> <p><span>命令</span> 0x55: ESP32 S2<span>接收数据,收到后进行</span> Checksum <span>校验,校验方法是:全部数据(</span>4K+2Bytes<span>)相加后结果应该为</span>0<span>;</span></p> <p><span>命令</span> 0xAA: ESP32 S2<span>发送数据,数据是</span> 4K + 2Byte<span>的</span> Checksum</p> <p><span>命令</span>VRS<span>:</span>ESP32 S2<span>返回当前的版本信息</span></p> <p><span>命令</span> 0x808080: ESP32 S2 <span>发送当前的</span> StoreInfo_struct <span>结构体给上位机</span></p> <p><span>命令</span> 0x808080:<span>上位机发送当前的</span> StoreInfo_struct <span>结构体给</span>ESP32 S2</p> <p> </p> <p><span>所有的命令加参数都是</span>3 Bytes <span>长度,上位机发送命令后,需要</span>ESP32S2<span>回复收到的命令,比如相同后才能继续(因为我发现一些情况下</span>ESP32 S2 <span>收到的命令和发送出去的不同),代码如下:</span></p> <p>// <span>接收命令,如果超时返回全</span> 0xFF</p> <p>void receiveCMD() {</p> <p>  if (Serial.available() != 0) {</p> <p>    if (DEBUGMODE) {</p> <p>      Serial1.println(Serial.available());</p> <p>    }</p> <p>  }</p> <p>  if (Serial.available() >= CMD_MAX) {</p> <p>    Serial.readBytes(CMD, CMD_MAX);</p> <p> </p> <p>    if (DEBUGMODE) {</p> <p>      Serial1.println("Get CMD_MAX");</p> <p>    }</p> <p>    if (DEBUGMODE) {</p> <p>      Serial1.print("rcvBuffer[i]: ");</p> <p>    }</p> <p>    // <span>重新将命令发回上位机,等待确认</span></p> <p>    for (int i = 0; i < CMD_MAX; i++) {</p> <p>      Serial.write(CMD[i]);</p> <p>      if (DEBUGMODE) {</p> <p>        Serial1.print((char)CMD[i]);</p> <p>      }</p> <p>    }</p> <p>    if (DEBUGMODE) {</p> <p>      Serial1.println("");</p> <p>    }</p> <p>    if (upperConfirm() != true) {</p> <p>      memset(CMD, 0xFF, CMD_MAX);</p> <p>      return ;</p> <p>    }</p> <p> </p> <p>    // <span>到这里表示正常</span></p> <p>  } else {</p> <p>    //<span>超时返回全</span> 0xFF</p> <p>    memset(CMD, 0xFF, CMD_MAX);</p> <p>  }</p> <p> </p> <p>  return ;</p> <p>}</p> <p><span>总结一下,如果你想制作一个同样的设备,需要如下步骤:</span></p> <p>1.      <span>制作</span> PCB</p> <p>2.      <span>焊接</span></p> <p>3.      Arduino <span>烧写</span> ESP32 <span>代码</span></p> <p>4.      <span>烧写</span> CH340B  EEPROM</p> <p>5.      USB A <span>公头端是</span> COM <span>转</span> USB <span>设备,用于</span>Windows <span>主机使用串口通讯程序发送</span>/<span>接收数据</span></p> <p>6.      USB B <span>母头端是</span> USB MSD <span>设备,用于</span> UEFI Shell <span>发送</span>/<span>接收数据</span></p> <p> </p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*6、BOM清单</h3> <hr class="horizontal-splitline normal-bold-2"> <table style="border-collapse: collapse; width: 480pt;" width="640"> <tr style="height: 14.4pt;"> <td style="height: 14.4pt; width: 48pt;" width="64" height="19">ID</td> <td style="width: 48pt;" width="64">Name</td> <td style="width: 48pt;" width="64">Designator</td> <td style="width: 48pt;" width="64">Footprint</td> <td style="width: 48pt;" width="64">Quantity</td> <td style="width: 48pt;" width="64">Manufacturer Part</td> <td style="width: 48pt;" width="64">Manufacturer</td> <td style="width: 48pt;" width="64">Supplier</td> <td style="width: 48pt;" width="64">Supplier Part</td> <td style="width: 48pt;" width="64">Price</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">1</td> <td>10uf</td> <td>C1,C7,C8</td> <td>C1206</td> <td align="right">3</td> <td>CC1206JRNPOBBN270</td> <td>YAGEO</td> <td>LCSC</td> <td>C326944</td> <td align="right">0.1755</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">2</td> <td>0.1uf</td> <td>C2,C3,C4,C9,C10</td> <td>C1206</td> <td align="right">5</td> <td>CC1206JRNPOBBN270</td> <td>YAGEO</td> <td>LCSC</td> <td>C326944</td> <td align="right">0.1755</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">3</td> <td>EN</td> <td>EN</td> <td>SW-SMD_L4.0-W2.9-LS5.0</td> <td align="right">1</td> <td>TS342A2P-WZ</td> <td>SHOU HAN</td> <td>LCSC</td> <td>C557591</td> <td align="right">0.25</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">4</td> <td>BSMD1206-050-6V</td> <td>F1</td> <td>F1206</td> <td align="right">1</td> <td>BSMD1206-050-6V</td> <td>BHFUSE</td> <td>LCSC</td> <td>C883122</td> <td align="right">0.1895</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">5</td> <td>GPIO0</td> <td>GPIO0</td> <td>SW-SMD_L4.0-W2.9-LS5.0</td> <td align="right">1</td> <td>TS342A2P-WZ</td> <td>SHOU HAN</td> <td>LCSC</td> <td>C557591</td> <td align="right">0.25</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">6</td> <td>204-10SURT/S530-A3</td> <td>LED1,LED2,LED3</td> <td>LED-TH_BD4.3-P2.54</td> <td align="right">3</td> <td>204-10SURT/S530-A3</td> <td>Everlight Elec</td> <td>LCSC</td> <td>C282135</td> <td align="right">0.2304</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">7</td> <td>SW UART</td> <td>P1</td> <td>HDR-TH_3P-P2.54-V-F</td> <td align="right">1</td> <td>Header-Female-2.54_1x3</td> <td>Boom Precision Elec</td> <td>LCSC</td> <td>C146243</td> <td align="right">0.3032</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">8</td> <td>SS8050_C2150</td> <td>Q1,Q2</td> <td>SOT-23-3_L2.9-W1.3-P1.90-LS2.4-BR</td> <td align="right">2</td> <td>SS8050</td> <td>CJ</td> <td>LCSC</td> <td>C2150</td> <td align="right">0.1238</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">9</td> <td>10K</td> <td>R1,R2,R3,R4</td> <td>R1206</td> <td align="right">4</td> <td>AECR1206F120KK9</td> <td>ResistorToday</td> <td>LCSC</td> <td>C352156</td> <td align="right">0.0443</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">10</td> <td>3.3K</td> <td>R5,R6,R7</td> <td>R1206</td> <td align="right">3</td> <td>PTFR1206B10K0P9</td> <td>ResistorToday</td> <td>LCSC</td> <td>C351536</td> <td align="right">1.0474</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">11</td> <td>ESP32-S2-WROVER(4MB)</td> <td>U1</td> <td>WIFI-SMD_ESP32-S2-WROVER-I</td> <td align="right">1</td> <td>ESP32-S2-WROVER(4MB)</td> <td>Espressif Systems</td> <td>LCSC</td> <td>C701333</td> <td align="right">20.47</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">12</td> <td>AMS1117-3.3</td> <td>U2</td> <td>SOT-223</td> <td align="right">1</td> <td>AMS1117-3.3</td> <td>AMS</td> <td>LCSC</td> <td>C6186</td> <td align="right">1.5243</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">13</td> <td>CH340B</td> <td>U3</td> <td>SOIC-16_L9.9-W3.9-P1.27-LS6.0-BL</td> <td align="right">1</td> <td>CH340B</td> <td>WCH</td> <td>LCSC</td> <td>C81010</td> <td align="right">7.26</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">14</td> <td>U-B-M4DD-W-1</td> <td>USB1</td> <td>USB-B-TH_U-B-M4DD-W-1</td> <td align="right">1</td> <td>U-B-M4DD-W-1</td> <td>Korean Hroparts Elec</td> <td>LCSC</td> <td>C530600</td> <td align="right">2.04</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">15</td> <td>USB-212-BCW</td> <td>USB2</td> <td>USB-A-SMD_USB-212-BCW</td> <td align="right">1</td> <td>USB-212-BCW</td> <td>XUNPU</td> <td>LCSC</td> <td>C720521</td> <td align="right">0.4174</td> </tr> <tr style="height: 14.4pt;"> <td style="height: 14.4pt;" align="right" height="19">16</td> <td>1x2</td> <td>USB_POWER1,USB_POWER2</td> <td>HDR-TH_2P-P2.54-V</td> <td align="right">2</td> <td>826629-2</td> <td>TE Connectivity</td> <td>LCSC</td> <td>C86471</td> <td align="right">0.6015</td> </tr> </table> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">注:项目涉及的BOM清单。这个位置请上传BOM的截图。清单详情请以PDF的格式上传到附件中。建议包括型号、品牌、名称、封装、采购渠道、用途等内容。具体内容和形式应以表达清楚项目构成为准。</span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">*7、大赛LOGO验证</h3> <hr class="horizontal-splitline normal-bold-2"> <p style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><img src="//image.lceda.cn/pullimage/Kfek2kgPDjYzHAv2VKoVbOgW9qJWb0LCrnviptiS.jpeg" alt="正面" width="1382" height="1036"></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><img src="//image.lceda.cn/pullimage/Xn3rxM1ABdy0Tbs5M2MawJhxLXpFgCFUKQ3tifr2.jpeg" alt="背面" width="1094" height="820"></p> <h3 class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;">* 8、演示您的项目并录制成视频上传</h3> <hr class="horizontal-splitline normal-bold-2"> <p style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">视频要求:请横屏拍摄,分辨率不低于1280×720,格式Mp4/Mov,单个视频大小限100M内;</span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="color: #95a5a6; font-size: 14px;">视频标题:立创电赛:{项目名称}-{视频模块名称};如立创电赛:《自动驾驶》-团队介绍。</span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"><span style="font-size: 14px;">更多详情:<a href="/posts/06c94d90c2c447dfbd9ed7339ff4a5b1" target="_blank">https://diy.szlcsc.com/posts/06c94d90c2c447dfbd9ed7339ff4a5b1</a></span></p> <p class="paragraph text-align-type-left pap-line-1.3 pap-line-rule-auto pap-spacing-before-3pt pap-spacing-after-3pt" style="line-height: 1.8;"> </p> </div>

文档

BOM

暂无

附件

暂无

评论(2)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
立创电赛 回复
<p> 记得上传logo验证图片哟~</p>
Zoologist 回复
<p>@LCDS  刚才上传了</p>
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow