Isso é mais uma opinião / comentário do que uma resposta.
Você não quer e não deve programar em C. O C ++, quando usado da maneira correta , é muito superior. (OK, devo admitir que, quando usado de maneira errada, é muito pior que C.) Isso limita você a chips que possuem um compilador C ++ (moderno), que é praticamente tudo suportado pelo GCC, incluindo o AVR (com algumas limitações, filo menciona os problemas de um espaço de endereço não uniforme), mas excluindo quase todos os PICs (o PIC32 poderia ser suportado, mas ainda não vi nenhuma porta decente).
Quando você está programando algoritmos em C / C ++, a diferença entre as opções mencionadas é pequena (exceto que um chip de 8 ou 16 bits estará em grande desvantagem quando você faz muita aritmética de 16, 32 ou mais bits). Quando você precisar do último pingo de desempenho, provavelmente precisará usar o assembler (o seu ou o código fornecido pelo fornecedor ou por terceiros). Nesse caso, convém considerar novamente o chip selecionado.
Ao codificar para o hardware, você pode usar alguma camada de abstração (geralmente fornecida pelo fabricante) ou escrever sua própria (com base na folha de dados e / ou código de exemplo). As abstrações C existentes no IME (mbed, cmsis, ...) geralmente são funcionais (quase) corretas, mas falham horrivelmente no desempenho (verifique os antiquários discursam cerca de 6 camadas de indireção para uma operação de conjunto de pinos), usabilidade e portabilidade. Eles desejam expor toda a funcionalidade do chip em particular, o que em quase todos os casos você não precisará e nem se importa, e bloqueia seu código para esse fornecedor em particular (e provavelmente para esse chip).
É aqui que o C ++ pode fazer muito melhor: quando feito corretamente, um conjunto de pinos pode passar por 6 ou mais camadas de abstração (porque isso possibilita uma interface melhor (portátil!) E um código mais curto), além de fornecer uma interface independente do alvo para os casos simples , e ainda resultar no mesmo código de máquina que você escreveria no assembler .
Um trecho do estilo de codificação que eu uso, que pode deixar você entusiasmado ou se afastar horrorizado:
// 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 > >;
Na realidade, existem mais algumas camadas de abstração. No entanto, o uso final do led, digamos que ativá-lo, não mostra a complexidade ou os detalhes do alvo (para um arduin uno ou um comprimido azul ST32, o código seria idêntico).
target::led::init();
target::led::set( 1 );
O compilador não se deixa intimidar por todas essas camadas e, como não há funções virtuais envolvidas, o otimizador enxerga tudo (alguns detalhes, omitidos, como ativar o relógio periférico):
mov.w r2, #134217728 ; 0x8000000
ldr r3, [pc, #24]
str r2, [r3, #16]
str r2, [r3, #48]
Foi assim que eu o teria escrito no assembler - se eu tivesse percebido que os registros do PIO podem ser usados com deslocamentos de uma base comum. Nesse caso, provavelmente o faria, mas o compilador é muito melhor em otimizar essas coisas do que eu.
Então, até onde eu tenho uma resposta, é: escreva uma camada de abstração para o seu hardware, mas faça isso em C ++ moderno (conceitos, modelos) para não prejudicar seu desempenho. Com isso, você pode mudar facilmente para outro chip. Você pode até começar a desenvolver algum chip aleatório que tenha, que esteja familiarizado, que tenha boas ferramentas de depuração, etc. e adie a escolha final até mais tarde (quando você tiver mais informações sobre a memória necessária, a velocidade da CPU, etc.).
Uma das falhas do desenvolvimento incorporado da OMI é escolher o chip primeiro (é uma pergunta freqüente neste fórum: qual chip devo escolher ... A melhor resposta é geralmente: não importa.)
(editar - resposta a "Portanto, em termos de desempenho, C ou C ++ estaria no mesmo nível?")
Para as mesmas construções, C e C ++ são os mesmos. O C ++ possui muito mais construções para abstração (apenas algumas: classes, modelos, constexpr) que podem, como qualquer ferramenta, ser usada para o bem ou para o mal. Para tornar as discussões mais interessantes: nem todo mundo concorda com o que é bom ou ruim ...