c++ - programacion - programación de microcontroladores pic en lenguaje c pdf
C++ en microcontroladores de pequeña huella (6)
Me parece que la gente se rehuye constantemente, o se opone vehementemente al uso de C ++ en los microcontroladores, pero no puedo, por mi vida, averiguar por qué. Si se mantiene alejado de las grandes bibliotecas de C ++ (p. Ej., STL) y no intenta utilizar funciones complicadas como RTTI o el manejo de excepciones, ¿existe realmente alguna diferencia notable entre C y C ++? ¿Tiene la herencia virtual un gran impacto en la complejidad o la huella? Pensaría que sería un poco más de memoria, pero la mayor parte de la complejidad sería manejada por el compilador, pero nuevamente no sé mucho sobre esa magia oscura. Simplemente no entiendo por qué las personas son bastante inflexibles sobre el uso de C, excepto quizás por las pocas arquitecturas para las que no hay compiladores de C ++ (si los hay). Parece que los beneficios de la modularización y las plantillas serían sencillos, incluso si no pudieras usar tu cin o cout.
Lo pregunto porque estoy investigando para algunos proyectos de hobby en los que me gustaría trabajar. Idealmente, me gustaría trabajar con C ++ estrictamente por la capacidad de modular las cosas de manera agradable, en lugar del enfoque "SomeClass_SomeMethod (struct object * this ...) de C para la" orientación a objetos ". (Prefiero objetar a Pascal para estos proyectos, pero desgraciadamente el soporte para ese lenguaje no es exactamente estelar ...) Preferiría evitar el cambio a un microprocesador mucho más capaz porque A. para los proyectos que estoy haciendo, no necesito un montón de recursos ... No planeo escribir filtros de Kalman de 60 estados ni codificar video B a 1080p (el verdadero disparador) Me gustaría usar procesadores disponibles en paquetes DIP y QFP. Me gustaría tener la capacidad de hacer prototipos sin soldar ni hornear nada en mi horno tostador.
¿Alguna idea?
¿hay realmente alguna diferencia notable entre C vs C ++?
En mi experiencia hay una gran diferencia en el uso de RAM.
Por ejemplo: Actualmente estoy trabajando en C ++ para un ARM uC con 512KB FALSH y 64KB de RAM. El uso de la memoria RAM debe ser inferior a 30 kB, pero es el doble porque cada constante termina en la memoria RAM. Esto se debe a que es casi imposible (al menos con los objetivos de GCC y ARM) convencer al compilador de que deje a los miembros de la clase const en FLASH. La única forma de lograr esto es mediante el uso de clases sin constructor, declarando públicos a todos los miembros const y utilizando listas de inicialización agregadas.
Para empeorar las cosas, C ++ no permite que se nombre a los miembros en la lista de inicializadores como puede hacer en C simple:
struct St { int b; int a[3]; }; static const struct St st_array[2] = { [1] = { .a = {1,2,3,}, .b = 10, }, // deliberately disordered to [0] = { .b = 8, .a = { 4,5,6,}, }, // illustate the value of names. };
Todos los compiladores C colocarán estas constantes en el segmento de "datos constantes" (en FLASH).
En C ++ deberías hacer esto:
class ClassA // cannot have constructor or destructor { public: // const data cannot be private for aggregate initialization const int b; const int a[3]; private: int priv_fn(int i); public: int pub_fn(); }; static ClassA classA_array[2] = { { 3, { 8, 9,10,}, }, // aggregate initialization { 4, { 9,10,11,}, }, // better get the order right!!! };
Dependiendo de su compilador, incluso esto puede no garantizar que las constantes permanezcan en FLASH.
Y sí, lo sé, con C ++ 0x puede usar las listas de inicialización con el constructor y eso es lo que estoy haciendo, pero en el momento en que tiene un constructor al que se llama en tiempo de ejecución, todas las inicializaciones se vuelven dinámicas.
El informe técnico (gracias MSalters) confirma esto:
7.1.2 Constructores y objetos ROMable En general, los objetos const de clases con constructores deben inicializarse dinámicamente. Sin embargo, en algunos casos, la inicialización en tiempo de compilación podría realizarse si el análisis estático ...
La conclusión es que tal compilador no tengo este análisis estático disponible y si tengo que limitarme a clases sin constructor con consts públicas y sin nombrar inicializadores, entonces también podría escribir en plano (y orientado a objetos) DO.
Básicamente, en C ++ solo paga por lo que usa más allá de lo que sería el código compilable de C, y algunos de los extras son gratuitos.
El mayor problema con algunos compiladores de C ++ para objetivos pequeños es la integridad de las implementaciones de C ++ disponibles o la disponibilidad de un compilador de C ++.
EETimes / Embedded.com ha publicado varios artículos sobre el tema a lo largo de los años:
- Mejor incluso en los niveles más bajos - Dan Saks
- C ++ incrustado produce un código más pequeño y más rápido - John Carbone
- Por qué C ++ es una alternativa viable a C en el diseño de sistemas integrados - Fergus Bolger
- Razones pobres para rechazar C ++ - Dan Saks
- Uso eficiente de C ++ en aplicaciones integradas - Mentor Graphics / Cesar A. Quiroz
- ¿La ineficiencia de C ++, realidad o ficción? - Sistemas IAR / Anders Lundgren
El punto que señala la mayoría de estos artículos es que no necesariamente debe usar todo C ++ en un sistema integrado y estos miden o explican el costo en términos de memoria, velocidad y determinismo de varias características. Las partes que utilice dependerán de la naturaleza de su aplicación (si tiene restricciones en tiempo real, por ejemplo) y de los recursos disponibles y el rendimiento de su plataforma de destino.
El comité de C ++ escribió un informe técnico (gratuito) sobre este tema.
La gente de C ++ pregunta constantemente "¿por qué estás usando C y no C ++?". Me gustaría saber por qué debería usar C ++ y no C.
En primer lugar, uno debe darse cuenta de que estos dos idiomas son antiguos y ambos tienen una sintaxis horrible . El debate a menudo parece estar centrado en "debes usar C ++, porque C ++ es moderno y C es antiguo". En realidad, el debate es sobre el sabor favorito de la carne de dinosaurio. En lugar de exigir un lenguaje moderno adecuado para las aplicaciones integradas, las personas predican C ++, que nunca fue nada más que un extraño lenguaje híbrido temporal con compatibilidad con C, en espera de que se invente un lenguaje mejor.
Segundo, hay un mito que dice que C ++ está orientado a objetos y C no. La orientación a objetos de la palabra de moda se reduce a tres cosas:
- 1) Diseño modular con objetos autónomos, que no están estrechamente acoplados a ninguna otra cosa. Este es un atributo muy importante de cualquier programa.
- 2) Encapsulación privada de datos y alcance reducido de datos. Este es un atributo bastante importante de cualquier programa.
- 3) Polimorfismo de clases: clases que heredan otras clases y se comportan de manera diferente cuando se heredan. El polimorfismo es bastante útil, pero mucho menos en sistemas integrados pequeños.
1) se puede lograr completamente tanto en C como en C ++, es una cuestión de diseño de programa en lugar de sintaxis de idioma. ¡Y este es el atributo OO más importante por mucho! Desafortunadamente, no hay nada en ningún idioma que le diga cómo diseñar su programa. No hay nada en C ++ que conduzca automáticamente a un mejor diseño modular, todo está en manos del programador.
2) se puede lograr tanto en C como en C ++. Ambos idiomas han reducido el alcance de los datos. En C, la encapsulación privada se realiza mediante una sintaxis algo horrible con la palabra clave estática en las variables de alcance del archivo. En C ++, se realiza de forma más elegante con privado / protegido.
3) se puede lograr tanto en C como en C ++. Ambos lenguajes tienen una sintaxis horrible para esto. En C, jugarías con estructuras y interfaces de funciones para lograrlo. En C ++, puede hacerlo de formas menos horribles a través del legado y haciendo las funciones "virtuales". Sin embargo, la sintaxis de C ++ y la implementación necesaria siguen siendo un gran lío, aunque un poco mejor que la forma en C.
Ningún idioma te dará cosas relacionadas con OO de manera bonita y elegante. Lo que C ++ gana con una sintaxis algo menos compleja, se pierde cuando comienza a vadearse a través de un comportamiento no definido / no especificado / definido por la implementación.
Parece que todo el argumento de OO no es un gran problema, C ++ no es una gran mejora cuando se trata de OO. Entonces, ¿qué más hay en C ++ que necesitaría en mi sistema integrado? Destaca una cosa: la sintaxis estandarizada de ensambladores en línea. Esta es quizás la mayor ventaja que C ++ tiene sobre C, para los sistemas integrados.
Aparte de eso, las características, STL, plantillas, RTTI, sobrecarga de overator, sobrecarga de funciones, etc., son características más o menos inútiles sin las cuales uno puede vivir.
Luego, al final, la realidad llega a abofetearte: hay muy pocos compiladores incrustados, si es que hay alguno, que lograron implementar C ++ completamente de acuerdo con el estándar.
Para "huella pequeña" en lo que a mí respecta es el código inflado. Si su código necesita residir en una pequeña pieza de hardware, una instancia de la clase de plantilla
std::vector<int>
tiene su propio conjunto de instrucciones, separado de
std::vector<double>
Por lo tanto, cada vez que creas un nuevo tipo de vector, el compilador copia y pega efectivamente el código para crear la nueva clase, con su propio conjunto de funciones, duplicando cada instrucción. Si tiene limitaciones en la cantidad de memoria para almacenar instrucciones, esto podría ser problemático muy rápido. Se ha vuelto problemático para las personas en sistemas no integrados.
Sin embargo, en términos de rendimiento en tiempo de ejecución, creo que no tienes mucho de qué preocuparte . En algunos casos, como la clasificación, C ++ supera a C.
Por supuesto que varía mucho.
No usaría la herencia virtual en un MCU "pequeño". Ni siquiera usaría un montón en absoluto.
Las características de C ++ que parecen más atractivas en ese espacio son los espacios de nombres (para compartir componentes de software entre programas para MCU en red), plantillas (por ejemplo, para parametrizar protocolos a través de puertos de E / S) y mejoras semánticas generales como static_cast
y promociones integrales menos generales .
Pero, al menos en mi breve incursión en el profesional embebido, simplemente no existía un compilador de C ++ adecuado, y la mierda que estaba disponible costaba miles de dólares al año.
GCC es el compilador de C ++ más capaz y ampliamente disponible para plataformas integradas. Sin embargo, su soporte de plataforma es muy desigual. Si tiene recursos ilimitados, EDG anuncia que brindarán soporte superior a Comeau a "su" plataforma integrada.