Un extraño error de software en el control de BLDC: Mire esos registros de “solo escritura”

Fue uno de los errores más extraños. El sistema parecía funcionar como se esperaba, pero los datos de telemetría sugerían lo contrario. La entrada de demanda que determina la velocidad a la que el motor debería girar informaba un 85%, pero afortunadamente el motor no giraba. Era tentador simplemente mover una mano y sugerir que no era gran cosa, o que era un problema con el software de análisis de telemetría, pero algo no estaba del todo bien. Era hora de profundizar, hurgar en el sistema y determinar qué estaba causando este error.

Este sistema en particular utilizaba un chip impulsor de motor de BLDC (CC sin escobillas) A4964 de Allegro Microsystems. Me he encariñado particularmente con este chip porque proporciona una solución flexible para el impulso del motor, quita del MCU (microcontrolador) todo el código de control que puede consumir los ciclos de la CPU (unidad central de procesamiento) y lo introduce en un chip de hardware dedicado (Figura 1).

Figura 1: El A4964 es útil, ya que descarga el control de un motor de BLDC del MCU al hardware dedicado. (Fuente de la imagen: Allegro Microsystems)

En esta configuración del sistema, estaba aprovechando la interfaz de comunicación de SPI (interfaz periférica serial) para configurar los 32 registros en el chip que determinan cómo se impulsa y controla el motor de BLDC.

Para la aplicación, el A4964 se configura durante la instalación mediante una rutina de inicialización al leer una tabla de configuración que contiene los parámetros deseados de configuración del motor. El pseudocódigo (solo a modo de ejemplo) para la cual se incluye a continuación (Listado 1):

Copiarfor(uint8_t WriteIndex = 0; WriteIndex < A4964MaxRegister; WriteIndex++)
{
    // Write value stored in A4964Config at index WriteIndex to the chip
}

Listado 1: Se muestra la rutina de inicialización que indica los parámetros de configuración del motor. (Fuente del código: Jacob Beningo).

Desde el punto de vista de la inicialización, no hay mucho que pueda estar mal con el código, por lo que rápidamente decidí examinar la lógica principal que se requería regularmente dentro de la aplicación. Este código fue un poco más interesante. El dominio de la aplicación era un entorno con abundante radiación, lo que puede afectar los valores almacenados en la RAM. Los valores de inicialización se escriben en la RAM del A4964 al inicio, por lo que para superar rápidamente cualquier cambio de bits que pudiera ocurrir, se leía periódicamente la memoria del A4964: si ocurría un desajuste, se actualizaban las configuraciones. El pseudocódigo era algo parecido a lo siguiente (Listado 2):

Copiarfor(uint8_t Index = 0; Index < A4964MaxRegister; Index++)
{
    // Read the A4964 configuration register at location Index

   // If read value does not match expected value, write configuration value
}

Listado 2: La radiación local podía afectar los valores almacenados en la RAM, por lo que, para contrarrestar los cambios de bits, se leía periódicamente la memoria del A4964 y la configuración se actualizaba si ocurría un desajuste. (Fuente del código: Jacob Beningo).

Una vez más, un código muy simple que no tiene mucho que pueda salir mal y, sin embargo, de alguna manera, algo estaba escribiendo un valor de entrada de demanda incorrecto en el chip. El valor parecía ser transitorio en el sentido de que aparecía en alguna telemetría antes de informar el valor correcto y luego, una vez más, proporcionaba el valor incorrecto. ¡Extraño!

Lo que hizo que esto fuera aún más interesante es que no había ningún valor de configuración o valor de aplicación que escribiera un 85% en el registro. Entonces, ¿de dónde provenía este valor del 85%? Bueno, cuando el decimal 85 se convierte a hexadecimal es 0x55. ¿Hubo algún lugar en la base de código donde se produce 0x55? Por supuesto que sí. 0x55 se utiliza como carácter de escritura ficticio para las operaciones de lectura en el bus de SPI. Pero ¿cómo se convierten las operaciones de lectura en operaciones de escritura?

Bueno, resulta que la respuesta es bastante obvia una vez que miramos más de cerca la hoja de datos del A4964 (Figura 2).

Figura 2: Un fragmento de la hoja de datos muestra el problema; el registro 30 es de solo escritura. (Fuente de la imagen: Allegro Microsystems)

El registro 30, que administra la DI (entrada de demanda) para el motor, es un registro de solo escritura. Intentar leer desde el registro tiene el efecto de escribir el byte ficticio en el registro. La función de inicialización simple y actualización del chip intentaba leer desde el registro de entrada de demanda para verificar las configuraciones y escribía involuntariamente una nueva entrada de demanda. El sistema seguía funcionando como se esperaba porque la lectura del registro de escritura siempre daba como resultado la escritura del valor correcto poco después, pero no siempre lo suficientemente rápido como para que el valor incorrecto no ingresara en la telemetría del sistema.

Con el A4964, un desarrollador de software no puede simplemente escribir datos de configuración en todo el mapa de memoria, sino que debe detenerse después del registro 29. Los dos últimos registros accesibles son registros especiales de escritura y de solo lectura.

A veces, no importa cuánto esfuerzo pongamos en escribir correctamente un controlador o implementar un software, siempre surge algún problema. Los errores extraños suelen ser una oportunidad para aprender algo nuevo sobre el hardware y, a menudo, dan como resultado nuevas prácticas recomendadas. Este pequeño error extraño ha hecho que agregue a mi lista “Observar cuidadosamente los registros de solo lectura o escritura” y asegurarme de interactuar con ellos correctamente. De lo contrario, la lectura de ese registro de solo escritura dar como resultado un evento catastrófico dentro del sistema.

Acerca de este autor

Image of Jacob Beningo

Jacob Beningo es un consultor de software integrado que actualmente trabaja con clientes en más de una docena de países para transformar drásticamente sus negocios mejorando la calidad del producto, el costo y el tiempo de comercialización. Ha publicado más de 200 artículos sobre técnicas de desarrollo de software embebido, es un conferenciante y entrenador técnico muy solicitado y tiene tres títulos que incluyen una Maestría en Ingeniería de la Universidad de Michigan. No dude en ponerse en contacto con él en jacob@beningo.com, en su sitio web www.beningo.com, y suscríbase a su boletín mensual Embedded Bytes Newsletter.

More posts by Jacob Beningo
 TechForum

Have questions or comments? Continue the conversation on TechForum, Digi-Key's online community and technical resource.

Visit TechForum