Arduino USB Host Shield PL2302 Debug Message

问题:当我运行USB Host Shield Library 中关于 Pl2303 的例子(比如 pl2303_gprs_terminal)的时候,在串口会有下面的 Debug 信息:

Start
0000: 09 02 27 00 01 01 00 80 32 09 04 00 00 03 FF 00 
0010: 00 00 07 05 81 03 0A 00 01 07 05 02 02 40 00 00 
0020: 07 05 83 02 40 00 00

经过研究,产生的位置在  Usb.cpp 下面函数中

uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) {

下面这个代码处:

// Invoke callback function if inTransfer completed successfully and callback function pointer is specified
   if(!rcode && p)
     ((USBReadParser*)p)->Parse(read, dataptr, total - left);

但是很明显,这里是调用设定的 callback 函数。

经过查找,最终确定实际生效的代码是hexdump.h 文件中下面的代码:

template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset __attribute__((unused))) {
        if(UsbDEBUGlvl >= 0x80) { // Fully bypass this block of code if we do not debug.
                for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
                        if(!byteCount) {
                                PrintHex<OFFSET_TYPE > (byteTotal, 0x80);
                                E_Notify(PSTR(": "), 0x80);
                        }
                        PrintHex<uint8_t > (pbuf[j], 0x80);
                        E_Notify(PSTR(" "), 0x80);

                        if(byteCount == 15) {
                                E_Notify(PSTR("\r\n"), 0x80);
                                byteCount = 0xFF;
                        }
                }
        }
}

因为其他地方对 UsbDEBUGlvl 赋值为 0x80,所以会输出一下信息用于Debug。

最近阅读 USB Host Shield 感觉风格不是很统一,比如,用于 Debug 的定义开关有很多处,估计是因为后来的代码是很多人合作的结果。

参考:

1.http://www.lab-z.com/atu9/

Windows10 Lite 版本

最近下载了一个 Win 10 lite 版本,专门用在虚拟机中配合 PHM 查看 Log (我不建议在工作机上安装 PHM ,因为在安装过程中会安装后一些服务会拖慢系统,导致系统降低,因此建议大家用额外的机器安装PHM 查看Log)。镜像来自下面的链接:

https://www.majorgeeks.com/files/details/windows_10_lite.html

这个版本具体的参数如下:

Technical Setup Details

Full NameWindows 10 Lite
Full Setup Size2.4 GB (For 32 Bit), 2.6 GB (For 64 Bit)
CompatibilityCompatible with 32 Bit (x86) / 64 Bit (x64)
Setup TypeOffline Installer / Full Standalone Setup
DevelopersMicrosoft

Minimum System Requirements

Memory (RAM)Minimum 1 GB
HDD (Hard Disk Drive)Minimum 16 GB Free Space Required
ProcessorIntel Pentium 4 Or Advance

在虚拟机中安装之后,还需要安装微软的 Edge 浏览器,之后就可以正常使用PHM。

虚拟机中的 Win10 Lite

链接: https://pan.baidu.com/s/1vlYXOvFDoDgfEBvbQKJ0-w 提取码: h6hn

参考:

1.https://www.lab-z.com/phm/ PowerHouse Mountain 的安装

ESP32 上使用 USB Host Mini

之前介绍过祖国版的 USB Host Mini 【参考1】,这里介绍一些如何在 ESP32 上使用USB Host 功能。试验的板子是 DFRobot 的 FireBeelte:

来自【参考2】

USB  Host Mini 上有24个Pin, 但是实际用到的只有9个,按照下图将它和 FireBeelte 接起来即可:

USB Host Library 直接兼容 ES32 ,. 建议先运行 例子中的Board_QC 来验证板子是否工作正常。

下面是取得 USB 描述符的例子运行结果:

=========================================================

20201027 补充在 ESP32-WROOM-32 上的实验

连接方式:

库中代码修改:

1.USB_Host_Shield_Library_2.0\avrpins.h

// Pinout for ESP32 dev module

MAKE_PIN(P0, 0);
MAKE_PIN(P1, 1); // TX0
MAKE_PIN(P10, 10); // TX1
MAKE_PIN(P3, 3); // RX0
MAKE_PIN(P21, 21); // SDA
MAKE_PIN(P22, 22); // SCL
MAKE_PIN(P19, 19); // MISO
MAKE_PIN(P23, 23); // MOSI
MAKE_PIN(P18, 18); // SCK
//LabZ_Start
MAKE_PIN(P13, 13); // SS
MAKE_PIN(P26, 26); // INT
//LabZ_End

2.USB_Host_Shield_Library_2.0\UsbCore.h

#elif defined(ESP8266)
typedef MAX3421e&lt;P15, P5> MAX3421E; // ESP8266 boards
#elif defined(ESP32)
//LABZ_Debug typedef MAX3421e&lt;P5, P17> MAX3421E; // ESP32 boards
typedef MAX3421e&lt;P13, P26> MAX3421E; // ESP32 boards  //LABZ_Debug
#else
typedef MAX3421e&lt;P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560, Leonardo, Due etc.), Intel Edison, Intel Galileo 2 or Teensy 2.0 and 3.x
#endif

3.USB_Host_Shield_Library_2.0\usbhost.h

#elif defined(ESP8266)
typedef SPi&lt; P14, P13, P12, P15 > spi;
#elif defined(ESP32)
//LABZ_Debug typedef SPi&lt; P18, P23, P19, P5 > spi;
typedef SPi&lt; P18, P23, P19, P13 > spi; //LABZ_Debug 
#else
#error "No SPI entry in usbhost.h"
#endif

参考:

  1. https://www.lab-z.com/cuhm/
  2. http://wiki.dfrobot.com.cn/index.php?title=%E6%96%87%E4%BB%B6:DFR0478%E5%BC%95%E8%84%9A%E5%9B%BE01.png

WPA 的安装

WPA 是 Windows Performance Analyzer的缩写,主要用途是用来分析代码性能【参考1】。在Debug Modern Standby S0 相关问题的时候非常有用,比如:​它可以告诉你谁在占用 CPU 使其处于S0状态,或者哪个中断将CPU 唤醒到S0。本文介绍一下这个工具的安装:

  1. 这个工具在 SDK 中,另外在ADK 中也有。

 2.选择路径

3.选择不要发送

4.选中 “Windows Performance Toolkit” 这就是我们需要的 WPA。从提示可以看出,其中包括 Windows Performance Recorder (记录器),Windows Performance Analyzer (分析器)和 Xperf (分析单个程序性能的工具)

5.下面只需要等待安装完成即可

6.输入 WPA 即可启用

如果你系统中有 WPA,但是无法打开 etl 那么请检查你安装的版本是否和 etl 的相匹配。

参考:

1. https://docs.microsoft.com/en-us/windows-hardware/test/wpt/windows-performance-analyzer

Arduino ESP32 安装指南

理论上 Arduino 支持 ESP32 的主控板是非常简单的事情,在IDE 中操作就可以了。但是因为众所周知的原因经常会出现错误,这里就介绍一下另外的方法。

  1. 在首选项中“附加开发板管理器网址”中加入下面这个网址:

https://dl.espressif.com/dl/package_esp32_index.json

2.这里设置好之后可以直接到开发板管理器中搜索 ESP32,如果能够正常搜索到ESP32,然后顺利完成下载,那么久无需阅读下面部分。

上面Step2 失败,出现错误,需要手工操作如下:

A. 将 package_esp32_index.json 放在C:\Users\[用户名]\AppData\Local\Arduino15 下面。比如,我当前登录账号是 Administrator ,name 对应路径是

C:\Users\Administrator\AppData\Local\Arduino15;

B. 找到 C:\Users\[用户名]\AppData\Local\Arduino15\preferences.txt 文件中的下面两行修改为:

target_package=esp32
target_platform=esp32

C. 再次来到开发板管理器中,同样会出错,但是这次可以搜索到 esp32 的开发板了

D. 在安装之前,将开发板Package和编译工具放置在下面的路径下:

C:\Users\[用户名Data\Local\Arduino15\staging\packages

E.选择你需要的版本,即可安装

F. 从原理上将,Step A告诉Arduino 我要加入新板子,新板子的描述在 一个JSON文件中。Arduino 会根据描述在开发板管理器中加入这个板子的型号,同时尝试去JSON文件给出的网址下载开发包等等工具,同时因为 JSON 文件给出了这些文件的 Checksum,当 Arduino 发现目录下存在对应的文件后,不会再次下载而是会去校验,校验结果Pass即可继续安装,从而顺利完成 Arduino ESP32的安装。

所以上述动作能够“骗过” Arduino 在没有网络下载的情况下正常安装。

本文提到的安装包有如下文件

esp32-1.0.0.zip
esp32-1.0.1.zip
esp32-1.0.2.zip
esp32-1.0.3.zip
esp32-1.0.4.zip
esptool-2.3.1-windows.zip
esptool-2.6.0-windows.zip
esptool-2.6.1-windows.zip
mkspiffs-0.2.3-arduino-esp32-win32.zip
xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip

可以在这里下载链接:https://pan.baidu.com/s/19GoaTbeSAGZ4ourMcWiCOg

提取码:sxsr

SystemInfo命令

这个命令能够显示计算机及其操作系统的详细配置信息,包括操作系统配置、安全信息、产品 ID 和硬件属性,如 RAM、磁盘空间和网卡和补丁信息等。比如,有人希望你确认操作系统版本信息,除了使用 WinVer, 还可以试试这个命令。例如,运行结果如下:

此外,还可以直接显示需要的结果,比如直接获得系统型号,可以和 findstr 配合使用

特别注意:很多资料说可以使用 find,但是根据我的实验,这条指令在中文操作系统下无法正常工作,推荐使用 findstr。

通过这样的工具,如果下次有人需要你提供当前版本信息,可以直接生成全部信息提供给他了。

参考:

  1. https://www.cnblogs.com/sfccl/p/12344416.html win10系统systeminfo命令的过滤用法
  2. https://baike.baidu.com/item/systeminfo systeminfo

制作一个 WinPE 启动盘

FAT32 分区存在着单个文件无法大于4G的限制,NTFS分区存在着无法启动的限制。将U盘制作成具有分别是FAT32和NTFS格式的分区可以结合二者优点避免上述限制。下面介绍一下具体制作方法。因为 Windows不支持对U盘分区,所以需要使用第三方工具,这里推荐 DiskGenius。官方网站 http://www.diskgenius.cn/

  1. 准备一个U盘,越大越好。
  2. 使用DiskGenius打开U盘,首先删除之前U盘上的分区,下面是一个14G的U盘

3, 选择新建分区,出现下面的画面,选择取消

4. 接下来新建第一个分区,注意需要设置为 NTFS 分区,我这边分配给他 13G

操作之后U盘分配如下

5.接下来继续在空闲的空间建立分区

这次选择 FAT32 格式,大小为1GB

之后,U盘空间分配如下

6.保存更改,工具会提示是否格式化,选择是自动格式化。

7. 经过这样的处理后U盘上有两个分区,分别是 NTFS 和 FAT32。对于 Win7 Win8 和 Win10 早期版本,只能看到 NTFS 分区,后面的FAT32分区是不可见的。

8. 继续使用 DiskGenuis, 选中U盘第二个分区,使用“浏览文件”

9.解压之前的 WinPELABZ.ISO, 将解压后的文件拖到第二个分区中。这个ISO是450MB大小,因此理论上只要分区大于这个值都可以放进去。同样的,如果你有其他的工具,比如DISM++,可以使用同样的方法放在这个分区上。

10.拷贝完成后即制作完成。

11.在启动时,调出 Boot Menu 选择从这个U盘启动即可。

在使用的时候,可以将硬盘镜像存放在 NTFS 格式的分区上,这样用一个U盘就能完成系统的恢复或者备份,非常方便。

ModernStandby调试的准备

《人月神话》是一本软件工程的著名书籍。其中“人月”的是一种表示劳动时间的计量单位。比如,一个软件需要3个人5个月来完成,这个软件的工作量就可以描述为 3*5=15人月。当然,因为软件设计是复杂的思维劳动,用上面的衡量办法很可能出现下面这样的推理:一头猪五个月下五个仔,换算下来一个猪仔相当于一个猪月,那么如果需要十个猪仔只需要十头猪一个月即可…….

其中的一章名称是“没有银弹”。“银弹”这个词来源于欧洲中世纪的传说。说的是狼人这样的怪物,一般的子弹是打不死它的。必须使用银子做的子弹才能杀死它。(说道这里我忽然发觉这个词听起来充满了贵族气息,比如月光下帅气的男主角从容的掏出手枪,装上散发出银色光芒的子弹然后射死怪物;相比之下国产的盗墓小说提到的对付“大粽子”的墨线糯米还有黑驴蹄子则充满了乡土气息……)后来“银弹”这个词就被用来形容,那些特别有效果、一用就很灵的方法。这章节 “没有银弹”的意思是,软件工程是一个超级复杂系统,没有任何特效的方法,可以一直提高效率。在Debug Modern Standby 的时候同样 “没有银弹” 。需要有足够的心理预期,因为整个过程可能会拉的很长有很多试验需要进行,必须保持足够的耐心。最常见的问题是在Debug 过程中因为灵光一闪而进行跳跃试验,漏掉一些因素最终导致数据和结论相互矛盾。因此,建议在上手的时候保持足够的耐心和勇气,尽量不厌其烦的将试验和条件逐一记录下来。

在动手之前,请保证如下事宜:

  1. 有一台能够进行参考的系统,最好是Intel RVP。在出现进入 MS死机或者重启时,可以非常有效的比对出当前是HW还是FW 问题。如果出现HW工程师开始研究FW设定,然后FW工程师反复研究电路图,通常意味着问题已经进入了死胡同;
  2. 在干净的系统上进行试验。这里的干净系统指的是只包括Windows和BKC驱动的系统。比如,XX电脑管家可能会导致系统无法进入MS,爱奇艺的存在也会影响进入 MS;
  3. 使用已经验证过的,确定支持 MS 的外围设备,特别是硬盘。作为工程师我们只能解决自己设计上的问题,无法解决部件的问题。特别是硬盘这种外观型号能够完全一致但是内部 FW版本不同的部件。另外,用具体试验来作为认定一些部件有问题是非常有说服力同时容易让人接受的。比如,硬盘是进入 MS 的关键部件,Intel SoC 无法兼容UMIS的 NVME 和FORESEE的SSD会让系统Block在 PC2;
  4. 进行测试时请拔掉USB设备,包括键盘鼠标和 Hub,理论上这些都不会影响MS,唯一的问题是你不知道你手上的是不是不影响MS的;
  5. 显示器可能会影响进入 MS。我听说过这样的事情,但是并没有亲见,如果有条件建议多用几个显示器试验;
  6. 检查所有的 GPIO 设定。最好让 HW 提供GPIO 设定的表格,虽然他们通常并不情愿,但是这个确实应该他们做,只有他们才能深刻的理解每一根GPIO的功能。设定之后在 Windows下用 GPIO 工具导出最终结果然后检查是否和HW设定匹配。我不认为有“高级错误” 和“低级错误”的差别。但是你可以想象当你和老板解释为什么某个问题花费了3周才能解决时,“GPIO设定错误”和“Intel 给出来的 PMC 有Bug,结果他们用了二十多天在我们不停的催促下才给出了更新的版本”哪种解释更容易让他接受;
  7. 如果设计有 ThunderBolt/TCSS ,务必请 HW保证设计同 RVP 相同,理论上用任何GPIO都是可行的,但是因为涉及到诸多的 FW 你无法保证其中能够配合你的设计。之前我碰到过一个 Camera 模块一直无法点亮,HW 测量表明对应的 MIPI Clock 频率不正确,在我研究三天无果焦头烂额甚至找不到能够配置频率的寄存器后,驱动工程师承认他在驱动中Hard Code成固定的频率;
  8. 尽量关闭BIOS中的安全相关的设定,比如:Secure Boot。因为这些项目可能会影响测试软件以及测试结果。当然如果试验发现确实会这样,后面找 Intel 来解决就好了(这也意味着其他家会有同样的问题,不用担心);
  9. 不要连接互联网。这句话的意思是:从安装系统开始,可以连接局域网,但是必须保证没有连接到互联网上。 Windows 后台有升级操作,但是你不知道的动作和进度。我碰到过多次工作正常的系统在连接一次互联网之后就变得不稳定,明确的结果能够给我们明确的方向,不稳定的结果非常有可能误导我们。
  10. 建议在开始之前关闭 RTD3 功能,这个功能对省电有帮助,但是 MS 没有帮助。在项目开始的时候,Codebase 中的 RTD3 设定的 GPIO 和你项目硬件设定不符有可能导致奇怪的问题;
  11. 可以多用用全盘镜像的工具,比如:Macrium Reflect 【参考1】,这样可以及时发现因为驱动更新导致的问题;

当上述工作完成后,就可以开始进行 Debug 了, 具体的方法就是运行 Power House Mountain 然后查看结果。具体有如下操作:

  1. 如果Sleep MS 的时候有异常重启,可以通过BIOS设定 CPU C-Status Limitation的方式来判断是否和MS相关。比如,Limit 到 C8 之后不会发生重启,就能确定问题是SLPS0 信号发出时导致的问题;通常这种问题是和硬件设计相关还需要请 HW 帮忙测试找到原因;
  2. 如果PHM提示某个设备有问题没有 Power Gated, 最简单的方法是关闭之然后继续试验。特别注意的是:Audio设备不要轻易关闭,一些能够正常工作的系统关闭 Audio 之后反倒变得无法进入CS,据说这个问题是同 GFX Driver 有关;
  3. 如果发现某个外部 PCIE 设备有问题,需要确认对应的 Clock Request Pin 是否正确。在 PHM 的 Log中有这个的读取结果,结合电路图进行确认。当然,这里我非常建议用示波器之类的确认这个Pin是否工作正常。
  4. 如果PHM 提示 CSME 工作异常,首先需要确认 BIOS中的ME 版本和系统驱动是否匹配,其次还要检查没有使用的SMB Pin之类是否正确关闭;

从上面的描述也可以看到,几乎所有的方面都会对 MS 产生影响,这也是为什么“在Debug Modern Standby 的时候同样 ‘没有银弹’ 。” 的原因。如果考试之前老师表示这本书全部都是重点,那么也就相当于没有重点……..

Good Luck, BIOS Engineer!

参考:

1. http://www.lab-z.com/newghost/   Ghost 替代者,新的全盘备份工具