这更像是一个意见/评论而不是一个答案。
您不想也不应该使用 C 进行编程。如果以正确的方式使用C++,它的优势要大得多。(好吧,我不得不承认,当以错误的方式使用时,它比 C 差得多。)这将您限制在具有(现代)C++ 编译器的芯片上,这大致是 GCC 支持的一切,包括 AVR(与一些限制,filo 提到了地址空间不统一的问题),但几乎排除了所有 PIC(可以支持 PIC32,但我还没有看到任何像样的端口)。
当您在 C/C++ 中编程算法时,您提到的选择之间的差异很小(除了当您执行大量 16、32 或更高位算术时,8 位或 16 位芯片将处于严重劣势)。当您需要最后一盎司的性能时,您可能需要使用汇编程序(您自己的或供应商或第三方提供的代码)。在这种情况下,您可能需要重新考虑您选择的芯片。
当您对硬件进行编码时,您可以使用一些抽象层(通常由制造商提供)或编写自己的(基于数据表和/或示例代码)。IME 现有的 C 抽象(mbed、cmsis、...)通常在功能上(几乎)是正确的,但在性能(检查 oldfarts 咆哮关于引脚设置操作的 6 层间接)、可用性和可移植性方面非常失败。他们希望向您公开特定芯片的所有功能,在几乎所有情况下,您都不需要也不会关心这些功能,并且它将您的代码锁定给该特定供应商(可能还有该特定芯片)。
这是 C++ 可以做得更好的地方:如果做得好,一个 pin 集可以通过 6 个或更多抽象层(因为这使得更好的(可移植的!)接口和更短的代码成为可能),同时提供一个独立于目标的接口对于简单的情况,仍然会产生与您在汇编程序中编写的相同的机器代码。
我使用的编码风格的片段,它可以让你兴奋或惊恐地转身离开:
// GPIO part of a HAL for atsam3xa
enum class _port { a = 0x400E0E00U, . . . };
template< _port P, uint32_t pin >
struct _pin_in_out_base : _pin_in_out_root {
static void direction_set_direct( pin_direction d ){
( ( d == pin_direction::input )
? ((Pio*)P)->PIO_ODR : ((Pio*)P)->PIO_OER ) = ( 0x1U << pin );
}
static void set_direct( bool v ){
( v ? ((Pio*)P)->PIO_SODR : ((Pio*)P)->PIO_CODR ) = ( 0x1U << pin );
}
};
// a general GPIO needs some boilerplate functionality
template< _port P, uint32_t pin >
using _pin_in_out = _box_creator< _pin_in_out_base< P, pin > >;
// an Arduino Due has an on-board led, and (suppose) it is active low
using _led = _pin_in_out< _port::b, 27 >;
using led = invert< pin_out< _led > >;
实际上还有更多的抽象层。然而,LED 的最终使用,比如说打开它,并没有显示目标的复杂性或细节(对于 arduin uno 或 ST32 蓝色药丸,代码将是相同的)。
target::led::init();
target::led::set( 1 );
编译器不会被所有这些层吓倒,并且由于不涉及任何虚函数,优化器可以查看所有内容(省略了一些细节,例如启用外围时钟):
mov.w r2, #134217728 ; 0x8000000
ldr r3, [pc, #24]
str r2, [r3, #16]
str r2, [r3, #48]
这就是我在汇编器中编写它的方式——如果我意识到 PIO 寄存器可以与公共基址的偏移量一起使用。在这种情况下,我可能会,但编译器在优化这些事情方面比我好得多。
因此,据我所知,它是:为您的硬件编写一个抽象层,但要在现代 C++(概念、模板)中进行,这样就不会损害您的性能。有了它,您可以轻松切换到另一个芯片。您甚至可以开始在您已经放置、熟悉、拥有良好调试工具等的随机芯片上进行开发,并将最终选择推迟到以后(当您获得有关所需内存、CPU 速度等的更多信息时)。
IMO 嵌入式开发的谬误之一是首先选择芯片(这是这个论坛上经常被问到的一个问题:我应该选择哪种芯片......。最好的答案通常是:没关系。)
(编辑 - 对“所以性能明智,C 或 C++ 将处于同一水平?”的回应)
对于相同的构造,C 和 C++ 是相同的。C++ 有更多的抽象结构(只有几个:类、模板、constexpr),可以像任何工具一样用于好或坏。为了使讨论更有趣:不是每个人都同意什么是好是坏......