usa - Escritura de firmware: ¿montaje o alto nivel?
una característica de los lenguajes de alto nivel (16)
Definitivamente iré con C. Es más rápido y crea un software más confiable. Asamblea tiene muy poco que ofrecer y en pocas ocasiones. Ten en cuenta que en C:
- Podrías fácilmente codificar el puerto desde plataformas existentes, incluso desde PC.
- Puede desarrollar en un lenguaje de alto nivel sin comprometer la velocidad de ejecución o el tamaño del código. Siempre que haya disponible un compilador de calidad (hay muchas opciones para PIC18), lo más probable es que sea mejor con C que con el ensamblaje artesanal.
- Es mucho más fácil depurar, probar y mantener el código. C produce un código más confiable.
Otra cosa que específicamente tiene que ver con PIC18. No tendrá que lidiar con la arquitectura de PIC no intuitiva y cosas como BANCOS DE MEMORIA.
Relacionado con:
- Prueba de firmware
- iniciar un simulador / emulador de microcontrolador
- Interpretación del código de ensamblaje
Si está escribiendo código para un microcontrolador, ¿hay alguna diferencia real si escribe en ensamblador o C o algún otro lenguaje de alto nivel? Si escribió el código C, ¿cómo lo compilaría?
Gracias
El montaje puede en muchos casos ser más rápido; cuando estás en un escritorio, los compiladores tienden a optimizarse hasta el punto de que el montaje manual rara vez es una necesidad, pero en el mundo de uC, a menudo lo es. Además, si necesita escribir rutinas de manejo de interrupciones y cosas por el estilo, a menudo no puede hacerlo en C.
En cuanto a la compilación, busque en Google un compilador de C para su objetivo.
He tenido una buena experiencia con compiladores IAR C para 8051 en el pasado.
Mi enfoque reciente siempre ha sido este:
Escríbalo en C con un buen compilador de optimización, y SÓLO ENTONCES si hay un problema con el tamaño o la velocidad, considera volver a escribir ciertas partes en el ensamblador.
Sin embargo, desde que tomé este enfoque, nunca tuve que escribir una sola línea de ensamblador ...
La mejor opción es, probablemente, codificar en C, y para las pocas instancias en las que necesita optimizar manualmente y puede hacer un mejor trabajo que el compilador, debe codificar el ensamblado en sus archivos c.
Un problema con el que me encontré con el ensamblaje de escritura para un microcontrolador es la necesidad de tener mucho cuidado con la forma en que se diseñó el código. Tener una mesa de saltos cruzar los límites de la memoria y hacer que tu código salte a lugares realmente extraños es bastante inquietante. Codificando en C, el compilador cubre esa base para usted.
Varios comentarios:
1) Absolutamente no ensamblado a menos que las restricciones de rendimiento u optimización lo justifiquen. Las siguientes métricas van por el techo con ensamblaje:
- hora de codificarlo
- es hora de depurarlo
- tiempo para probarlo
- tiempo para documentarlo
- tiempo para descubrir (1 año después) qué era lo que estabas haciendo cuando lo codificaste
- posibilidades de cometer un error
2) Mi preferencia sería C ++ en lugar de C para su encapsulación del espacio de nombres y su facilitación de las prácticas orientadas a objetos en tiempo de compilación . C tiene demasiadas oportunidades para las variables globales y las colisiones del espacio de nombres. (Java en tiempo real sería bueno, pero por lo que entiendo, sus requisitos todavía son bastante altos)
O más bien un subconjunto de C ++: excluir excepciones, funciones virtuales, identificación de tipo de tiempo de ejecución, también asignación de memoria dinámica en la mayoría de los casos, básicamente cualquier cosa que no se especifique en tiempo de compilación, ya que normalmente requerirá muchos recursos adicionales durante el tiempo de ejecución. Esa es la "hinchazón" de C ++.
He utilizado compiladores de TI e IAR para C ++, para los microcontroladores TMS320 y MSP430 (respectivamente) y con la configuración de optimización adecuada, hacen un trabajo fantástico para reducir los gastos generales que se pueden esperar de C ++. (Especialmente si lo ayudas con un uso juicioso de la palabra clave en inline
)
Incluso he usado plantillas para algunos de sus beneficios en tiempo de compilación que promueven la buena reutilización del código: por ejemplo, escribir un único archivo de código fuente para manejar CRC de 8 bits, 16 bits y 32 bits; y polimorfismo en tiempo de compilación para permitirle especificar el comportamiento habitual de una clase, y luego reutilizarlo, pero anular algunas de sus funciones. Una vez más, el compilador TI tenía una sobrecarga extremadamente baja con la configuración de optimización adecuada.
He estado buscando un compilador de C ++ para los Microchip PIC; la única compañía que he encontrado que produce uno es IAR. ($$$ ha sido un obstáculo, pero espero comprar una copia en algún momento) Los compiladores Microchip C18 / C30 son bastante buenos pero son C, no C ++.
3) Una advertencia específica sobre la optimización del compilador: puede / hará que la depuración sea muy difícil; a menudo es imposible pasar de un solo paso a través de un código C / C ++ optimizado y las ventanas de tu reloj pueden mostrar variables que no tienen correlación con lo que crees que debería contener el código no optimizado. (Un buen depurador podría advertirle que una variable en particular se ha optimizado para que no exista o no en un registro en lugar de una ubicación de memoria. Muchos depuradores no lo hacen.> :(
Además, un buen compilador le permite elegir / elegir la optimización en el nivel de función a través de #pragmas. Los que he usado solo te permiten especificar la optimización en el nivel del archivo.
4) Interconectando el código C para ensamblar: Esto generalmente es difícil. La forma más fácil es crear una función de código auxiliar que tenga la firma que desee, por ejemplo, uint16_t foo(uint16_t a, uint32_t b) {return 0; }
uint16_t foo(uint16_t a, uint32_t b) {return 0; }
, donde uint16_t
= unsigned short, solemos hacer explícito el # de bits. Luego, compile y edite el conjunto que produce (solo asegúrese de dejar las partes de inicio / salida del código) y tenga cuidado de no golpear ninguno de los registros sin restaurarlos después de que haya terminado.
El ensamblaje en línea generalmente puede tener problemas a menos que esté haciendo algo muy simple como habilitar / deshabilitar las interrupciones.
El enfoque que más me gusta es la sintaxis intrínseca del compilador / ASM extendida. El compilador C de Microchip está basado en el compilador C de GNU y tiene " ASM extendida " que le permite codificar bits de ensamblado en línea, pero puede darle muchos consejos para indicarle qué registros / variables está haciendo referencia y manejará todo el ahorro / restauración de registros para asegurarse de que su código de ensamblado "juegue bien" con el compilador de C. TI para el DSP TMS320 no los admite; tiene un conjunto limitado de intrínsecos que tienen algún uso.
He utilizado el ensamblaje para optimizar algunos códigos de control que se ejecutan con frecuencia, o para calcular sin (), cos () y arctan (). Pero de lo contrario me mantendría alejado del ensamblaje y me quedaría con un lenguaje de alto nivel.
Ir por c!
He trabajado para un gran fabricante de CE. La última vez que vi ensamblaje fue alrededor de 1996 en algunas rutinas de servicios de interrupción pequeños para la descodificación RC5 y RC6 y algoritmos de ajuste de TV. Después de eso siempre se usaba c, y C ++ (solo clases usadas, sin stl, excepciones o rtti). Tengo buenas experiencias con el antiguo compilador KEIL para 8051 y con el compilador de Greenhills (MIPS) y el conjunto de herramientas de VxWorks (basado en PowerPC).
Como dice Roddy, primero escriba en C y optimice en ensamble más tarde (si es necesario).
Esa es la línea de fondo si usa C puede optimizar a mano más tarde, yo no usaría nada que no sea C o ensamblador (sin C ++, etc.).
La clave es el conjunto de instrucciones del microcontrolador si está utilizando un PIC o incluso un 8051. Utilizaría el ensamblador solamente. Si es un compilador amigable, es como armar o avr o msp430, entonces usa C para guardar algo de tipeo pero probablemente tengas algunas rutinas en ensamblador por varias razones. Del mismo modo, es probable que desee evitar una biblioteca C, incluso newlib puede ser demasiado voluminoso, pedir prestado código o ideas de ellos, pero no solo vincular uno. Oh, volviendo a la pregunta, observe qué compiladores C están disponibles para el objetivo, otra vez brazo y avr no tendrás ningún problema. Posible msp también está bien. El hecho de que Keil o IAR le VENDERÁN un compilador no significa que deba comprarlo o usarlo, el resultado de pagar así como los compiladores gratuitos pueden ser terribles. Debe estar bien versado en el asm de todos modos y examinar la salida (es probable que tenga que escribir un desensamblador para hacer esto).
En pocas palabras (otra línea de fondo), no hay una respuesta global (evite algo más que C es una respuesta global) siempre depende de la plataforma, cuáles son sus recursos, cuál es su tarea, cuáles son los requisitos de rendimiento, cuáles son los requisitos de portabilidad. (si está verdaderamente integrado en un microcontrolador, la mayoría de ellos, por definición, no son portátiles), qué compiladores, depuradores, jtag, etc. están disponibles, incluso en lo que respecta a qué sistema operativo host está desarrollando puede ser un factor importante.
Hay otro momento en el que escribir en montaje puede ser necesario: si necesita realizar alguna prueba de RAM de bajo nivel o similar, que requiere un control absoluto sobre dónde se almacenan los datos.
Por ejemplo, el software que confirma a SIL -2 (Nivel de integridad de seguridad) y superior puede requerir comprobaciones continuas en la memoria RAM, con el fin de detectar cualquier posible corrupción de datos. El área de RAM que está comprobando no puede cambiar mientras se está comprobando, por lo que escribir la prueba en ensamblador le permite asegurarse de que esto sea cierto, por ejemplo, almacenando cualquier variable local en registros específicos o en otra área de RAM . Esto sería difícil, si no imposible, en C.
El código de inicio que pone a cero la RAM e inicializa variables estáticas distintas de cero también se puede escribir en ensamblador para el mismo escrito, aunque normalmente se proporciona este tipo de código.
Si está escribiendo código que es altamente dependiente de los periféricos específicos del dispositivo, y la cadena de herramientas que está utilizando no proporciona los elementos intrínsecos necesarios para utilizarlos de manera eficiente (como el crappy Freescale DSP563CC compilador), luego use el ensamblado.
Además de eso, creo que las reglas no escritas de usar ensamblaje frente a un lenguaje de alto nivel son más o menos las mismas que para el desarrollo de software de escritorio: mantener el código limpio, mantenible y optimizar el código de acceso con lenguaje de máquina.
Es una lástima que nadie haya mencionado Forth o Scheme hasta el momento. Ambos pueden ser apropiados para entornos pequeños, y pueden proporcionar impresionantes ganancias de productividad.
Definitivamente C, excepto cuando
la memoria del programa es extremadamente limitada. Digamos después de una minuciosa optimización de la mano de su código de ensamblador, logra encajar su programa en estos 1024 bytes de Flash, con 0 bytes restantes. En este caso, ningún compilador de C será bueno.
quieres tener control de tiempo absoluto. Si cualquier cantidad de latencia de interrupción es demasiado larga, tendrá que confiar en el ensamblador.
La codificación de ensamblaje es una cosa del pasado para PC, pero es muy relevante en embedded.
El ensamblaje de escritura en embedded es diferente al ensamblaje de escritura en PC. Los compiladores de PC son "mejores que los humanos" en la generación de instrucciones optimizadas. Los sistemas integrados a menudo tienen arquitecturas raras, y sus compiladores de optimización no son tan maduros como un compilador de optimización de PC.
La mayoría de los fabricantes de microcontroladores proporcionan algún tipo de compilador cruzado en el que puede compilar el código en su PC y luego transferirlo al microcontrolador.
Por qué C?
Una ventaja de C es que su código será más fácil de transferir a otros microcontroladores en el futuro. La historia de la informática ha demostrado que el código generalmente dura más que las implementaciones de hardware.
Una segunda ventaja son las estructuras de control (if, for, while) que hacen que el código sea más legible y mantenible.
¿Por qué lenguaje ensamblador?
Puede realizar optimizaciones artesanales.
Veredicto
Como suele ser el caso con este tipo de preguntas, las concesiones dependen en gran medida del uso específico.
Tenga en cuenta que a menudo es posible mezclar los dos haciendo llamadas de ensamblaje dentro del código C, para que pueda encontrar el equilibrio adecuado para su proyecto.
Específico para el hardware PIC
Parece que no tienes la opción de GCC con la mayoría del hardware PIC. Por otro lado, como señaló un comentador, el compilador Microchip C30 para el PIC24 de 16 bits y dsPIC33 es gcc.
PIC aún no es compatible con SDCC .
Nueva información: de acuerdo con un comentario, SDCC tiene soporte viable para PIC.
Hay algunas otras opciones de código abierto, pero no tengo experiencia con ellas.
Plain C o Pascal, Modula2. Pero debido a la disponibilidad del compilador eso significa C.
Los extras de C ++ y similares son solo interesantes por razones de estilo, ya que la asignación dinámica y el tamaño del programa suelen ser muy limitados.
También un tiempo de ejecución más complicado puede ser un problema si tus aplicaciones se vuelven difíciles.
Assembler también puede ser útil, pero solo si vende cantidades realmente gigantescas, y un firmware más pequeño significa un chip más pequeño y económico (menos flash) y el tamaño del programa es supervisable (léase: hay alguna posibilidad de que lo obtenga sin errores a tiempo) )
El problema en estos días es que incrustado puede ser cualquier cosa, desde un ATTiny con 6 pines y unos pocos bytes de RAM a un SBC multi-core con un sistema operativo incrustado que avergonzaría a las computadoras de escritorio de algunas personas.
Como tal, la elección del entorno de desarrollo / desarrollo debe tener en cuenta qué tan eficiente debe ser frente a qué tan complejo es el sistema.
En primer lugar, C funciona en todas partes y se escala bastante bien, cuanto más alto vaya, más terminará llamando bibliotecas externas, etc. para manejar la complejidad.
Para micros muy pequeños (medición de flash / ram en bytes) es mejor que utilice ASM, cuando alcanza el rango de kb, C o cualquiera de los otros lenguajes tradicionales se pueden usar ya que no necesita contar cada byte. Una vez que tienes megabytes para jugar, tienes la habilidad y cada vez más la necesidad de usar un RTOS para encargarse de todo y reducir el tiempo de desarrollo. Para cuando tenga hardware puede ejecutar un sistema operativo completo, probablemente puede abstraerse del hardware y simplemente escribir todo en una celda acolchada como Java o algo así sin preocuparse demasiado por cuán terriblemente inútil es y cómo está. ya no es un programador real ...;)
La excepción a lo anterior es cuando necesita todo el rendimiento que puede extraer del hardware, momento en el cual puede necesitar bajar un nivel o dos para mantener la eficiencia.