【问题标题】:Why are periperal registers 16 bit only on 32 bit MCUs such as STM32 and GD32VF103?为什么 STM32 和 GD32VF103 等 32 位 MCU 上只有 16 位外设寄存器?
【发布时间】:2022-07-12 23:43:36
【问题描述】:

在 ST STM32F103(ARM 内核)或 GigaDevices GD32VF103(RISC-V 内核)等 32 位微控制器上,有许多用于处理外设的寄存器。

令我惊讶的是,需要超过 16 位的外围寄存器被分成 2 个寄存器,即一个高位寄存器和一个低位寄存器 - 尽管 CPU 的字长(以及标准寄存器大小)是 32 位!示例:RTC_CNTHRTC_CNTL(用于读取当前 RTC 计数器值)。

因此,用于读取/写入它们的代码变得乏味且容易出错,并且存在非原子访问的问题。示例:

static uint32_t get_rtc_counter()
{
    uint32_t r = RTC_CNTL;
    r |= RTC_CNTH << 16;
    return r;
}

GlobalDevices 用户手册甚至将这些寄存器的高 16 位标记为保留(“必须保持在复位值”)——因此它们甚至可以作为 32 位寄存器访问!

由于两个供应商使用不同的 MCU 来做这件事,我对这背后的原因很感兴趣。

在与外设交互时使用这样的 16 位寄存器一定有一些技术优势,即使 CPU 本身是 32 位的。

我能想到的原因:

  • 当 ST 开始使用 STM32 时,它只是重用了之前非 32 位 MCU 系列(例如 ST8 或 ST10)的外设模块/设计
  • GlobalDevices 为他们的 ARM MCU 系列复制了一些 STM32F,只是在他们的 GD32VF103 RISC-V 系列中重新使用了他们的外设模块

但也许这背后有更好/真正的技术原因。

也许还有其他 32 位 MCU 不这样做。


更新 (2022-05-10):FWIW,SiFive E310 32 位 RISC-V MCU 做事不同!这意味着它通常使用整个 32 位的内存映射外设寄存器,并且不会将字段分成 16 位的一半。例如,它的 RTC 计数器为 48 位宽,因此分为低 32 位和高 16 位部分。

【问题讨论】:

    标签: stm32 microcontroller riscv peripherals


    【解决方案1】:

    当您坐下来编写程序时,您是否总是/立即选择一种语言,即使它可能没有意义。需要用虚数进行计算,而 Fortran 不是您的第一选择?当您选择计数为 10 的循环变量时,您是选择还是假设 8 位更好? (如果是,为什么???)。您是使用 i,j,k 作为循环变量还是有自己的习惯?

    首先 GD 以一种有点阴暗的方式克隆设备,我尝试过的 risc-v 显然是基于 cortex-m 的设备,他们将购买的 ARM 的 IP 换成了其他一些购买的 risc- v 核心。

    是的,在某些情况下,您会看到具有数十年历史的供应商从以前的 8 位或 16 位(因为没有更好的术语)内核获取外围设备并重新使用这些外围设备。很好的测试,很好的使用,很好的理解,完全支付,当我们已经有两个或三个时,为什么要花费数万美元来创建另一个具有相同功能的 uart(当然你可以问 ST 这个问题,因为他们有两个或三个很多这样的东西)。

    芯片设计人员如何以及为何选择寄存器的数量、字段在寄存器中的分布方式、寄存器的宽度、地址空间和这些寄存器的解码等。例如,它可能只有 8 位或寄存器中有 16 位,但在 4 字节边界上,可以使用 32 位事务访问。

    这里没有答案,你看看能不能直接联系工程师,开个zoom会议什么的,看看他们会不会让你开脑洞。 (他们已经继续前进的好机会)(他们可能一开始是承包商,在芯片业务中很常见,在开发阶段由承包商完成大部分工作,然后他们继续到其他一些公司/设计进行开发阶段)最有可能的选择是基于经验的几秒钟的问题,而且大多数时候不是他们作为一个团队坐了几个月然后决定的事情。

    根据您个人的经验,希望能够与 fpga 工程师或 asic 工程师一起工作并亲眼看到这一点,但您已经知道这个答案,因为当您编写软件时,您不会与团队坐下来数周或数月选择变量的名称和大小。只有你们中的一些人做了一些让别人很痛苦的事情,以至于有人在同行评审中提出了它,才会发生这种对话,否则,你的函数名、参数、参数顺序、变量名等在很大程度上是你的选择。硬件不再像软件那样神奇,今天它是使用非常类似于软件编程语言的“编程”语言来完成的。就像你的软件一样,他们敲出成百上千行 HDL...

    此外,芯片供应商明确购买 IP,每块芯片中都有一部分是购买的 IP,有些是内部的,即使是英特尔和其他大牌。您的 x86 中有很多购买的 IP 不是英特尔创建/发明/拥有的。

    出于与上述相同的原因,购买的 IP 将具有某种形式的接口,有时它们提供基于寄存器的接口和基于离散信号的接口,或者仅提供其中一种。一旦您参与了购买的 ip dram 控制器或 pcie 控制器或类似的事情,然后去查看您的竞争对手为他们的控制器注册规格(或者更有可能查看他们的 Linux 驱动程序,因为您通常不能包含购买的某些部分由于 NDA 协议,文档中的 IP 信息)您有时可以弄清楚,啊,他们购买了与我们相同的控制器,并使用相同的 init 例程...(对于某些技术,每个人都使用的可用 IP 列表非常简短大名或小名)。

    因此,您所询问的特定外设可能是购买的并具有 16 位接口,或者您所建议的可能是 STM8 或 ST7 或来自 ST 已拥有的前产品线的其他 IP。并且基于接口,设计人员可能更容易将其设置为两个单独的寄存器访问,而不是尝试将外设上的一个 32 位转换为两个独立的。或者将其保留为两个并保留一个,以防已经编写了一些内部或外部代码以在两个较小的事务中访问该字段。你应该/将会知道这一点,你创建了一个库,一个同事使用它,你改变它并给同事带来痛苦。好吧,我认为这样会更好,是的,但是我有数千行代码我必须去接触、同行评审、验证等。你可以选择是否与你的同事为敌总有一天,您将需要依靠那些您从未见过或与之互动的客户,您认为他们的生活可能会变得更好。

    关于别人做什么。由于每个芯片供应商的每个系列或产品都是其自己的开发项目,真人会根据经验和其他因素做出个人选择。您会发现可以执行此操作的产品和不执行此操作的产品。您会在公司内部甚至在单个芯片中发现,其中一个外围设备以一种方式做事,而一个外围设备以另一种方式做事。这都是非常预期和正常的。有一些基于 ARM 的 MCU 使用 8 位寄存器和只有 8 位事务来控制外围设备,它们的地址空间比它们可以消耗的要多,为什么不将所有访问都设为 32 位呢?当然,与内存不同,对外围设备的较小访问(8 位或 16 位)不一定会带来性能损失。只是意味着我们程序员有时必须确保我们生成正确的指令。

    保留的其他位是用于 1) 我们可能有一个错误,如果您从重置值更改一点,外围设备将无法工作 2) 我们可能会采用此外围设备并添加功能并将其放入下一代芯片,但如果你在那里使用相同的代码和零,它应该以传统方式工作 3)我们有一些我们选择不记录的位等。芯片一个芯片,一个寄存器一个寄存器,你会弄清楚你需要关心多少。可以说,我个人不会假设我的代码会移植,即使它看起来像下一个芯片上的同一个外围设备,我至少会测试它,然后明白它可能不准确,可能需要在某个地方有一个零,或者我可能必须进行读取-修改-写入。很多时候,无论如何你都应该做读-修改-写,而不是一些指针和相等,然后是一个单独或相等的头脑,而是一个读...修改...写。并且通过这样做作为一种习惯(是的,有很多例外,特别是 gpio 是很多读取-修改-写入,uart 通常是直接写入)您将保留这些标记为保留的位(必须为零或请勿修改)。

    归根结底,如果有人真的知道这些登记册的真实答案,那么在此处提供大量信息可能会违反他们的雇佣合同或 NDA,除非公司选择公开分享这些信息……那么信息已经在那里了。大多数关于设计的“为什么”问题都无法回答......

    【讨论】:

      【解决方案2】:

      要回答这个问题,需要了解一点seconductor的发展历史和ARM RISC架构的设计原理。

      从历史上看,ARM 处理器提供 32 位指令集。但是,32 位指令集在固件的内存占用方面是有代价的。这意味着使用 32 位指令集架构 (ISA) 编写的程序需要更多字节的闪存存储,而且闪存通常很耗电,尤其是 STM32Fx 系列等 MCU 使用的较旧的 14nm 节点(与较新的 7nm STM32Lx 和 STM32Gx 系列相比)。 32 位 ISA 对 MCU 的功耗和总成本有影响。

      为了解决这些问题,ARM 引入了 Thumb 16 位指令集,它是最常用的 32 位指令集的子集。 Thumb 指令的长度均为 16 位,并且会自动“转换”为相应的 32 位 ARM 指令。这意味着 16 位 Thumb 指令可以透明地(从开发人员的角度)实时扩展为完整的 32 位 ARM 指令,而不会损失性能。

      ARM 之后(在 2003 年?)引入了 Thumb-2 指令集,它是一种操作状态下的 16 位和 32 位指令集的混合。 Thumb-2 是一个可变长度指令集,与 Thumb 相比,它提供了更多的指令,实现了相似的代码密度。

      Cortex-M3/4/7 支持完整的 Thumb 和 Thumb-2 指令集。

      【讨论】:

      • 嗯,我不明白这个论点。当然,对于压缩指令集(例如 Thumb 或 RISC-V C 扩展),指令 encoding 只使用 16 位而不是(与 RISC 通用的)32 位编码。但是这种压缩指令只是扩展到正常操作。我的意思是,拇指指令并不是只能从内存(或内存映射的 IO 寄存器,就此而言)加载/存储 16 位。
      猜你喜欢
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 2021-01-16
      • 2014-11-18
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多