【问题标题】:Is it possible to create a new primitive type in C++ for embedded platforms?是否可以在 C++ 中为嵌入式平台创建新的原始类型?
【发布时间】:2023-07-05 01:17:01
【问题描述】:

我正在从头开始为 Atmel ATmega2560 芯片编写自己的 c++ 库,作为学习它(以及一般电子设备)如何工作的练习。作为其中的一部分,我想在 C++ 中创建一个新的基本 byte 类型,它不仅仅是另一种类型的别名,并且具有 8 位的精确大小。

由于这是一个嵌入式平台,我希望尽可能避免为芯片生成额外的指令来处理,这使得类和结构不适合。我知道我可以使用 char 类型,但是 C++ 标准对它的大小进行了模糊定义(“至少一个字节”,并且一个字节的大小可能因平台而异),我不确定如何AVR平台对待它;虽然我怀疑unsigned char 将是 8 位,因为大多数寄存器都是 8 位。还有其他原因我不想使用unsigned char

基本上,一旦我的图书馆开始运作,我想做的事情是这样的:

int main()
{
/* PORTB is global object instantiated in my lib that unifies handling the Data Register and Data Direction Register for PORTB pins on the chip. PORTD is similar, just memory addresses of registers are different */
  PORTB.setDDR(0); // All pins are inputs.
  PORTD.setDDR(0xFF); // All pins are outputs.
  byte b = PORTB.read();
  b |= 0b10011000;
  PORTD.write(b);

  return 0;
}

能够隐式转换为 int 和其他基本类型将是一个额外的好处,但可能不是必需的。除了分叉 avr-gcc 和编写新的内在类型之外,是否有可能做到这一点?

注意:我有 ATmega2560 的完整数据表,其中包括指令集列表。如果必须,我不害怕使用 in-line Assembly,但出于性能(毕竟,我只是人类)和最佳实践的原因,我不希望这样做。

我能够找到this question,但这仍然只是别名,并且无法控制类型的实际大小。一些答案还提到使用 Boost 库;我不确定 Boost 是否适用于 AVR,并且我不想依赖其他库,因为这违背了从头开始编写自己的库的目的。

【问题讨论】:

  • “[char] 的大小定义模糊”,不,它正好是 1 个字节,与平台无关。也许您正在考虑八位字节。如果是这样,请查看 .
  • 除非您正在编写自己的编译器,否则您无需担心任何这些,您的编译器供应商已经开始工作了。
  • 我认为用 C++ 编写 AVR 不是一个好主意。由于外部哈佛架构,这将增加相当多的开销(更不用说闪存和可能的 RAM 开销)。对于类型:阅读stdint.h。在那里,您已经有了适当大小的类型。

标签: c++ embedded avr avr-gcc atmega


【解决方案1】:

具有固定基础类型的枚举可以满足您的要求:

enum byte : unsigned char {};

但是,您的概念基础似乎有些摇摇欲坠:

我不确定 AVR 平台如何处理它

在嵌入式编程中,您通常会花更多时间了解特定平台。可以肯定的是,char 在 8 位平台上正好是 8 位,但实际上您应该找到实际说明的手册。

/* PORTB 是在我的库中实例化的全局对象,它统一处理芯片上 PORTB 引脚的数据寄存器和数据方向寄存器。 PORTD类似,只是寄存器的内存地址不同*/

这不是您图书馆的工作。芯片供应商通常最了解他们自己的硬件和他们支持的编译器。使用官方库。

使用编译器作为基础构建您自己的运行时库可能是一个有趣的练习,但您并不想永远开发和支持它。

【讨论】:

  • 纠正我,如果我错了,但是 IIRC,C++ 中的 enum 只允许按照定义分配其常量。所以你不能像在 C 中那样组合位等(你不能指定底层类型 otoh。你实际上必须为所有可能的值提供常量。
  • @Olaf 不,C++ 枚举与 C 向后兼容。C++ 标准甚至允许枚举在std:: 中实现位集类型。
  • 嗯...实际上我很确定这是主要区别之一。我真的需要更新我的 C++ 知识。
  • 我对这个答案投了反对票,因为它完全忽略了我这样做是为了娱乐和教育的事实。我知道对于一个真正的应用程序,我最好使用 avr-libc 和 C。我还明确表示我不想使用预制库,所以告诉我只使用官方库会适得其反.此外,我从未表示我要发布这个库。这只是一个学习练习。最后,我确实有该芯片的完整数据表。我什至是这么说的。但它有超过 1k 页长,而且我通过实践学习得最好,这就是这个练习的重点
  • @KDØBPV 这是您的特权,但您的任何批评都不适用于这里的解决方案,即使用枚举。 (数据表可能没有说明 C ABI,大多数都没有。)对于它的价值,我是唯一一个支持你的问题的人。
【解决方案2】:

没有。 C++ 中的所有类型要么由标准定义(“原始类型”,还包括指针和函数)、由实现定义的扩展类型(__int128)或用户定义类型(类、结构、联合)。

【讨论】:

  • 这通过排除用户定义的类型来引出问题。 C 或 C++ 中的任何类型都不是“只是另一种类型的别名”; typedef 实现别名但不创建类型。
最近更新 更多