这更多是一种意见/评论,而不是答案。
您不希望也不应该使用 C进行编程。以正确的方式使用 C ++ 会更加出色。(好的,我不得不承认,如果以错误的方式使用它,它会比C差得多。)这限制了您使用具有(现代)C ++编译器的芯片,GCC支持的一切几乎全部,包括AVR(带有有一些限制,filo提到了地址空间不均匀的问题),但是几乎排除了所有PIC(可以支持PIC32,但我还没有看到任何不错的端口)。
当您使用C / C ++进行算法编程时,您提到的选择之间的差异很小(除了8或16位芯片在执行16、32或更高位算术时会处于严重的劣势)。当您需要最后一点性能时,可能需要使用汇编器(您自己的汇编语言或供应商或第三方提供的代码)。在这种情况下,您可能需要重新考虑选择的芯片。
对硬件进行编码时,可以使用某些抽象层(通常由制造商提供)或编写自己的抽象层(基于数据表和/或示例代码)。IME现有的C抽象(mbed,cmsis等)通常在功能上(几乎)是正确的,但是在性能方面却令人吃惊(要检查针脚操作中有关6层间接寻址的旧版),可用性和可移植性。他们希望向您公开特定芯片的所有功能,而在几乎所有情况下,您将不需要它们,而不必关心它们,这会将您的代码锁定在该特定供应商(可能是该特定芯片)上。
这是C ++可以做得更好的地方:正确完成操作后,引脚集可以经过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),它们可以像任何工具一样用于好坏。为了使讨论更加有趣:不是每个人都同意什么是好是坏。