embedded - sobre - ¿Las peores prácticas de los sistemas integrados?
todo sobre sistema integrado de gestion (20)
Algunas cosas extra que no hacer:
- Deje el desarrollo y las pruebas de las partes dependientes del hardware hasta el final, solo para descubrir que el hardware no funciona, no funciona como se espera o tiene algunas deficiencias que no se pueden corregir en el software (por ejemplo, distorsiones no lineales no deseadas que romper todo el procesamiento de la señal adicional).
- Diseñe circuitos analógico-digitales de una manera simple sin pensar en cómo las cosas que suceden en la parte digital pueden y pueden afectar a la parte analógica (p. Ej., Diafonía, lo que lleva a la lectura de datos erróneos de los ADC).
¿Qué considerarían las "peores prácticas" para desarrollar un sistema integrado?
Algunas de mis ideas sobre qué no hacer son:
Estoy seguro de que hay muchas buenas ideas sobre lo que no debes hacer, ¡escuchemos!
Aquí hay algunos:
No diseñe una arquitectura fácilmente explicable que sus desarrolladores, gerentes y clientes puedan entender.
Un sistema integrado casi siempre es una plataforma sensible a los costos. No planifique que el hardware se vuelva más lento (más barato) y no planifique nuevas funciones en la ruta de datos críticos.
La mayoría de los sistemas integrados son "sin cabeza" (sin teclado ni mouse ni ningún otro HID). No planifique en su agenda escribir herramientas de depuración. Y no recurra al menos a un desarrollador para mantenerlos.
Asegúrese de subestimar cuánto tardará en recibir el aviso. Ese es el tiempo que se necesita para llevar la CPU central a un punto en el que pueda hablar con usted y con usted.
Siempre asuma que los subsistemas HW funcionan de fábrica, como la memoria, los relojes y la potencia.
Asignación de memoria dinámica después de la inicialización. El grupo de memoria debe permanecer estático después de que el sistema esté funcionando.
Sin definir un poco más la "programación incorporada", es imposible decir qué es una buena o mala práctica.
Muchas de las técnicas que podría utilizar para programar un micro de 8 bits en un dialecto no estándar poco fiable de ''C'' serían completamente inapropiadas en una plataforma CE o XPe, por ejemplo.
La abstracción es un lujo (demasiado caro) en muchos casos, por lo que "evitarlo" podría ser bueno en lugar de malo.
Supongamos que la endiosidad será la misma para siempre.
(Extiéndalo al tamaño de los registros y cualquier cosa sobre especificaciones de hardware)
(Explicación del caso en los comentarios).
Tratando de desarrollar sin acceso al hardware real para el que está desarrollando.
Una cosa importante en los sistemas integrados es evaluar la tecnología, tanto el software (compilador, bibliotecas, sistema operativo) como el hardware (conjuntos de chips) independientemente de su aplicación. Evitar el uso de camas de prueba para estos es peligroso. Uno debe comprar kits de evaluación o construir sus propias camas de prueba.
- Skimping en la instalación de registro. Los sistemas integrados son difíciles de depurar y necesita mucho registro.
- No tener la capacidad de permitir niveles de registro. Un sistema de muchos exhibirá comportamientos extraños y necesita establecer el nivel de depuración del registro de ese sistema en uno más detallado.
- No permitir algún tipo de puerto de salida para permitir el registro en una consola, por ejemplo.
- No tener la capacidad de "atravesar" el código.
- No tener la capacidad de crear un perfil del código para que pueda ver qué bits se deben optimizar, por ejemplo, en ensamblador.
- No está desarrollando ningún tipo de "prueba de cordura" para que pueda verificar rápidamente si el dispositivo funciona una vez cargado y antes de enviarlo.
- Basando el diseño en algunos sistemas operativos "de cosecha propia"
Alguien me detiene antes de lastimarme.
Por cierto, me doy cuenta de que no todos estos son estrictamente específicos para el desarrollo integrado , pero creo que cada uno de ellos es al menos tan importante en el mundo integrado como el mundo real.
Cuando haga un horario, avance y suponga que todo va a funcionar la primera vez.
Acérquese a la tabla sin un osciliscopio y / o un analizador lógico. Esp. el alcance, eso nunca es útil.
No considere la fuente de alimentación durante el diseño. Problemas como el calor, la eficiencia, los efectos de la ondulación en las lecturas de ADC y el comportamiento del sistema, la radiación EMF, el tiempo de arranque, etc. no son importantes.
Hagas lo que hagas, no uses un controlador de reinicio (el tipo IC de 5 céntimos), solo usa un circuito RC (con suerte uno con un montón de ruido de CA de alta frecuencia acoplado a él)
¡ABRAZA EL BIG BANG! ¡No desarrolles pequeñas piezas incrementalmente e integre a menudo, tonto tonto! ¡Solo codifica durante meses, junto a tus compañeros de trabajo, y luego ponlos juntos la noche anterior a la gran demostración de feria!
No instrumente código con instrucciones de depuración / rastreo. La visibilidad es mala.
Haz muchas cosas en tus ISR. Tipos de burbujas, consultas a bases de datos, etc. Oye, es probable que nadie te interrumpa, tienes la palabra, ¡disfrútalo amigo!
Ignora el diseño de la placa en un diseño. Deje que el trazador automático vaya a la ciudad en esas trazas de impedancia combinadas y en la fuente de alimentación de alta corriente y alta frecuencia. ¡Oye, tienes cosas más importantes de las que preocuparte, compañero!
Utilice silicio de adopción temprana nuevo, beta, inédito, especialmente si es de seguridad crítica (aviación, médica) o de gran volumen (es divertido recordar 1 millón de unidades). ¿Por qué ir a Vegas cuando hay un nuevo muestreo de silicio en ese chip de 7 etapas con 7 núcleos y 300 MHz?
OK, vuelta 2 ... solo algunos más:
No use un temporizador de vigilancia (¡especialmente el incorporado!)
Use tipos de punto flotante y rutinas cuando la matemática entera escalada sería suficiente
Use un RTOS cuando no esté garantizado
No use un RTOS cuando realmente tenga sentido
Nunca mire el código ensamblador generado para comprender qué está pasando debajo del capó
Escriba el firmware para que no se pueda actualizar en el campo
No documente ninguna suposición que esté haciendo
Si ve algo extraño mientras prueba / depura, simplemente ignórelo hasta que vuelva a suceder; Probablemente no fue nada importante, como un apagón, una interrupción omitida, un signo de corrupción en la pila, o algún otro problema fugaz e intermitente
Al dimensionar las pilas, la mejor filosofía es "comenzar en pequeño y seguir aumentando hasta que el programa deje de fallar, entonces probablemente estemos bien".
No aproveche las herramientas de creación de perfiles de tiempo de ejecución como uC / Probe de Micrium (estoy seguro de que hay otras)
No incluya las autopruebas de encendido del hardware antes de ejecutar la aplicación principal: ¿está funcionando el código de arranque? ¿Qué podría no funcionar?
Definitivamente no incluya una prueba de RAM en el POST (arriba) que no va a implementar
Si el procesador de destino tiene una MMU, por todo lo que es sagrado, ¡no use esa aterradora MMU! Especialmente no permita que lo proteja de las escrituras en el espacio del código, la ejecución desde el espacio de datos, etc.
Si ha estado probando, depurando e integrando con un cierto conjunto de opciones del compilador (por ejemplo, no / low optimization), ¡ASEGURESE DE ENCENDER LA OPTIMIZACION COMPLETA antes de su versión final de compilación! Pero solo activa la optimización si no vas a probar. Quiero decir, ya has probado durante meses: ¿qué podría salir mal ?!
- Vectores de excepción no inicializados (ya sabes, para los que "nunca serán alcanzados")
- Dilo conmigo: variables globales. Especialmente los compartidos entre ISR y tareas (o bucles de primer plano) sin protección.
- No usar "volátil" cuando sea necesario.
- Tener rutinas emparejadas entre DisableInterrupts () y EnableInterrupts (). ¿Lo tengo? Not Restore Interrupt () , pero ENABLE . Sí, anidando.
- No hay GPIO para alternar cuando se prueba.
- No hay puntos de prueba a bordo.
- Sin LED o puerto serie para ver el estado del sistema en tiempo de ejecución.
- No hay medida de cuán ocupado / inactivo está la CPU.
- Uso del ensamblaje en línea para todos los casos menos los más graves. Escribe una llamada rápida.
- Usar para (i = 0; i <1000; i ++) {} para "retrasar un poco". Sí, eso no te va a morder de mil maneras diferentes ...
- No se utiliza const en todas partes posible para preservar la RAM y reducir el tiempo de arranque (sin copiar / init de variables)
Tengo un montón más, pero eso debería ayudarnos a empezar ...
Escriba su módulo FW para que sea totalmente genérico y acepte todos los parámetros posibles como una variable aunque la capa superior siempre llame con los mismos parámetros.
Use memcpy en todas partes del código aunque tenga un motor DMA en el sistema (por qué molestar a HW).
Diseñe una arquitectura FW en capas compleja y luego tenga acceso a un módulo directamente a las variables globales propiedad de módulos de nivel superior.
Elija un RTOS pero no se moleste en probar su rendimiento real (¿no podemos confiar en los números dados por el proveedor?)
Utiliza múltiples procesadores en tu solución y asegúrate de que tengan endianidad opuesta. Luego, asegúrese de que la interfaz entre ellos sea una de ellas que tenga acceso directo a la memoria del otro.
Sí, he programado esa arquitectura antes.
Printf.
Si su instalación de rastreo requiere un cambio de contexto y / o interrupciones, nunca podrá depurar nada, incluso vagamente relacionado con el tiempo.
Escribe en un búfer de memoria (puntos de bonificación para las enumeraciones de memcpying en lugar de s (n) printf), y léelo en otro momento.
Esta es quizás más una respuesta de hardware, pero para comenzar nuevos proyectos desde cero, subestimar los requisitos de recursos es un gran problema, especialmente cuando se trabaja con microcontroladores autónomos pequeños sin una forma sencilla de ampliar el tamaño del código / almacenamiento.
No hacer:
Deje los vectores de interrupción no utilizados que no apuntan a nada (después de todo, nunca van a ser activados, entonces, ¿dónde está el daño en eso ...), en lugar de tener que saltar a un controlador de interrupción no utilizado por defecto que hace algo útil.
No esté familiarizado con los detalles del procesador que está utilizando, especialmente si está escribiendo controladores de bajo nivel.
Elija la versión de una familia de procesadores con la menor cantidad de flash, con el argumento de que siempre puede "actualizar más tarde", a menos que los costos lo hagan inevitable.
Eso no es solo para sistemas integrados, pero pasar todo este tiempo buscando errores (depuración) en lugar de evitar errores con cosas geniales como, por ejemplo, revisiones de código, es definitivamente una de las peores prácticas comúnmente aplicadas.
Otra opción es dejar que un gran procesador haga todo el trabajo en lugar de dividir el problema en pequeños problemas, por ejemplo, con más pequeños procesadores. ¿Recuerdas COCOMO?
Depende mucho del tipo de controlador para el que está programando. A veces, el costo es lo más importante y estás tratando de salir adelante con la menor cantidad de dinero posible. Ese es el barco en el que suelo estar. Estas son algunas de las peores prácticas que he usado:
- No se concentre en mejorar sus procesos. Solo inténtalo un poco más la próxima vez. Más tarde, cuando no estamos ocupados lanzando nuevos productos apresuradamente mientras apoyamos todos estos errores en el campo, podemos preocuparnos por eso.
- Evite diseñar una herramienta de ingeniería para facilitarle la vida y, si construye una, no la habilite para enviar entradas no válidas al dispositivo.
- No cuestione la optimización. Es magia. El compilador sabe lo que está haciendo. Nunca habrá un error del compilador, especialmente no para su cliente submicrocontrolador PIC de 7 bits. Demasiada gente notaría ¿verdad?
- Divida y multiplique como si estuviera ejecutando un motor de física, no se preocupe por el desbordamiento, la pérdida de precisión, redondeando a cero.
- Si el tiempo parece funcionar, no verifique si está apagado en 1 o si se desplaza con el tiempo. Jugaste percusión en la escuela secundaria, notarías si la diferencia entre 7200000 ciclos de reloj y 7200001.
- Confíe en las pruebas de nivel del sistema de un grupo que no sabe nada sobre su firmware
- Trabaja en tantos dispositivos diferentes como sea posible. Tenga varias sesiones de depuración en diferentes entornos de desarrollo. Trabaja en el desarrollo de un producto mientras haces pruebas en otro y tratas de reproducir un tema de campo en el tercero.
- Lanza una nueva versión de código rápidamente porque solo cambiaste una cosa y probablemente no la rompiste. ¡La línea de producción está baja, no podemos perder tiempo!
- No realice ningún tipo de prueba para advertirle si la optimización se ha desactivado. Probablemente no estará bien? La nueva versión IDE que acaba de instalar no podría haber roto esa configuración.
- Escribe el código lo suficientemente bien como para trabajar. Pasa el 75% del tiempo llegándote a mitad de camino.
- No tiene ninguna entrada en el diseño de las características. Permita que cualquier característica reúna días de información de estado. No tiene forma de inyectar esta información de estado para una prueba. Esto le dará tiempo libre cuando intente reproducir errores que la gente ha visto en el campo y los chicos de producción apreciarán también su tiempo libre.
Desde la perspectiva del software, no se toma el tiempo de aprender el hardware.
- Supongamos que el micro hace lo que la hoja de datos dice que hace / no hace lo que la hoja de datos promete que no hará.
- Coloque la rutina de servicio de vigilancia en una interrupción temporizada de alta prioridad para que ocurra lo que ocurra, el perro guardián nunca fallará.
- Use cualquier código visto en Internet, especialmente si es de un sitio Arduino / Pic.
- Supongamos que existe una definición estándar de cualquier componente de un componente al siguiente, por ejemplo, Tx / Rx (aquí tenemos una unidad Sony con 2 puertos de comunicaciones, uno tiene Tx / Rx invertidos en relación con el otro).
- Piensa que el cliente se molestará en verificar / probar cualquier cosa hasta que haya vendido al menos 100 unidades
- Asuma que cualquier otro jugador en el campo realmente sabe lo que está haciendo (tenemos un documento de estándares que dice "creemos que esto es lo que hizo nuestro antiguo protocolo, pero nadie realmente recuerda")