¿Por qué la programación de sistemas integrados parece más difícil que la programación de sistemas?

No soy un programador de sistemas integrados, pero administro muchos de ellos. Además del hecho de que los diseños integrados generalmente le piden que haga más con menos, las quejas más comunes que escucho cuando adoptamos una nueva plataforma son:

  1. Mala / sin documentación . Los paneles integrados (o peor, personalizados) (tanto industriales como aficionados) a menudo tratan la documentación como una ocurrencia tardía, lo que deja a los desarrolladores en problemas cuando algo no funciona como se esperaba
  2. Falta de apoyo comunitario . Incluso las placas integradas más populares tienen pequeñas comunidades en comparación con el ecosistema x86, por lo que buscar en Google y esperar que aparezca una respuesta con frecuencia no funciona. Además, descubrimos que muchos de los miembros más activos de la comunidad están utilizando sus sistemas integrados en el trabajo, por lo que cuando cambian sus prioridades, a menudo abandonan la comunidad, dejando un vacío de experiencia.
  3. Herramientas no estándar . Somos una tienda de Linux, pero incluso los sistemas integrados que vienen con soporte de Linux directo del fabricante a menudo toman atajos o hacen cambios de software que dejan las cadenas de herramientas del desarrollador paralizadas (nuevamente, a menudo sin ninguna documentación que explique por qué o cómo solucionarlas).
  4. Las bibliotecas populares pueden faltar . Contrariamente a la opinión popular, muchos desarrolladores odian tener que reinventar la rueda.

Por lo general, se ‘considera’ porque, en la programación de sistemas integrados, se trata directamente con el hardware, que no es lo suficientemente inteligente como para decirle cosas como: “¡Hola! ¡No puedes escribir en este registro! ”. Por lo tanto, la depuración se convierte en un problema, pero hoy en día los compiladores, depuradores de hardware y otras herramientas se han vuelto tan inteligentes que es relativamente fácil encontrar sus errores.

En segundo lugar, la mayoría de los sistemas embebidos vienen con memoria limitada, por lo que siempre existe la limitación de memoria y debe programar en consecuencia. La memoria, la tachuela, las variables, etc., deben manejarse en consecuencia.

En tercer lugar, en el caso de la programación de sistemas, hay un sistema operativo que gestiona diferentes tareas y aplicaciones, si uno de ellos se porta mal, el sistema operativo lo mata. No existe tal cosa cuando está programando un hardware directamente, por lo que el programador debe ser muy meticuloso al escribir su código. Si algo falla, eso podría ser catastrófico para todo el sistema.

Primero tiene que responder la pregunta: “¿en qué parte de la pila de software está haciendo la programación de sistemas?”

Si está codificando en el nivel del núcleo y haciendo cosas como controladores de dispositivos, entonces puede estar interactuando directamente con las interfaces de hardware.

Aunque no tengo ninguna experiencia con sistemas embebidos, tengo una experiencia considerable, aunque anticuada, con la escritura de controladores de dispositivos a nivel de hardware. Las interrupciones de campo y la respuesta al estado de la máquina son comunes en este paradigma. Supongo que esto es similar a lo que ocurre en los sistemas integrados.

La interacción directa con los estados de la máquina y las instrucciones primitivas requiere muchos conocimientos técnicos profundos. Me tomó un par de años trabajar con eso todos los días para convertirme en un experto en eso. Eso fue después de que ya era un muy buen programador avanzado de lenguaje ensamblador.

Supongo que es algo personal, pero que he escuchado a mucha gente decir. Hay un par de razones, pero creo que la más común es que el desarrollo integrado tiende a ser una capa eliminada del desarrollador. Cuando escribe código de sistemas (por ejemplo, un servidor para una aplicación basada en socket o un nuevo comando de sistema de archivos), realiza su desarrollo, lo ejecuta, mira los resultados y luego revisa los registros. Con muchos proyectos de desarrollo integrados, debe descargar su imagen / código al dispositivo, ejecutarlo y tener una forma de observar lo que salió bien y lo que salió mal.

Si bien sé que no son populares en estos días, los depuradores pueden nivelar el campo de juego, pero a menudo son más difíciles de comenzar en el caso incrustado. Para un programa de sistemas, puedo hacer que publique registros más detallados (o tome el enfoque más arrogante de las condiciones de impresión en el código en cuestión) y adjunte un depurador de algún tipo al código en ejecución. También puedo ejecutar un generador de perfiles y un detector de fugas de memoria en el programa para buscar una amplia gama de problemas.

Para hacer lo mismo en el caso incrustado, podría tener que conectar conectores especiales a pines ocultos o hacer una conexión a través de un bus o red a un depurador especial construido. A menudo, las personas encuentran este paso tan propenso a errores como el desarrollo que intentan solucionar.

Al final, si logra que su configuración de entorno de compilación y prueba funcione sin problemas y repetidamente, no creo que incrustar sea más difícil que la programación de sistemas. En algún momento siento que son todo lo contrario, ya que el código de los sistemas tiende a tener que lidiar con un ecosistema más grande y complejo.

Porque generalmente lo es.

La complejidad es mayor ya que muchas veces se trata directamente con el hardware. Por ejemplo, puede que no haya tal cosa como abrir un archivo y escribir. En cambio, la interfaz es la página NAND sin procesar, que puede o no funcionar dependiendo de cuántas veces ya se haya escrito.