Estructura elegante para codificar sistemas embebidos en C

Algunas preguntas sobre el estilo de codificación eficiente usando C:

Estoy trabajando en controladores PIC de 8 bits usando C. Me gustaría saber ciertas cosas sobre el estilo y la estructura de la codificación.

  1. He leído que mantener un archivo de encabezado es un buen estilo de programación. Pero para funciones de segmentación con bastante facilidad para la depuración y el desarrollo futuro, ¿podemos mantener más de 2 archivos de encabezado? ¿O es propenso a errores? Confío en que la creación de archivos de encabezado y la declaración de prototipos de funciones eliminarán la externdeclaración en cada archivo fuente relacionado al hacerlo. (es decir, eeprom.h, datos.h)

  2. ¿Es una buena práctica mantener todas las variables en un archivo de encabezado separado? Además, ¿cómo maneja las variables que se necesitan en más de un archivo fuente?

Limpié esta pregunta lo mejor que pude. Espero no haber alterado las intenciones de la misma, ya que el inglés fue desafiante.

Respuestas (2)

Con respecto a la pregunta 2: se supone que las variables no deben definirse en un archivo .h. El propósito de un archivo de encabezado es declarar las funciones "públicas" y la estructura de datos utilizada en un archivo C, para que otros archivos C sepan cómo llamarlos/usarlos. Por definición, un archivo de encabezado se incluirá varias veces en un proyecto completo. Es por eso que los archivos .h no deben contener ningún código, o este código se duplicará (en realidad, la mayoría de las veces esto provoca un error de compilación). El único caso en el que una variable debe declararse en un archivo .h es una variable global compartida en varios archivos C, en ese caso, la variable se define en uno de los archivos C y se declara como externa en el archivo .h.

Acerca de las variables globales: la razón real por la que las variables globales no son tan buenas es porque evita que el código que las usa vuelva a entrar. Eso significa que el código no será compatible con recursividad ni subprocesos múltiples. En un PIC de 8 bits con una pila ridículamente pequeña, ninguna de esas técnicas tiene sentido, por lo que las variables globales no son tan malas. Sin embargo, es una práctica común evitar las variables globales cuando pueda, el código es más fácil de leer/depurar/reutilizar de esa manera.

El estilo de programación depende de la persona y de los estándares de codificación que esté siguiendo.

Prefiero los archivos de encabezado modulares. Cada módulo, digamos EEPROM, tendrá EEPROM.h e incluso si el módulo EEPROM se distribuye entre archivos, trato de usar un solo archivo de encabezado. Aunque se vuelve difícil, pero lo intento. Además, solo las funciones públicas se declaran en el archivo de encabezado, mientras que las privadas estarían solo en el archivo C. Esto ayuda en la modularidad del código.

No hay nada como tener múltiples archivos de encabezado que se vuelven propensos a errores. Pero sí, a veces resulta engorroso rastrear una función si hay varios encabezados para un módulo.

Sobre tu segunda pregunta,

Una buena práctica es que no debe tener variables globales :-) Intente mantener este recuento lo mínimo posible. Y tener todas las variables en un archivo hace que sea arriesgado que todas las variables sean accesibles para todos los archivos de su aplicación. Por lo tanto, hacer extern es mejor que mantener todo en un archivo de encabezado.

Si no tiene restricciones de memoria, haga las funciones Get() y Set(), es decir, haga funciones para leer el valor de una variable y establecer el valor de esa variable. Por esto, no necesita hacer que esas variables sean externas o incluirlas en el archivo de encabezado. También puedes hacerlos en línea para evitar saltos.

Lea este hilo sobre variables globales.

No estoy de acuerdo con su artículo n. ° 2, específicamente porque el autor habla de plataformas integradas, específicamente PIC de 8 bits, que tienen muchos recursos limitados, simplemente no puede orientar su código a objetos como lo ha descrito cuando solo tiene unos pocos cientos bytes de RAM disponibles.
@Madmanguruman Point anotó y editó la respuesta. Me perdí esa línea "PIC de 8 bits", pero es mejor usar un código parcialmente orientado a objetos para que sea fácil de entender y modificar. Preferiré este enfoque en los controladores basados ​​en ARM.
Me parece bien. Los ARM apenas tienen recursos limitados.
Utilicé un enfoque similar orientado a objetos en PIC de 8 bits (principalmente PIC18, para ser justos) durante muchos años. Es un mecanismo de programación defensivo muy efectivo y es más fácil de leer y mucho más seguro que llenar el código con declaraciones externas para acceder a las variables. Por mi dinero, cualquier uso de declaraciones externas para otra cosa que no sea la depuración indica codificación perezosa, y el código perezoso generalmente es un código no confiable.