programación de microcontroladores vs programación orientada a objetos

11

He realizado una programación básica orientada a objetos con C ++ (creando un B-Tree, algoritmos de hash, listas dobles enlazadas) y he realizado pequeños proyectos en C (como hacer una calculadora científica, etc.)

¿Qué tan diferente es la programación de hardware (específicamente para microcontroladores) de la programación orientada a software / objeto en términos de la mentalidad y el "pensamiento" que el programador debe tener?

¿Es generalmente considerado uno más difícil que el otro mi mayor número de personas?

Con mi experiencia (como se describió anteriormente), ¿necesitaría mucha preparación para entrar en la programación de hardware o puedo sumergirme sin demasiada preparación?

rrazd
fuente
44
La mayor curva de aprendizaje será cómo manejar el hardware específico en su micro. Eso implicará estudiar detenidamente las hojas de datos durante horas. Desafortunadamente, no hay una salida fácil.
drxzcl
@rrazd, noté que has incluido la etiqueta arduino. ¿Es esto porque quieres usar el lenguaje de cableado y las bibliotecas de arduino? ¿O va a escribir sus aplicaciones integradas en C puro? Si tiene la intención de seguir con el entorno arduino, es bastante seguro y fácil de jugar, ya que han hecho algunas abstracciones lejos del hardware.
Jon L
@ Jon planeo usar una placa arduino para empezar. ¿No es similar al lenguaje C? Pensé que involucraba los mismos conceptos básicos ...
2011
1
Me pregunto si quiere decir lo que mucha gente llamaría 'programación de E / S', o si anticipa reorganizar el hardware con código. El arduino es decididamente el primero; este último sería el dominio de los FPGA.
JustJeff
1
@rrazd: cambié el título; "programación de hardware" se parece demasiado a HDL (lenguaje de descripción de hardware), por ejemplo, VHDL y Verilog, que se utilizan para programar FPGA y CPLD.
stevenvh

Respuestas:

10

Tendrá que abandonar por completo el paradigma orientado a objetos cuando trabaje con la mayoría de los microcontroladores.

Los microcontroladores generalmente están limitados por el registro y la RAM, con velocidades de reloj lentas y sin rutas de canalización / código paralelo. Puede olvidarse de Java en un PIC, por ejemplo.

Tienes que entrar en una mentalidad de lenguaje ensamblador y escribir procedimentalmente.

Debe mantener su código relativamente plano y evitar la recurrencia, ya que las limitaciones de RAM a menudo pueden provocar problemas de pila.

Debe aprender a escribir rutinas de servicio de interrupción que sean eficientes (generalmente en lenguaje ensamblador).

Es posible que deba refactorizar partes del código manualmente, en lenguaje ensamblador, para implementar una funcionalidad que el compilador no admite (o no admite).

Debe escribir un código matemático que tenga en cuenta el tamaño de la palabra y la falta de capacidades de FPU de la mayoría de los microcontroladores (es decir, hacer una multiplicación de 32 bits en un micro = mal de 8 bits).

Es un mundo diferente. Para mí, tener conocimientos de informática o de programación profesional puede ser un obstáculo tan grande como no tener ningún conocimiento cuando se trata de microcontroladores.

Adam Lawrence
fuente
1
No tiene que abandonar por completo el paradigma orientado a objetos, pero en micros más pequeños puede ser necesario abandonar las implementaciones de objetos pesados ​​y realmente pensar cuál es la mejor manera de resolver cada problema. A menudo eso es de procedimiento, pero los objetos livianos, bien implementados (generalmente a mano), a veces pueden reducir el tamaño de los proyectos complicados de microcontrol.
Chris Stratton
66
Todo esto es cierto excepto abandonar la orientación a objetos. Probablemente no utilizará un lenguaje con características OO, pero eso no descarta la orientación a objetos. Para los microcontroladores, va a escribir controladores para todos los periféricos de hardware (ADC, controladores de bus serie, PWM, etc., etc.). Dicho controlador siempre debe escribirse de manera orientada a objetos para que sea 1) autónomo y no conozca / no le importe el resto del programa, y ​​2) implemente la encapsulación privada para que el resto del programa no pueda entra y juega con él. Esto es 100% posible en C y no afectará el rendimiento.
Lundin
1
Estoy totalmente en desacuerdo con la primera oración, todos mis proyectos de microcontroladores fueron construidos con C ++ y un enfoque orientado a objetos, y los micros que utilizamos no eran muy grandes (32kB de ROM), el cargador de arranque orientado a objetos también estaba en menos de 2kB, I Realmente no veo limitación. No puedes hacer cosas locas, pero el diseño puede orientarse a objetos sin problema.
Arsenal
@ Nota del Arsenal Dije 'más', y tenga en cuenta que está comentando un hilo de cuatro años. :)
Adam Lawrence
Estoy completamente en desacuerdo con la primera y la última oración. Y también el ensamblaje se usa muy raramente y, principalmente, solo para MCU de 8 bits (solo consulte este foro, ¿cuántas publicaciones con código de ensamblaje puede encontrar?). Ciertamente puede y (en mi humilde opinión) debe escribir en estilo OO para MCU de 32 bits
Andrejs Gasilovs
10

Necesita pensar en varias cosas:

  • Usarás C como lenguaje
  • Todavía puede crear una sensación de orientación a objetos utilizando punteros de función para poder anular funciones, etc. He utilizado este método en proyectos pasados ​​y actuales y funciona muy bien. Entonces OO está parcialmente allí pero no en sentido C ++.

Hay otras limitaciones que entrarán en juego, como la velocidad y la memoria limitadas. Entonces, como pauta general, evito:

  • Usando el montón, si hay una manera de resolver el problema sin Malloc, lo hago. Por ejemplo, preasigno buffers y solo los uso.
  • Reduzco intencionalmente el tamaño de la pila en la configuración del compilador para enfrentar los problemas de tamaño de la pila desde el principio, lo optimizo con cuidado.
  • Supongo que cada línea de código será interrumpida por un evento, así que evito el código no reentrante
  • Supongo que incluso las interrupciones están anidadas, así que escribo ese código en consecuencia
  • Evito usar el sistema operativo a menos que sea necesario. El 70% de los proyectos integrados realmente no necesitan un sistema operativo. Si debo usar un sistema operativo, solo uso algo con el código fuente disponible. (Freertos, etc.)
  • si estoy usando un sistema operativo, casi siempre abstraigo cosas para poder cambiar el sistema operativo en cuestión de horas.
  • Para los controladores, etc. Solo usaré las bibliotecas proporcionadas por el proveedor, nunca manipulo los bits directamente, a menos que no tenga otra opción. Esto hace que el código sea legible y mejora la depuración.
  • Miro los bucles y otras cosas, especialmente en ISR, para asegurarme de que sean lo suficientemente rápidos.
  • Siempre tengo algunos GPIO a mano para medir cosas, cambio de contexto, tiempo de ejecución de ISR, etc.

La lista continúa, probablemente estoy por debajo del promedio en términos de programación de software, estoy seguro de que hay mejores prácticas.

Franco
fuente
3
+1 para "puedes usar paradigmas OO si quieres". Lo que debe verificar en la puerta no es un diseño OO. OOD es solo una filosofía que lo alienta a mantener juntos el código y los datos relacionados. Lo que debe dejar atrás es la forma en que OO se implementa en los sistemas empresariales, con múltiples capas de abstracción, inversión de control y todo ese jazz. La tarea de su firmware es conducir el hardware, eso es todo.
drxzcl
7

Hago ambas cosas, así que aquí está mi punto de vista.

Creo que la habilidad más importante en incrustación es su capacidad de depuración. La mentalidad requerida es muy diferente, ya que mucho más puede salir mal, y debe estar muy abierto a considerar todas las diferentes formas en que lo que está tratando de hacer puede salir mal.

Este es el mayor problema para los nuevos desarrolladores integrados. La gente de PC tiende a tenerlo más duro, ya que están acostumbrados a trabajar tanto para ellos. Tienden a perder mucho tiempo buscando herramientas para hacer cosas por ellos (pista: no hay muchas). Hay un montón de golpes en las paredes una y otra vez, sin saber qué más hacer. Si siente que se está atascando, retroceda y descubra si puede identificar qué podría estar saliendo mal. Revise sistemáticamente su lista de problemas potenciales hasta que la resuelva. De este proceso se deduce directamente que debe limitar el alcance de los problemas al no cambiar demasiado a la vez.

Las personas integradas con experiencia tienden a dar por sentado la depuración ... la mayoría de las personas que no pueden hacerlo bien no duran mucho (o trabajan en grandes empresas que simplemente aceptan que "el firmware es difícil" como respuesta a por qué una determinada característica es años tarde)

Está trabajando en un código que se ejecuta en un sistema externo a su sistema de desarrollo, con diferentes grados de visibilidad en su objetivo de plataforma en plataforma. Si está bajo su control, busque ayudas de desarrollo para ayudar a aumentar esta visibilidad en su sistema de destino. Use puertos seriales de depuración, salida de depuración de bit bitging, la famosa luz intermitente, etc. Ciertamente, como mínimo, aprenda cómo usar un osciloscopio y use el pin I / O con el 'alcance para ver cuándo ciertas funciones entran / salen, los ISR se disparan, etc. He visto a la gente luchar durante literalmente años más de lo necesario simplemente porque nunca se molestaron en configurar / aprender a usar un enlace de depurador JTAG adecuado.

Es mucho más importante ser muy consciente de exactamente qué recursos tiene en relación con una PC. Lea las hojas de datos cuidadosamente. Considere el 'costo' de recursos de todo lo que está tratando de hacer. Aprenda trucos de depuración orientados a los recursos, como llenar el espacio de la pila con un valor mágico para rastrear el uso de la pila.

Si bien se requiere cierto grado de depuración para PC y software embebido, es mucho más importante con embebido.

Darron
fuente
5

Supongo que su experiencia en C ++ está basada en PC.

Un error a menudo cometido por los programadores al pasar de la PC al microcontrolador es que no se dan cuenta de cuán limitados pueden ser los recursos . En una PC, nadie lo detendrá cuando cree una tabla con 100 000 entradas o escriba un programa que compile a 1 MB de código de máquina.
No son los microcontroladores que tienen una gran cantidad de recursos de memoria, especialmente en la parte alta, pero aún así es muy lejos de lo que va a ser usado para. Para un proyecto de pasatiempo, probablemente siempre puedas ir al máximo, pero en un proyecto profesional a menudo te verás obligado a trabajar con el dispositivo más pequeño porque es más barato .
En un proyecto estaba trabajando con una TI MSP430F1101. 1 KB de memoria de programa, 128 bytes de configuración Flash, 128 bytes de RAM. El programa no cabía en el 1K, así que tuve que escribir una función de 23 bytes en la configuración Flash. Con estos pequeños controladores, calcula por byte . En otra ocasión, la memoria del programa era 4 bytes demasiado pequeña. Boss no me dejaba usar el controlador con más memoria, sino que tenía que optimizar un código de máquina ya optimizado (ya estaba escrito en el ensamblador) para que quepa los 4 bytes adicionales. Obtienes la imagen.

Dependiendo de la plataforma en la que esté trabajando, tendrá que lidiar con E / S de muy bajo nivel . Algunos entornos de desarrollo tienen funciones para escribir en una pantalla LCD, pero en otros está solo y tendrá que leer la hoja de datos de la pantalla LCD de principio a fin para saber cómo controlarla.
Es posible que deba controlar un relé, que es más fácil que una pantalla LCD, pero requerirá que vaya al nivel de registro del microcontrolador. Nuevamente una hoja de datos o manual de usuario. Tendrá que conocer la estructura del microcontrolador, que encontrará en un diagrama de bloques, nuevamente en la hoja de datos. En los días del microprocesador hablamos de un modelo de programación., que era básicamente una alineación de los registros del procesador. Los microcontroladores actuales son tan complejos que una descripción de todos los registros puede tomar la mejor parte de una hoja de datos de 100 páginas. IIRC solo la descripción del módulo de reloj para el MSP430 tenía 25 páginas.

μ

Microcontroladores a menudo se programan en C . C ++ es bastante hambriento de recursos, por lo que generalmente está fuera. (La mayoría de las implementaciones de C ++ para microcontroladores ofrecen un subconjunto limitado de C ++). Como dije, dependiendo de la plataforma, puede tener una amplia biblioteca de funciones disponibles que podrían ahorrarle bastante tiempo de desarrollo. Vale la pena tomarse un tiempo para estudiarlo, puede ahorrarle mucho tiempo más adelante si sabe lo que hay disponible.

stevenvh
fuente
He escrito juegos para el Atari 2600, que es una plataforma bastante limitada; mi primer juego publicado fue esencialmente código 4K (dado que tenía un carrito de 32K, agregué algunos extras adicionales, pero la versión 4K era totalmente jugable); La RAM es de 128 bytes. Me parece interesante contemplar que en el año en que escribí ese juego (2005), se publicaron otros juegos que, literalmente, eran un millón de veces más grandes.
supercat
@supercat - Sí, pero eso era de esperar, ¡en 2005 el Atari 2600 ya tenía 200 años! Nunca he jugado juegos de acción como FPS, pero cuando veo lo que se necesita para jugarlos, una GPU mucho más poderosa que tu CPU, tanto programática como eléctricamente, no puedo evitar sacudir mi cabeza :-). Jugué al ajedrez (Sargon) en un TRS-80 IIRC de 16k. El simulador de vuelo de mi hermano no necesitaba más.
stevenvh
No tiene casi 200 años. Debutó en 1977, por lo que ni siquiera era 30. Aunque estoy de acuerdo en que eso fue hace eones en términos tecnológicos, todavía estoy impresionado por el hecho de que no hay solo un aumento de cien, ni un aumento de mil veces , pero un MILLÓN de veces en RAM y tamaño de código. La velocidad no ha recibido tanto impulso, ya que el 2600 era 1.19MHz y los sistemas más nuevos solo están en el rango bajo de GHz. Pueden hacer mucho más por ciclo que el 2600 (que podría, y tenía que, generar 1/76 de una línea de video cada ciclo), pero no creo que sean 1,000,000x tan rápido.
supercat
3

"programación de hardware" puede significar muchas cosas. Programar un chip muy pequeño (piense en 10F200, 512 instrucciones, unos pocos bytes de RAM) puede ser casi como diseñar un circuito electrónico. Por otro lado, la programación de un gran microcontrolador Cortex (1 Mb FLASH, 64 kB RAM) puede ser muy similar a la programación de PC / GUI, utilizando un gran kit de herramientas GUI. En mi humilde opinión, un buen programador integrado / en tiempo real necesita habilidades tanto del lado de la ingeniería del software como del lado del diseño del circuito. Para el uC más grande, C ++ es una buena opción de lenguaje, para los más pequeños, C podría ser la única opción. El conocimiento de ensamblaje puede ser útil, pero no recomendaría hacer proyectos serios por completo en ensamblaje.

He realizado un gran trabajo integrado con personas de ambos lados (SWI y EE). Generalmente prefiero a las personas SWI, siempre que tengan algo de experiencia con la programación de subprocesos múltiples.

Su pregunta parece que quiere sumergirse en la programación integrada. Por supuesto, hazlo. Para los aspectos de bajo nivel (la interfaz de los periféricos en su chip y el hardware que lo rodea) necesitará aprender algunas habilidades nuevas, pero es mucho trabajo sin muchos conceptos nuevos. Para las capas superiores de sus proyectos, puede recurrir a su conocimiento existente.

Wouter van Ooijen
fuente
1

Para cada método de biblioteca arduino que llame hay una gran cantidad de código C / C ++ que lo hace posible, simplemente está bien empaquetado para que lo use como API. Eche un vistazo al código fuente de arduino en el directorio hardware / arduino / * y verá todo el C / C ++ escrito para usted que interactúa directamente con los registros del microcontrolador AVR. Si su objetivo es aprender a escribir cosas como esta (directamente para el hardware), entonces hay mucho que cubrir. Si su objetivo es hacer que algo funcione con sus bibliotecas, entonces puede que no haya mucho de qué hablar, ya que la mayor parte del trabajo duro se realiza para usted y sus bibliotecas y el entorno de desarrollo son muy fáciles de usar.

Sin embargo, algunas reglas generales cuando se trabaja con dispositivos con recursos limitados que podrían aplicarse al entorno arduino u otros:

Tenga en cuenta la cantidad de memoria que está utilizando. Tanto el tamaño del código (que va a la memoria flash) como el uso de RAM estática (constantes en su código que siempre existirán en la RAM). Yo diría que el uso de RAM estática es un poco más importante al comenzar, ya que es fácil pasarlo por alto. No es raro que tenga solo 1000 bytes para trabajar con su pila, montón y constantes. Sea prudente en cómo lo gasta, así que evite cosas como largas matrices de enteros (4 bytes cada una) cuando sean suficientes bytes o caracteres sin signo (1 byte cada uno). Otra respuesta aquí cubre algunos otros puntos importantes muy bien, así que me detendré aquí, principalmente quería aclarar que hay mucho que cubrir si no está utilizando la biblioteca arduino y escribiendo sus propias bibliotecas C.

Jon L
fuente
0

Con respecto a la programación de microcontroladores vs OOP, no son algo opuestos. Es cierto que todas las bibliotecas de proveedores están en C simple, pero todas las plataformas también admiten C ++ OOP. Los desarrolladores pueden construir y construir bibliotecas de alto nivel C ++ y firmware del dispositivo además de eso. El buen ejemplo son las bibliotecas Arduino, oficiales y construidas por el usuario, principalmente clases de C ++. Quizás no todas las ventajas de OOP se pueden utilizar por completo en un entorno integrado, pero las ventajas conocidas de C ++ vs C también son válidas aquí.

En cuanto a la mentalidad y el pensamiento, como se señaló en otras respuestas, los microcontroladores son plataformas con recursos muy limitados (especialmente en RAM, menos en velocidad), cosas como la asignación dinámica de memoria, las excepciones de C ++ generalmente se descartan. Dado que se elige el hardware correcto, es fácil adoptar estas limitaciones y usar otras técnicas (también ampliamente utilizadas en otras plataformas).

En mi opinión, el desafío más difícil podría ser una dimensión adicional más que se encuentra en la programación integrada: el tiempo. Esto se debe a que, por lo general, el software integrado se ocupa mucho de eventos en tiempo real, protocolos estrictamente cronometrados para controlar el hardware periférico y la tarea general en sí misma (estos son algunos paralelos en otras plataformas de "alto nivel" también, como las aplicaciones de subprocesos múltiples).

Esté preparado para leer muchas hojas de datos cuando trabaje con hardware nuevo. Supongo que podría estar relacionado con la parte de la pregunta de "mentalidad" :) Seguramente se necesitarían algunos conocimientos de EE y hardware.

También me gustaría señalar que en estos días el desarrollo de software integrado no requiere lenguaje ensamblador. De hecho, Java (BTW es OOP por defecto) ya está aquí y se está fortaleciendo (al menos para alguna clase de dispositivos integrados, por ejemplo, dispositivos IoT, podría tener un futuro muy brillante).

Flanker
fuente
En términos de preocupaciones, aquellos en torno a la (re) asignación de memoria dinámica tienden a ser un mayor impedimento para la OO tradicional que el tiempo .
Chris Stratton
Quizás estás en lo cierto. Pero hay personas que programaron en los años 80-90 para el software MSDOS en modo real, con 64K (segmento de memoria de datos) de espacio RAM disponible y para ellos era "natural". Quizás la PC MSDOS tenía un entorno más "integrado" que el STM32F4 de hoy :)
Flanker
El STM32F4 generalmente tiene más memoria de programa en forma de flash, pero la PC generalmente viene con mucha más memoria RAM para almacenar objetos de tiempo de ejecución mutables. Si bien todo el puntero lejano forzado por el direccionamiento segmentado fue un problema, ambos carecen de una verdadera MMU, y eso va a ser una preocupación aún mayor en el sistema con menos RAM, que es el STM32F4. Además, los tiempos de funcionamiento de la PC tienden a ser más cortos y las tasas de fallas aceptables son más altas.
Chris Stratton