Esto es más una opinión/comentario que una respuesta.
No quieres ni debes programar en C. C++, cuando se utiliza de forma correcta es muy superior. (Vale, tengo que admitir que cuando se usa de forma incorrecta es mucho peor que C.) Eso te limita a los chips que tienen un compilador (moderno) de C++, que es más o menos todo lo que soporta GCC, incluyendo AVR (con algunas limitaciones, filo menciona los problemas de un espacio de direcciones no uniforme), pero excluyendo casi todos los PICs (PIC32 podría ser soportado, pero no he visto ningún puerto decente todavía).
Cuando estás programando algoritmos en C/C++ la diferencia entre las opciones que mencionas es pequeña (excepto que un chip de 8 o 16 bits estará en grave desventaja cuando hagas mucha aritmética de 16, 32 o más bits). Cuando necesites la última onza de rendimiento, probablemente tendrás que usar ensamblador (ya sea el tuyo propio o el código proporcionado por el vendedor o un tercero). En ese caso, es posible que quieras reconsiderar el chip que has elegido.
Cuando estás codificando para el hardware puedes usar alguna capa de abstracción (a menudo proporcionada por el fabricante) o escribir la tuya propia (basada en la hoja de datos y/o el código de ejemplo). IME las abstracciones existentes en C (mbed, cmsis, ...) son a menudo funcionalmente (casi) correctas, pero fallan horriblemente en el rendimiento (comprueba el despotricar de oldfarts sobre 6 capas de indirección para una operación de ajuste de pin), usabilidad y portabilidad. Quieren exponer todo funcionalidad del chip en particular, que en casi todos los casos no necesitarás ni te importará, y bloquea tu código a ese proveedor en particular (y probablemente a ese chip en particular).
Esto es lo que C++ puede hacer mucho mejor: cuando se hace correctamente, un conjunto de pines puede pasar por 6 o más capas de abstracción (porque eso hace posible una mejor interfaz (¡portátil!) y un código más corto), pero proporcionar una interfaz independiente del objetivo para los casos sencillos y sigue dando como resultado el mismo código máquina que se escribiría en ensamblador .
Un fragmento del estilo de codificación que utilizo, que puede entusiasmarte o hacerte retroceder con horror:
// 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 > >;
En realidad hay algunas capas más de abstracción. Sin embargo, el uso final del led, digamos que para encenderlo, no muestra la complejidad ni los detalles del objetivo (para un arduin uno o un ST32 blue pill el código sería idéntico).
target::led::init();
target::led::set( 1 );
El compilador no se siente intimidado por todas esas capas, y como no hay funciones virtuales implicadas, el optimizador lo ve todo (algunos detalles, omitidos, como la activación del reloj del periférico):
mov.w r2, #134217728 ; 0x8000000
ldr r3, [pc, #24]
str r2, [r3, #16]
str r2, [r3, #48]
Que es como lo habría escrito en ensamblador - si me hubiera dado cuenta de que los registros PIO pueden ser utilizados con desplazamientos desde una base común. En este caso probablemente lo haría, pero el compilador es mucho mejor que yo para optimizar estas cosas.
Así que la respuesta que tengo es: escribe una capa de abstracción para tu hardware, pero hazlo en C++ moderno (conceptos, plantillas) para que no perjudique tu rendimiento. Con eso en su lugar, usted puede cambiar fácilmente a otro chip. Incluso puedes empezar a desarrollar en algún chip al azar que tengas por ahí, con el que estés familiarizado, para el que tengas buenas herramientas de depuración, etc. y posponer la elección final hasta más adelante (cuando tengas más información sobre la memoria necesaria, la velocidad de la CPU, etc.).
OMI una de las falacias del desarrollo embebido es elegir primero el chip (es una pregunta que se hace a menudo en este foro: qué chip debo elegir para .... La mejor respuesta es generalmente: no importa).
(editar - respuesta a "Entonces, en cuanto a rendimiento, ¿C o C++ estarían al mismo nivel?")
Para las mismas construcciones, C y C++ son iguales. C++ tiene muchas más construcciones para la abstracción (sólo algunas: clases, plantillas, constexpr) que pueden, como cualquier herramienta, usarse para lo bueno o para lo malo. Para hacer las discusiones más interesantes: no todos están de acuerdo en lo que es bueno o malo...
2 votos
Si las cosas funcionan con el PIC32, ¿qué sentido tiene cambiar? Aunque el código se adapte completamente (no lo hará), todavía hay que acostumbrarse a la nueva cadena de herramientas y al IDE. ¿Qué sentido tiene? Cambiar por razones religiosas o para estar "basado en ARM" (o cualquier otra cosa) es una tontería. Necesitas tener una buena razón, pero no nos has mostrado ninguna.
0 votos
No he preguntado por el cambio. Hablé sobre la elección de una arquitectura diferente para otros proyectos, ya que estamos trabajando en múltiples proyectos + hay margen de mejora en nuestro diseño actual. El punto principal era sobre la curva de aprendizaje y los desafíos de trabajar con dos arquitecturas diferentes al mismo tiempo.
0 votos
Una cosa que encontré es que Atmel Studio proporciona una sincronización superior a la de MPLAB video de youtube