1.TinyML-TVM是源译如何驯服Tiny的(上)
2.Game and Watch 破解刷机教程
3.OpenOCD代码结构浅析(基于RISCV)
4.å¦ä½ç¼è¯Windowsä¸çOpenOCD
5.Espressif IDE 及其 v2.4.0 新增功能——第一部分
TinyML-TVM是如何驯服Tiny的(上)
低成本、人工智能驱动的码编消费类设备的激增,激发了研究者对“裸智能”(低功耗、源译通常无操作系统)设备的码编兴趣。传统上,源译专家能在这些设备上运行某些模型,码编efu漫画源码但为不同设备优化模型是源译个挑战,往往需要针对设备的码编手动优化。尤其是源译针对没有Linux支持的平台,没有可扩展的码编模型部署解决方案。因此,源译开发者通常需要创建一次性的码编定制软件堆栈,以管理资源和调度模型执行。源译
尽管机器学习软件的码编优化并不是裸机领域特有的难题,它与GPU和FPGA等硬件后端的源译开发人员共同面对。TVM展现出了适应新硬件目标的能力,但在微控制器独特配置的挑战下,它之前还未能提供足够的支持。为解决这一问题,TVM扩展了微控制器后端,即µTVM(发音为“MicroTVM”),以在裸机设备上执行张量程序,并通过TVM内置的张量程序优化器AutoTVM自动优化这些程序。上图展示了µTVM+AutoTVM基础设施的概览。
µTVM+AutoTVM的实际应用
在讨论TVM/MicroTVM及其工作原理之前,我们先看一个实际应用示例。假设我们使用STMFZG板,它配备了一个强大的ARM Cortex-M7处理器,非常适合边缘人工智能应用。通过USB-JTAG端口将板连接至桌面,使用OpenOCD打开与设备的JTAG连接,从而通过µTVM使用设备无关的TCP套接字控制M7处理器。在桌面上运行TVM代码,执行CIFAR-分类器,如完整脚本所示:
在这个设置中,左峰源码性能表现可能不佳,但AutoTVM提供了一线生机。通过为设备编写调度模板并进行一轮自动调整,可以显著提升性能。具体来说,只需替换原始构建行:
然后替换为:
这样,结果将显著提升,性能大约提升2倍,与CMSIS-NN版本5.7.0(commit ab7c9a)相比,后者是一个手工优化的ML内核库。
µTVM的性能表现与CMSIS-NN模型相比较具竞争力,但工作才刚刚开始,利用TVM的优化特性还有更多空间。通过加速密集/全连接运算(如密集/全连接操作)并利用TVM的模型特定量化和运算符融合功能,可以进一步优化性能。µTVM与TVM能够协同工作,发挥最佳性能。
µTVM的设计理念
µTVM旨在满足设备最低公分母的要求,只需提供设备的C交叉编译器工具链、读/写设备内存的方法、设备内存布局和体系结构特征的规范以及为设备准备函数执行的代码段。大多数裸机设备都支持C和JTAG,因此(1)和(2)通常是免费的。此外,(3)和(4)要求通常较小。例如,STMF系列板的(3)和(4)示例如下:
µTVM基础设施和设备runtime的构建是为了满足这些需求,正努力通过支持常见的开源runtime平台(如mBED OS)来简化编译和链接过程。
µTVM的设备会话
考虑到微控制器的网络特性,引入了微会话的概念,它稍微偏离了标准的TVM代码。µTVM中的每一项功能都依赖于与目标设备的开放会话。在第一个代码片段中,一行代码偏离了规范,票务源码android即这一行:
通过这个with块内的每一行,都可以调用µTVM中的函数,上下文是device_config指定的设备。这条线背后做了很多工作,让其拆分如下:
首先,它初始化与设备的连接,使用指定的任何通信方法(通常是OpenOCD)。然后使用指定的交叉编译器交叉编译µTVM设备runtime。最后,主机为编译后的二进制文件分配空间,并使用打开的连接将二进制文件加载到设备上。
由于runtime现在位于设备上,自然需要一些函数来运行它。
模块加载
TVM的核心抽象之一是模块。模块为特定设备/ runtime目标存储一组相关函数。考虑到微控制器通常没有操作系统,µTVM需要额外的工作来维护这种高级抽象。跟踪创建和加载µTVM兼容模块的过程:
假设有一个微型会议打开设备,并实现二维卷积的TVM调度。如果想把它加载到微控制器上,需要将C代码发出。为了实现这一点,只需要设定目标tvm.build或relay.build,例如:
然后,通过µTVM基础设施中的核心功能运行它:create_micro_mod:
这样,交叉编译模块中的C源代码,为生成的二进制文件分配空间,然后将二进制文件的每个部分发送到设备上分配的插槽中。一旦模块二进制文件在设备内存中处于合适的位置,二进制文件中的函数指针将被修补,使模块能够在设备runtime访问帮助函数(例如,分配草稿行)。
加载内核后,可以获取卷积函数的vue源码运行远程句柄,如下所示:
张量加载
如果要调用运算符,首先需要一些张量作为参数:
然后,根据其数据类型(例如int8、float等)和形状,计算每个张量的字节大小,主机在设备堆上分配内存区域。接着将张量的数据加载到分配的区域中。
函数调用
运算符执行可能是系统中最复杂的部分。为了简化表示,我们首先讨论严格执行(运算符一被调用就立即执行),然后是延迟执行(只有在需要运算符的结果时才执行运算符),这是系统的实际工作方式。
严格执行
调用函数时,输入和输出张量都作为参数传递,这就是目标传递样式:
考虑到这些张量已经在设备上分配,只需要向设备发送元数据(设备地址、形状和数据类型),设备就能知道使用哪个驻留张量。下面显示了一个名为“runtime”的函数调用。在构造这个表示之前,需要将元数据序列化到设备上专门为此目的而存在的arguments部分中。
µTVM会有一个全局UTVMTask实例,从主机端写入该实例。一旦写入任务,runtime就拥有了执行函数所需的一切,可以在runtime的入口点开始执行。runtime执行一些轻量级初始化,运行运算符,然后将控制权返回给主机。
Game and Watch 破解刷机教程
本教程适用于任天堂新版Game&Watch Mario/Zelda版本。进行刷机操作有风险,若机器在刷机过程中发生硬件损坏或机器无法正常使用,我们概不负责。
更新日期://
根据评论区用户@alexzhong 的户外旅行源码建议,在下载编译固件所需的gcc工具链时,请确保下载x版本的工具链,而非arm版本。否则,可能会在编译过程中遇到错误。
准备工具:
- 十字螺丝刀一把
- Y字螺丝刀一把
- stlink(推荐淘宝盗版stlink v2,价格在元以内)
- Game&Watch Zelda/Mario 版本 MXUFM2I-G(用于扩展内存大小,可选)
- 一台装有Ubuntu的电脑(或使用具有USB直通功能的虚拟机如VMware)
认识Game&Watch硬件:
- Game&Watch主控为stmh7b0vbt6,配备Mhz Cortex-M7内核与kb内部flash存储。
- 外部Flash采用mxu系列的1.8v spi nor flash,Zelda版本为4MB大小,Mario版本为1MB大小,通过OctoSpi接口连接主控。
- 电池与喇叭与Switch Joycon同款,以降低成本。
- 主板供电为1.8v,debug接口的VDD也是1.8v,请勿接至3.3v供电,以防硬件烧毁。
硬件接口定义:
- Zelda版本:连接SWCLK, GND, SWDIO三根线。
- Mario版本:同样连接SWCLK, GND, SWDIO三根线,但需注意不要连接VDD。
更多硬件信息参考:github.com/ghidraninja/...
破解加密和备份原机固件:
- Game&Watch固件经过加密,尽管硬件开放性高,但固件本身仍需破解。
硬件准备:
- 断开电池连接,将SWDIO, SWCLK, GND线连接至stlink对应端口。
- 将stlink连接到Ubuntu系统(或VMware)。
- 使用Game&Watch的typec电源。
系统软件准备:
- 自行编译安装OpenOCD,由于版本和自带库问题,可能无法使用apt自动安装。
- 确保git submodule更新完整,可能需要反复尝试。
- 下载并解压arm gnu toolchain。
备份和破解流程:
- 下载脚本仓库。
- 配置脚本环境。
- 运行脚本备份外部flash。
- 确保flash备份后,开始向flash中写入内容。
- 备份内部flash,确保机器处于蓝屏模式,完成所有文件备份。
- 机器在完成脚本4解锁和脚本5恢复后,变为解密状态,可刷入其他固件。
错误代码分析:
- 运行中可能出现各种问题,查看logs目录下的n_openocd.log以获取详细错误信息。
- 确保脚本有读取usb设备的权限,运行sudo命令以获得权限。
- 连接器与设备不兼容时,可尝试更新stlink v2的固件。
编译并刷入retro_go固件:
- Game&Watch无扩展存储,所有游戏rom均在固件内。
- 支持运行的游戏平台包括:GBC、GB、GBA、NES、SNES、N、MD、SMS、SCS-1、SFC、PCE、GG、PS、PSX、SCE、PS2、PS3、PS4、Xbox、Xbox、XboxOne、Wii、WiiU、DS、3DS、PSVita、NDS、3DS、WiiU、Switch等。
- 准备游戏rom,确保容量不超过flash大小。
- 编译前,确保所有破解流程要求的软件已安装完毕。
- 下载固件源码,配置运行环境。
- 将游戏rom放入rom目录,编译固件。
- 编译完成后,自行刷机。
OpenOCD代码结构浅析(基于RISCV)
揭示OpenOCD的RISCV调试之旅:深度解析与实践在探索RISC-V平台的JTAG模块调试世界中,OpenOCD代码的精髓成为了一道迷人的学习课题。OpenOCD的架构犹如精密的调音器,由两大部分巧妙地编织:配置文件的解析与GDB通信的桥梁。
配置文件解析艺术OpenOCD的起始点是配置文件,这里隐藏着TCL语法的魔法。command_registrants[]数组如同指挥家的指挥棒,引导预注册的handler函数,如trace handler,以独特的名字定位,灵活适应不同的工作模式。每个handler函数注册后,它们形成一个有序的执行矩阵,便于Jim解释器高效地搜索并执行命令。
GDB通信的秘密通道服务器的核心是server_loop(),它如同信使,接收socket中的每一道指令,无论是设置断点还是执行其他操作。设置软件断点的奥秘,是通过riscv_remove_breakpoint函数,将OpenOCD的机器码巧妙地“写回”到目标MCU的内存地址。底层操作涉及dmi_write()和dmi_read(),犹如在调试的迷宫中穿行,通过Debug Module获取和修改内存。
OpenOCD通过DTM寄存器深入RISC-V的CSR世界,利用DMI命令格式进行抽象操作,实现对mstatus等寄存器的间接访问。异常处理流程中,每一步都像一场精密的舞蹈,信号通过JTAG的TCK、TMS、TDI和TDO四根引脚交织传递。 调试实战指南要驾驭OpenOCD,首先得铺好基础:安装依赖、下载源码、配置ddd调试器,编译并启动gdbserver和ddd,熟练运用gdb的断点、单步命令。DDD的可视化工具如变量查看、调用栈和寄存器窗口,让调试过程更加直观。
理解OpenOCD与处理器的亲密合作至关重要:GDB加载elf文件,通过符号信息驱动,OpenOCD则搭建起GDB与Debug-Module之间的沟通桥梁,实现精准的调试操作。 探索之旅的下一步对OpenOCD源码的深入研究,是了解其精髓的关键,这是一场永无止境的学习之旅。未来,我将继续学习,更新文档,以更全面的视角解析OpenOCD的复杂运作。
å¦ä½ç¼è¯Windowsä¸çOpenOCD
ãOpenOCDä»ç»ã
OpenOCD为åµå ¥å¼ç®æ ç³»ç»æä¾ä¸ä¸ªè°è¯ï¼å¨çº¿ç¼ç¨åJTAGè¾¹çæ«ææµè¯çå·¥å ·ãæ¯æWigglerï¼åºäºFTçJTAGçé¢çä¸äºè°è¯å¨ãç®æ è¯çæ¯æARM7,ARM9, ARM, ARMåCortexçæ ¸å¿çè¯çã并æä¾ä¸ä¸ªGDB Serveræ¥å£ã
ãOpenOCDçç¼è¯åå®è£ ã
1. å¦ææ¯Windowså¹³å°çè¯ï¼éè¦å å®è£ Cygwinç¯å¢ï¼æ³¨æä¸å®è¦éæ©å®è£ 以ä¸å¼åå ï¼
- autoconf: Wrapper scripts for autoconf commands
- automake: Wrapper scripts for automake and aclocals
- gcc: C compiler upgrade helper
- make: The GNU version og the 'make' utility
- subversion: A version control system
(å¯ä»¥å®å ¨å®è£ ï¼å ç¨5Gå¤ç空é´ï¼éè¦ä¸è½½Mçæ件)ã
2. ä¸è½½OpenOCDçSVNæºä»£ç ï¼æå¼Cygwinå½ä»¤è¡çé¢ï¼æ§è¡å¦ä¸çå½ä»¤ï¼
mkdir /home/openocd
cd /home/openocd
svn checkout svn://svn.berlios.de/openocd/trunkãææ¯
svn checkout bined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst srst_pulls_trst
#LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough
jtag_reset 1 1
jtag_reset 0 0
#jtag scan chain
jtag_device 4 0x1 0xf 0xe
target arm7tdmi little 0 arm7tdmi-s_r4
[new_target_name] configure -event reset-init {
# Force target into ARM state
soft_reset_halt
#do not remap 0x-0x to anything but the flash
mwb 0xEFC 0x
}
working_area 0 0x 0x nobackup
#flash bank lpc <base> <size> 0 0 <target#> <variant>
flash bank lpc 0x0 0x7d 0 0 0 lpc_v2
ãOpenOCDçæµè¯ã
æå¼Cygwinå½ä»¤è¡çé¢ï¼æ§è¡å½ä»¤ï¼
openocd -f openocd.cfg
以ä¸æ¯æçè¿è¡æªå¾ï¼
ãIARçé ç½®ã
å¨é¡¹ç®é项çDebugä¸çsetup页éï¼éæ©GDB Serverï¼
å¦æ代ç éè¦ä¸è½½å°flashä¸è¿è¡ï¼Download页ééæ©Use flash loaderï¼å¨plugin页éï¼å¯ä»¥å»æstack以æé«é度ã
å¨ä¸é¢çGDB Serverä¸ï¼TCP/IP address or hostnameä¸æ·»localhostã
ä¹åå°±å¯ä»¥æè°è¯æé®å¼å§è°è¯äºã
Espressif IDE 及其 v2.4.0 新增功能——第一部分
Espressif IDE 是乐鑫针对 ESP-IDF 物联网开发框架打造的集成开发环境,它融合了 ESP-IDF Eclipse 插件、基本 Eclipse CDT 插件、OpenOCD 插件及其他第三方插件,提供构建 ESP-IDF 应用所需的全套工具。
在 v2.4.0/2.4.1 版本中,Espressif IDE 引入了一系列新特性,显著提升了插件质量,加速了开发流程。IDE 为 ESP-IDF 组件提供了集成支持,用户在创建项目时,相关组件将自动链接至项目,存放在 esp_idf_components 文件夹中,便于用户直接在 Eclipse 项目资源管理器中浏览源代码,通过 F3 或在 macOS 下的 command + 点击函数名,实现快速导航至函数定义。
为了解决之前无法解析头文件和索引器的问题,IDE 对索引器进行了优化,根据 compile_commands.json 定义的组件找到头文件并解析功能,每次构建后,IDE 都会链接 ESP-IDF 组件,并刷新文件列表,显著提高了开发效率。
ESP-IDF 提供了应用层跟踪功能,帮助用户分析应用程序行为。用户可通过 IDE 的用户界面启动或停止跟踪,并处理输出数据,使用 app_trace_to_host 项目快速入门。跟踪配置和 OpenOCD 服务器启动集成在 IDE 中,为用户提供便捷的调试体验。生成输出文件后,用户可通过“开始解析”按钮解析文件,查看应用内存使用情况。
IDE 支持从 IDF 组件注册器安装 ESP-IDF 组件,用户在项目资源管理器中选择项目后,通过“安装 ESP-IDF 组件”操作,获取所有可用组件列表并快速集成到现有项目中,同时组件 readme 文件可通过“更多信息”按钮查看。
在 Panic 模式下,用户可利用 GDBStub 片上调试功能诊断和调试 ESP-IDF 应用程序。在 SDKConfig 中启用 GDBStub 调试,连接串行监视器自动启动 GDBStub 调试器。当芯片进入 Panic 模式,用户可查看寄存器堆栈跟踪或直接查看堆栈框架中的变量值。Espressif 菜单提供了插件相关项目的便捷操作,支持 Eclipse - 版本及其他版本。
通过 v2.4.0/2.4.1 版本,Espressif IDE 实现了全面优化与修复,显著提升了用户开发体验。了解更多信息,请参考 v2.4.0 和 v2.4.1 版本页面。