CortexProg
Cortex-M的时代及其带来的复杂性
ARM Cortex-M芯片正在慢慢取代各种爱好者和专业人士所做的各种8位微处理器。这通常是件好事。它确实带来了一些变化。早在8位时代,基本上有两个主流派系(AVR和PIC),旁边有一些奇怪的选择(8051等)。这意味着有一个用于PIC的编程工具,一个用于AVR,因此几乎适用于所有情况。每个阵营的工具都支持某种程度的调试,跟踪和闪存编程。使用新的Cortex-M芯片并不是那么容易。有许多制造商制造精美的芯片,他们都有自己的方法来编程他们的芯片。这快速失控。必须有一个理智的解决方案。有几个。主要是JLink和ULink。两者都支持许多芯片,两者都要花费数百美元。这不是一个非常友好的价格。还有一些开源解决方案,但令人惊讶的是它们也需要花费一些钱并支持更少的东西。那么,我们可以做些什么来解决这个问题呢?
有人可能会说,它不可能那么糟糕。ARM芯片通常基于ARM文档的标准。嗯,这是真的。但在这种情况下,这没有多大帮助。ARM调试标准仅涵盖读写寄存器和内存等内容。关于编程flash,没有什么可说的。为什么会这样?每个供应商都以自己的方式闪现。强迫他们都遵守限制规范会妨碍他们可以做的一些创造性事情。然而,所有这些仍然使用户处于绑定状态。我想帮忙。
从卑微的开始......
那么如何引导ARM Cortex-M调试器呢?那么,必须在已有的芯片上实现它。对于许多业余爱好者(包括我们),这意味着8位。比如AVR。这就是开始。在ATTiny85上使用ModulaR引导程序可以为代码留出4.75K的空间。是否适合使用ARM Cortex-M调试器,与PC通信的协议以及所有必要的胶水代码?事实证明......是的
CortexProg硬件的第一个版本是用最少数量的组件手工组装在多孔板上的。值得注意的是(并且有目的),该板仍然受到PC端工具的支持,并具有所有必要的功能以保持有用。偶尔我会把它作为试驾来验证这一点。为什么这有关系?因为如果您希望深入研究基于Cortex-M的项目,您可能只需要组装一个并立即使用它。
那么,它需要什么?
通过SWD调试Cortex-M芯片相对轻松。实现SWD调试器的效果确实不那么明显(参见ADIv5.2规范)。该协议有很多层。这在概念上理解它是好的,但在尝试查看逻辑分析仪中的信号迹线时有点烦人。这是它的工作原理。在最底层,我们有线协议。SWD需要三条线:IO,CLOCK和GROUND。时钟始终由主设备(调试器)驱动。IO线依次由两者驱动。所有交易都是主要发起的。每个成功的事务都会从调试器或调试器传输32位数据。事务标头包含元数据。感兴趣的部分是2位地址和1位地址类型。地址类型确定事务是发送到SWD硬件本身(调试端口又称DP)还是发送到它所连接的任何内容(Access Port aka AP - 它上面的层)。地址位(2)的数量可能看起来有点奇怪。这似乎很少,不是吗?是。是的。
那就像SPI,对吗?
哈。不,SWD真的不像什么。如果你有SPI双向使用数据线并添加了可变比特长度的事务,那么它最近的表兄弟可能就是SPI。这意味着ATTiny没有可以帮助我们使SWD工作的硬件单元。我的初始代码是用C语言编写的。虽然有效,但速度非常慢。完成调试后,我在AVR程序集中编写了所有内容,以获得巨大的加速(超过10倍)。在这一点上,我认为它的速度与AVR一样快 - 平均速度为1.4Mbps(时钟速度在8MHz到1MHz之间)。这段代码在wire-avr-asm.S中你可能会发现它很有意思。实际上,SWD速度并不是限制因素 - 对于这种AVR版本的CortexProg硬件,通过v-usb的i / o比SWD需要更多的时间。
好的,这些位正在工作,字节呢?
显然2位地址不够,所以在地址2我们有一个寄存器,我们可以写几个位。前8位确定我们正在谈话的接入端口号(更高层)。底部4为DP提供了4个以上的地址位,接下来的4个对于AP是相同的。所以现在我们可以在DP中解决总共64个地址,在AP中解决64个地址。还不够。下一层是什么?
如果我们枚举我们可以访问的所有AP(可能有多个),我们可以找到允许访问AHB总线(MEMAP)的AP。这是所有外围设备和存储器通常驻留的地方。CPU内核也连接到此AP。MEMAP有寄存器,我们可以写入一个地址,另一个我们可以读取和写入数据。所以在这里,经过4层间接后,我们最终可以编写一个32位地址并获得32位数据。呼...
我们到了吗?
精明的读者可能会注意到我们只是读取和写入RAM。调试如何工作?这还有另一层次的间接性。在所有Cortex-M类芯片的专用存储空间中,可以找到调试寄存器。它们允许进行各种类型的调试,包括读取和写入寄存器的间接方式,停止和启动CPU,甚至捕获异常。这与大量的胶水一起将得到一个可以进行基本调试的点。
但等等,还有更多!我们还没有编程芯片的闪存。但是,我们已经到了ARM规范的末尾。每个制造商都有自己的方法来做到这一点。有些甚至有基于芯片系列或型号的多种完全不同的方法。这就是为什么他们各自制作自己的闪光工具。这就是该项目最初启动的原因。目标是使CortexProg支持尽可能多的芯片类型。一个重要的次要目标是允许易于获取和安装的插件支持芯片类型,以便用户可以自己创建并与他人共享。我们设法做到了这一点。但是,在一个人甚至尝试闪存芯片之前,必须先确定它。这并不像人们期望的那么简单。
识别CPU
阅读ARM调试规范,有一些事情会让人觉得这可能很容易。首先,DP有一个可以读取的IDCODE寄存器。它会为我们识别芯片,对吧?不是这样。除了告诉我们DP的版本之外,它几乎没有其他功能。让我们看一下。Cortex-M芯片具有CPUID寄存器。当然,这将告诉我们我们正在处理的具体微控制器?再一次,没有。这最多告诉我们Cortex-M类型(M0,M0 +,M3,M4,M7,M23,M33等)。这不足以将LPC812与nRF51822分开。现在怎么办?深入了解规范向我们展示了存在称为ROMTABLE的东西,其中有关于CPU的更详细信息。当然,就是这样,对吧?好吧,还是没有。但这是一个好的开始。ROMTABLE在大多数(但不是全部)芯片可以明确告诉我们芯片的制造商和制造商指定的“型号ID”。这对每个制造商来说意味着什么。有些足够好用于识别具有不同型号ID的每个系列(例如赛普拉斯),有些仅在闪烁方法改变时更新型号ID(例如,北欧),而有些只是随意分配ID(例如STM)。所以没有希望吗?
许多制造商已经提出了自己的微控制器类型识别方法。几乎所有都有一些内存地址可以读取以获得芯片的身份。问题是,每个制造商之间的地址不同,甚至是同一制造商的芯片系列。这使我们想要的基于插件的微控制器支持变得复杂。但并非不可能!我们通过首先识别芯片制造商,然后查看哪些脚本可以支持它,并让每个人尝试通过查找这些魔术寄存器来识别芯片来解决它。这似乎有效,用户永远不需要从任何列表中选择“芯片类型”。凉!
那么现在我们可以写flash吗?
是! 我们现在可以写flash了。每个插件首先标识用于使用ROMTABLES的CPU类型以及其他特定于制造商的方法。如果匹配,则插件将代码发送到用于编程闪存的CPU的RAM。然后将数据分段发送到RAM并进行编程。支持的基本操作是:EraseWholeChip,EraseSector,WriteSector。每个芯片类型的扇区尺寸不同,但从不担心,CortexProg会告诉我们芯片的尺寸。怎么样?插件决定了它们。这允许我们为芯片共享相同的插件,其唯一的区别是闪存大小。
插件结构
每个插件都由几个部分组成。最后,我们有识别信息。这用于正确识别芯片。还有一个用户可读的设备名称,因此可以告诉用户识别工作。除此之外,还有要上传到设备的代码。该代码有7个基本入口点,所有入口点都是可选的。前三个是初始化,按顺序调用。接下来是ChipErase,然后是SectorErase,然后是SectorWrite,然后是Cpuid(它有助于cpu识别)。插件还有一种方法可以请求调试器在内存中的任何位置设置断点/观察点。这用于某些芯片,其中必须允许ROM在闪存可用之前运行。每个插件都很简单,在源代码中包含一些示例和一个文档,以帮助您编写自己的插件。鼓励分享。
插件代码被复制到RAM(位置由插件源决定)。然后调用三个init入口点中的每一个,给它时间来确定芯片闪存大小并初始化闪存。在此之后,CortexProg将读取专用于FlashAddress,FlashBlockSize,FlashNumBlocks的地址。这将呈现给用户,然后将继续进行进一步的操作(如读取或写入闪存)。
调试,跟踪等
将代码编程到芯片中很棒,但还有很多工作要做!CortexProg允许真正的调试。PC端实用程序包含一个完整的GDB服务器,因此您可以将GDB附加到正在运行的程序并执行源级调试。但还有更多!CortexProg也允许同步printf样式输出,直接到您的控制台。所有这些都不需要任何额外的电线,不像其他解决方案!有了这个,人们可以直接从应用程序记录事物,而不用担心丢失一个字节。
由于每个特定的微控制器都支持有限数量的断点和观察点,因此CortexProg会对您进行智能管理,因此您无需这样做。这一切都适合你。太可爱了!
CortexProg的另一个可能的用例是同时闪烁许多板。多个CortexProg设备可以同时连接到同一个PC,PC端工具可以非常容易地单独控制每个设备。这样可以非常容易地对数百个电路板进行并行编程,比许多替代解决方案便宜得多。
PC端工具
HID协议用于允许在所有操作系统下无人操作。主要的CortexProg工具允许调试,编程,擦除,写入和一些特殊功能(如解锁锁定芯片)。当然,提供了PC端工具的源代码,您可以编写自己的源代码,因为协议非常简单 - 它基于ModulaR协议。
协议消息允许高级事物,例如向RAM读取和写入大块数据以及读取和写入CPU寄存器,以及执行单个SWD事务等非常低级的事情。所以无论你想在CortexProg之上构建什么 - 你都可以做到!实际上,PC端工具甚至可以说ModulaR的协议允许固件更新(甚至是初始上传),因此您甚至不需要ModulaR的上传器进行更新!
该工具在Linux和Windows(XP或更高版本)下构建良好。您可以随时在官方CortexProg网站上找到最新的资源和二进制文件。
Windows兼容性
Windows可能允许无驱动程序的HID,但它并不像在Linux中那样轻松。只要消息大小不足,Linux就会对您发送给设备的内容以及您获得的内容非常宽容您在隐藏报告描述符中承诺的报告大小。Windows则恰恰相反:它痴迷于确保您遵循HID规范。这意味着您的描述符必须完全正确,并且您可能只发送与描述符相同的字节数 - 不多也不少。这是一个问题,因为对于最大速度,您希望尽可能大地使用数据包,但是对于小数据包,您仍然有义务将大多数空的数据包带出来。此外,这只是在尝试在Windows下构建CortexProg PC端工具时才出现的。此时整个通信协议已经精心设计并且可以稳定数月。哦,它依赖于可变大小的消息......
你可能会说,“好吧,走出窗外”。不,我认为没有理由惩罚Linux用户的微软选择。相反,为工具添加了suport以执行此填充,并且固件将使用填充的数据包来回复填充的数据包。它在代码中称为WinPadding。如果PC发送WinPadded数据包,CortexProg将从那时起始终在WinPadded数据包中回复。Linux从不发送WinPadded数据包,因此可以获得更高的速度。
进一步优化是声明一些报告大小,并在任何给定时间选择最佳。遗憾的是,AVR中没有足够的RAM来使大量缓冲区工作,因此不值得。更快的官方CortexProg硬件确实采用了这种方法。
脚本化
CortexProg可以用Lua编写脚本!您可以使用它创建任意复杂的流程流。这在CortexProg手册中称为“特殊脚本”,在官方CortexProg网站的开发人员页面中有一个完整的部分。
如何建立一个
首先,您需要一台运行ModulaR v2或更高版本的ATTiny85板。有关详细信息,请访问ModulaR bootloader的页面。完成后,将SWDIO连接到引脚B4,将SWDCK连接到引脚B3。就这些!CortexProg的基本版本就是这个。它的速度并不快(没有任何基于V-USB的功能),但它可以工作,并允许您慢慢编程和调试任何基于3.3V Cortex-M的电路板。它有多快?可以每秒约800字节读取或写入闪存。这可能听起来不是很多,但在许多情况下,您需要做的就是将真正的引导加载程序加载到ARM板上。所以,这就足够了。
此代码的许可证如下:此代码可用于您自己的个人非商业用途,只要此许可证,源代码(带有任何修改)以及此页面的链接随代码或设备一起提供包含它。未经我的许可,您不得将此代码用于任何商业目的。
我们如何改进这一点?
当然这还不够。我们想用3.3V以外的电压调试,每秒超过800字节。内置的USB到串行转换器会很好,可变电压电源也可以为调试板提供电源。事实上,这种设备的工作正在取得进展。一些工作原型已经存在,他们已经掌握在用户手中,让他们感到高兴。您可以在此处查看前三个修订版的照片。旧金山的一些初创公司也在使用它们。当然,所有较新版本的CortexProg都使用以前的版本进行了闪存。(第一块主板是使用基于AVR的CortexProg硬件闪存的。)这是您进入的地方。如果您想帮助实现超低价的快速CortexProg调试器,请转到KickStarter页面并帮助实现这一目标。目标是能够以低于30美元的价格出售这些产品。在这个价位上,它将是最便宜的ARM Cortex-M调试器。为什么?这样每个人都可以进入基于ARM的编程,比AVR或PIC编程便宜得多!
阅读有关CortexProg(和下载)的更多信息
这是官方网站,其中包括开发人员手册,用户指南,更多信息以及其他链接和资源。您可以下载版本1.1.0.0的AVR源和PC端工具源[ 此处 ]。进一步的更新将发布在官方网站上,这种自制的基于AVR的设计将继续成为CortexProg的完全支持变体。
以上使用google自动翻译.
离线
这玩意速度快不起来吧。主要是慢在usb是低速的。才1.5m
离线
历史应该向前发展而不是倒退
离线