c++ c unit-testing embedded testing-strategies

c++ - Automatización de prueba con hardware integrado



unit-testing embedded (8)

¿Alguien ha tenido éxito al automatizar las pruebas directamente en el hardware integrado?

Específicamente, estoy pensando en automatizar una batería de pruebas unitarias para módulos de capa de hardware. Necesitamos tener mayor confianza en nuestro código de capa de hardware. Muchos de nuestros proyectos utilizan temporizadores de interrupción, ADC, dispositivos de serie SPI (memoria flash), etc.

¿Esto vale la pena el esfuerzo?

Por lo general, apuntamos a:

Procesador: microcontroladores de 8 o 16 bits (algunas cosas de DSP)
Idioma: C (a veces c ++).


Los proyectos integrados de pruebas unitarias son bastante difíciles, ya que generalmente requieren un estímulo externo y una medición externa.

Hemos tenido éxito en desarrollar un protocolo serie externo (mensajes rs232 o udp o tcpip) con comandos básicos para ejercitar el hw con registro de depuración en los controladores de bajo nivel que buscan condiciones erróneas o incluso condiciones ligeramente anormales (especialmente para la comprobación de límites)

Pero una vez desarrollado, podemos ejecutar las pruebas después de cada compilación si es necesario. Definitivamente le permitirá entregar un producto de mejor calidad.


Por supuesto. En la industria automotriz utilizamos comprobadores personalizados de $ 100,000 para cada nuevo producto para verificar que el hardware y el software funcionen correctamente.

Los desarrolladores, sin embargo, también construyen un comprobador más barato (menos de $ 1,000) que incluye un montón de E / S USB, A / D, entrada / salida PWM, etc. y usan secuencias de comandos en la estación de trabajo, o software de prueba HIL / SIL diseñado específicamente como MxVDev.

El hardware en el Loop (HIL) es probablemente lo que usted quiere decir, y simplemente involucra algunas E / S de hardware USB conectadas a la E / S de su dispositivo, con el software en la computadora ejecutando pruebas en su contra.

Si vale la pena depende.

En la industria de alta confiabilidad (avión, automotriz, etc.) el cliente especifica pruebas de hardware muy extensas, por lo que debe tenerlo solo para obtener la oferta.

En la industria del consumo, con proyectos no complejos, generalmente no vale la pena.

Sin embargo, con cualquier proyecto en el que participen más de unos pocos programadores, es realmente agradable realizar una prueba de regresión nocturna en el hardware: es difícil simular correctamente el hardware al grado necesario para asegurarse de que las pruebas de software son suficientes.

La prueba muestra inmediatamente cuando un problema ha ingresado en la construcción.

En general, realiza pruebas de caja negra y de caja blanca; tiene un código de diagnóstico ejecutándose en el dispositivo que le permite espiar señales y memoria en el hardware (que podría ser simplemente un depurador, o podría ser un código que escribió que reacciona a mensajes en un autobús, por ejemplo). Esta sería una prueba de caja blanca donde puede ver lo que ocurre internamente (e incluso provocar que sucedan algunas cosas, como errores de memoria críticos que no se pueden probar sin introducir el error por su cuenta).

También realizamos una serie de pruebas de "caja negra" en las que se ignora la ruta de diagnóstico y solo se estimula / lee la E / S.

Para una configuración mucho más económica, puede obtener tarjetas microcontroladores de $ 100 con USB y / o Ethernet (como la familia Atmel UC3) que puede conectar a su dispositivo y ejecutar pruebas básicas.

Es especialmente útil para el mantenimiento del producto: cuando el proyecto finalice, almacene algunas placas de trabajo, el comprobador y un juego completo de software en CD. Cuando necesite hacer una modificación o solucionar un problema, es fácil configurarlo y hacer una copia de seguridad con algún conocimiento (después de la prueba) de que la funcionalidad principal no se vio afectada por los cambios.

-Adán


Sí, hago esto, aunque siempre tuve un puerto serie disponible para E / S de prueba.

Con frecuencia es difícil dejar la unidad sin modificaciones. Algunas pruebas requieren una línea comentada o una llamada agregada, por ejemplo, para tratar con un perro guardián.

En mi humilde opinión, esto es mejor que ninguna prueba de unidad en absoluto. Y, por supuesto, también necesita estar realizando pruebas completas de integración / sistema.


Sí. He tenido éxito, pero no es un problema directo de resolver. En resumen, esto es lo que hizo mi equipo:

  1. Definió una variedad de pruebas unitarias usando un marco de prueba de unidad C construido en casa. Básicamente, solo un montón de macros, la mayoría de las cuales se llamaron TEST_EQUAL , TEST_BITSET , TEST_BITVLR , etc.

  2. Escribió un generador de código de arranque que tomó estas pruebas compiladas y las orquestó en un entorno de ejecución. Es solo un pequeño controlador que ejecuta nuestra rutina de inicio normal, pero en lugar de entrar en el ciclo de control, ejecuta un conjunto de pruebas. Cuando termine, almacena la última suite para ejecutar en la memoria flash, luego restablece la CPU. Luego se ejecutará la próxima suite. Esto es para proporcionar aislamiento en caso de que un conjunto fallezca. (Sin embargo, es posible que desee desactivar esto para asegurarse de que sus módulos cooperen. Pero eso es una prueba de integración, no una prueba de unidad).

  3. Las pruebas individuales registrarían su salida utilizando el puerto serie. Esto estuvo bien para nuestro diseño porque el puerto serie era gratis. Deberá encontrar una forma de almacenar sus resultados si se consume todo su IO.

¡Funcionó! Y fue genial tenerlo Usando nuestro registrador de datos personalizado, puede presionar el botón "Probar" y, un par de minutos más tarde, obtendrá todos los resultados. Lo recomiendo altamente.

Actualizado para aclarar cómo funciona el controlador de prueba.


Si su objetivo es la prueba de fabricación (asegurándose de que los módulos estén ensamblados correctamente, sin cortocircuitos inadvertidos / aperturas / etc.), primero debe centrarse en probar los cables y conectores, seguidos de conexiones soldadas y conectadas, y luego la PCB misma. Todos estos elementos se pueden probar en busca de cortos y abre mediante la búsqueda de patrones de acceso que conducen cada línea individual alta mientras sus vecinos son bajos y viceversa, y luego leyendo los valores de las líneas.

Sin conocer más detalles de su hardware, es difícil ser más específico, pero la mayoría de los procesadores integrados pueden configurar los pins de E / S en un modo GPIO que simplifica este tipo de pruebas.

Si no realiza pruebas de lecho de uña en sus PCA, esta prueba debe considerarse un primer paso obligatorio para las placas recién fabricadas.


Si su objetivo es probar su código de controlador de bajo nivel, es probable que necesite crear algún tipo de accesorio de prueba, utilizando cables de bucle invertido o múltiples unidades interconectadas para permitirle ejercitar cada controlador. El emparejamiento de una placa con un software conocido con una placa ejecutando una compilación de desarrollo le permitirá probar regresiones en protocolos de comunicación, etc.

Las estrategias de prueba específicas dependen del hardware que desea probar. Por ejemplo, los ADC se pueden probar presentando una forma de onda conocida y convirtiendo una serie de muestras, luego verificando el rango apropiado, la frecuencia, el valor promedio, etc.

He encontrado que este tipo de prueba es muy valiosa en el pasado, lo que me permite modificar y mejorar con confianza el código del controlador sin temor a romper las aplicaciones existentes.


Sí.

La dificultad depende del tipo de hardware que intentas probar. Como otros lo han dicho anteriormente, el problema va a ser la complejidad del estímulo externo que debe aplicar. Es probable que el estímulo externo se logre mejor con una plataforma de prueba externa (como ha descrito Adam Davis).

Una cosa a tener en cuenta, sin embargo, es exactamente lo que está tratando de verificar.

Es tentador suponer que para verificar la interacción del hardware y el firmware, realmente no tiene otra opción que aplicar directamente un estímulo externo (es decir, aplicar DAC a todas sus entradas de ADC, etc.). En estos casos, sin embargo, los casos de esquina que realmente desea probar estarán sujetos a problemas de tiempo (por ejemplo, interrupciones que llegan cuando está ejecutando la función foo ()) que serán increíblemente difíciles de probar en una forma significativa, y aún más difícil de obtener resultados significativos de. (es decir, las primeras 100.000 veces que ejecutamos esta prueba estuvo bien. La última vez que lo ejecutamos falló. ¿Por qué?!?)

Pero la verificación del hardware debe hacerse por separado. Una vez hecho esto, a menos que esté cambiando regularmente (a través de imágenes fpga descargables o similares), entonces debería poder asumir que el hardware funciona y probar su firmware por pura evidencia.

Entonces, en este caso, puede concentrarse en verificar los algoritmos que se utilizan para procesar sus estímulos externos. Por ejemplo, llamando a sus rutinas de conversión de ADC con un valor fijo como si provinieran de su ADC directamente. Estas pruebas son repetibles y, por lo tanto, de beneficio. Sin embargo, requerirán compilaciones de prueba especiales.

Probar las rutas de comunicación de su dispositivo va a ser relativamente sencillo y no debería requerir compilaciones de código especiales.


Hemos tenido buenos resultados con pruebas automatizadas en nuestros sistemas integrados. Tenemos pruebas escritas en lenguajes de alto nivel (fáciles de programar y depurar) que se ejecutan en máquinas de prueba dedicadas. Estas pruebas generalmente hacen una comprobación de cordura o generan entradas aleatorias en los dispositivos, luego verifican el comportamiento correcto. Hay mucho trabajo para generar y mantener estas pruebas. Diseñamos un marco y luego permitimos que los pasantes trabajen en las pruebas mismas.

No es una solución perfecta, y las pruebas son ciertamente propensas a errores, pero la parte más importante es mejorar los agujeros de cobertura existentes. Encuentre el agujero más grande y diseñe algo para cubrirlo de manera automatizada, incluso si no es perfecto o no cubrirá toda la función. Luego, cuando todo esté cubierto, puede volver y abordar la peor cobertura o las características más críticas.

Algunas cosas a considerar:

  • ¿Cuál es la penalización de un error de firmware? ¿Qué tan fácil es actualizar el firmware en el campo?
  • ¿Qué tipo de cobertura proporciona mi prueba? ¿Es un simple control de cordura? ¿Es lo suficientemente configurable como para que pueda probar muchos escenarios diferentes?
  • Una vez que una prueba ha fallado, ¿cómo va a reproducir ese valor para depurarlo? ¿Has registrado todas las configuraciones de dispositivo y prueba para poder eliminar tantas variables como sea posible? Configuración del dispositivo, versión de firmware, versión del software de prueba, todas las entradas externas, todo el comportamiento observado?
  • ¿En qué estás probando? ¿Es la especificación lo suficientemente clara sobre el comportamiento esperado del dispositivo que está probando o está validando con respecto a lo que cree que debería hacer el código?