如何从“基本”微控制器过渡到 ARM Cortex?

电器工程 微控制器 手臂 数据表 文件 皮质-m0
2022-01-10 18:35:15

我有多年使用来自不同制造商的 8 位内核的经验——即 8051、PIC 和 AVR——我现在有一个 Cortex M0 来解决。特别是这个,但我希望我们能比那个更笼统。

结果比我预想的要多一点,有多个文档以不同的详细程度描述了系统的不同部分,而我真正看到的将它们连接在一起的文档中没有一个。这与拥有一个解释一切的数据表相比。我知道首先要记录更多的东西,但是格式的变化让我陷入了困境。

上面的网站有一个文档很好地概述了每个子系统和外围设备,另一个文档详细描述了每个寄存器,我有他们的 SDK 的所有源代码,包括头文件和一些复杂的示例,但我仍然看到没有任何东西可以描述它是如何连接在一起的。

是否有 Cortex 架构的简明演练来解释小型控制器所不具备的功能——比如从 CPU 到外围设备的多层总线,每层都有自己的看门狗定时器——以及它们是如何连接在一起的?

4个回答

我研究过 AVR 以及基于 ARM Cortex-M3/M4/R4 的 MCU。我想我可以提供一些一般性的建议。这将假设您使用 C 编程,而不是汇编。

CPU实际上是最容易的部分。基本的 C 数据类型将有不同的大小,但无论如何您都在使用 uint8/16/32_t,对吧?:-) 现在所有整数类型都应该相当快,32 位(int)是最快的。您可能没有 FPU,因此请继续避免使用浮点数和双精度数。

首先,努力了解您对系统级架构的理解。这意味着 IO、时钟、内存、复位和中断。此外,您需要习惯内存映射外设的概念。在 AVR 上,您可以避免考虑这一点,因为寄存器具有唯一的名称,并为它们定义了唯一的全局变量。在更复杂的系统上,通常通过基地址和偏移量来引用寄存器。这一切都归结为指针算术。如果您对指针不满意,请立即开始学习。

对于 IO,弄清楚如何处理外设复用。是否有中央多路复用器控制来选择哪些引脚是外围信号,哪些是 GPIO?或者您是否使用外围寄存器将引脚设置为外围模式?当然,您需要知道如何将 GPIO 配置为输入和输出,并启用开漏模式和上拉/下拉。外部中断通常也属于这一类。GPIO 非常通用,因此您的经验应该可以很好地为您服务。

计时归结为几件事。您从时钟源开始,通常是晶体或内部 RC 振荡器。这用于创建一个或多个系统级时钟域。高速芯片将使用 PLL,您可以将其视为倍频器。在各个点也会有时钟分频器。他们需要考虑的关键事项是您的 CPU 时钟频率应该是多少,以及您的通信外围设备需要多少比特率。通常这是非常灵活的。当您变得更高级时,您可以了解低功耗模式之类的东西,这些模式通常基于时钟门控。

内存是指闪存和 RAM。如果您有足够的 RAM,那么在早期开发过程中将程序保留在那里通常会更快,这样您就不必一遍又一遍地对闪存进行编程。这里最大的问题是内存管理。您的供应商应提供示例链接器脚本,但您可能需要根据程序的性质为代码、常量、全局变量或堆栈分配更多内存。更高级的主题包括代码安全和运行时闪存编程。

重置非常简单。通常你只需要注意看门狗定时器,它可能默认启用。当您一遍又一遍地运行相同的代码时,重置在调试期间更为重要。由于这种方式的排序问题,很容易错过一个错误。

关于中断,您需要了解两件事——如何启用和禁用它们,以及如何配置中断向量。AVR-GCC 使用 ISR() 宏为您完成后者,但在其他架构上,您可能必须手动将函数地址写入寄存器。

微控制器外设通常相互独立,因此您可以一次学习一个。选择一个外围设备并使用它来学习部分系统级内容可能会有所帮助。Comm 外设和 PWM 适用于时钟和 IO,而定时器适用于中断。

不要被复杂程度吓倒。那些“基本”微控制器已经教会了你很多你需要知道的东西。如果您需要我澄清任何事情,请告诉我。

记住 ARM 拥有微处理器的知识产权,但实际上并不制造零件,这一点很有用。相反,制造商授权各种 ARM 处理器版本,并生产自己独特的部件,其中包含单独的功能和外围设备组合。

话虽如此,如果您是该架构的新手,那么从 ARM 的文档开始可能是有意义的,该文档本质上是所有此类微处理器的基线文档。

例如,ARM 的网站上描述了 Cortex-M0 。

还有一个ARM 相关书籍的列表,可以满足各种需求和兴趣。

最后,还有特定制造商的数据表。对于 M0,Cypress、NXP 和 STMicroelectronics 只是众多基于 Cortex-M0 的真实零件制造商中的三个。

(不,我不为 ARM 工作,也从来没有。)

一大区别是使用供应商提供的库。对于 PIC、Atmels 等,大多数开发人员并没有太多使用基本库(用于 gpio、计时器、adc 等)。根据我的经验,人们在编写自己的代码时(最多)会使用它们作为指南。

但是,对于 ARM,这些库几乎总是被使用。建议制造商遵循一个标准“CMSIS”。大多数都这样做。它有助于代码可移植性(在不同的 ARM 之间和制造商之间),并为构建代码提供了一种“标准化”方法。人们习惯于看到和理解库函数。

当然有一些开发人员直接访问寄存器,但他们是异常值:)

为了回答您的问题,我发现通读图书馆文档非常有帮助。ST 拥有完善的代码,以及由 Doxygen 创建的大型帮助文件。您可以查看每个硬件模块的所有选项。

以 GPIO 为例,初始化函数处理:

  • 方向(进或出)
  • 上拉/下拉
  • 集电极开路/推挽式
  • 转换率
  • 等等。

通过查看选项,您可以看到什么是可能的。当然,您将学习如何将这些选项传递给 Init 函数!

好的,既然我已经说过了,我看到您的特定 ARM 没有符合 CMSIS 的库。相反,他们有自己的专有 SDK 可供下载。我会开始查看他们的 SDK 文档。

如果您没有与此特定产品结婚,我可能会建议您找到具有更兼容库的其他供应商。无论如何,你都会爬上一条学习曲线,所以你不妨让你的投资更便携……

手臂很有趣!我没有回头。

搬家的好时机;8 位正在迅速消亡;当您可以购买带有(例如)STM32F103 的 5 美元板时,这是一个功能相当强大的 32 位 ARM 微控制器(甚至带有 USB!),毫无疑问,时代已经改变了。

你已经有了一些很好的答案,但主要是我会说“忘记组装”,几乎“忘记关心 cpu 如何在低级别工作” - 有一天会有一个角落案例你需要深入研究它(特定的优化或调试)但 ARM 内核运行 C 代码非常好(按设计),而且您很少需要深入探索。

这确实意味着您将花费一定的时间来解决编译器(尤其是链接器和 makefile)的问题,向您吐出一些晦涩难懂的错误,但它们都是可以克服的。

ARM 的工作原理(即 ARM cpu 书籍)是密集的,直到您真正需要优化的那一天才很有趣(当您拥有 32 位寄存器和您的 PLL 时,您会惊讶地发现这种情况很少见) d CPU 时钟在 100mhz 范围内)。

“old skool” ARM 指令集比更新的“Thumb2”更容易阅读反汇编 - 这是您在大多数现代微控制器级 ARM (Cortex) 上找到的 - 但同样是汇编语言指令的内部大多淡入背景;如果您拥有正确的工具集(尤其是带有断点/单步等的不错的源级调试器),那么您根本就不会太在意它是 ARM。

一旦您进入了 32 位寄存器和 32 位数据总线宽度以及您想要的所有芯片上可用的世界,您将永远不想再回到 8 位 CPU;基本上,“放轻松”并编写代码以使其清晰易读而不是高效通常不会受到任何惩罚。

然而......外围设备......是的,有问题。

你肯定会在现代 MCU 上玩很多东西,其中很多都是非常花哨的东西;您经常会发现远远超出 AVR、PIC 和 8051 片上外设的复杂世界。

一个可编程定时器?不,有八个!DMA?12 个具有可编程优先级和突发模式、链接模式和自动重载的通道怎么样?

I2C?I2S?数十种引脚复用选项?重新编程片上闪存的 15 种不同方法?当然!

通常感觉就像您已经从饥荒变成了外围设备的盛宴,并且通常会有整块芯片您会欣赏但几乎不会使用(因此;时钟门控)。

片上硬件的数量(以及仅在一个供应商的芯片系列中的变化)现在相当令人难以置信。一个芯片供应商当然会倾向于重复使用 IP 块,所以一旦你熟悉了某个品牌,它就会变得更容易,但“现在做的事情太疯狂了”。

如果外设及其交互(以及 DMA 和中断和总线分配以及和...)如此复杂(有时,与数据表中描述的不完全一样),工程师经常拥有最喜欢的 ARM MCU 范围和倾向于仅仅因为他们熟悉外围设备和开发工具而想要坚持使用它。

良好的库和开发工具(即使用适当的调试器进行快速编译+调试周期)和大量工作示例代码项目对于您现在选择 ARM MCU 绝对至关重要。似乎大多数供应商现在都有非常便宜的评估板(

我相信您已经注意到,一旦您使用 ARM 超越了微控制器级别并进入 SOC 级别(例如 Raspberry Pi/etc 风格的 SOC),那么规则就会完全改变,而这一切都与您将使用哪种 Linux 有关跑,因为——几乎没有例外——你会疯狂地尝试其他任何事情。

基本上; 无论(可能)在本次演出中为您预先选择的 CPU 是什么,请为自己购买一些来自不同供应商(TI、STM、飞思卡尔等)的超便宜的基于 Cortex 的评估板,并且使用提供的示例代码进行破解。

最后的建议;一旦您在数据表中找到描述您正在使用的确切部件号芯片的引脚复用选项的一页或三页,您可能希望将其打印出来并贴在墙上。在项目后期发现由于引脚复用而无法实现某种外围设备组合并不好玩,有时这些信息被隐藏得如此之深,你会发誓他们试图隐藏它:-)