Uso de la utilidad ST-LINK para configurar el RTC a la hora actual

Lo que estaba haciendo

Estoy usando un microcontrolador STM32 y para mi proyecto necesito poder enviar datos en momentos específicos del día (por ejemplo, a las 11 a. m. y a las 2 p. m.). El microcontrolador necesita saber qué hora es antes de que pueda lograr esto. Desafortunadamente, solo tengo una comunicación unidireccional y, por lo tanto, no puedo solicitar la hora actual de la red.

Por lo tanto, quiero configurar la hora actual, directamente después de que termine de programar. Sabía que podía escribir datos en la memoria flash usando la interfaz de línea de comandos de la utilidad ST-LINK (ST-LINK_CLI) usando el siguiente comando:

ST-LINK_CLI.exe -w32 <Address> <data> -Rst

Escribí un script de prueba simple que escribe la marca de tiempo de Unix en alguna dirección que el código no usa actualmente.

Estaba a punto de escribir una función para leer la marca de tiempo y usarla para establecer la hora RTC. Hasta que leí lo siguiente en el Manual de usuario de la utilidad ST-LINK :

-w32 admite la escritura en registros de memoria Flash, OTP, SRAM y R/W.

Cuando el manual dice que admite la escritura en los registros R/W, ¿significa esto que puedo acceder directamente a los registros RTC y configurarlos? Lo he intentado, pero parece que no puedo escribir en estos registros.

Preferiría usar este método si lo hace, ya que no necesitaría escribir una función específica para manejarlo en el microcontrolador. Esto significa que puedo configurar el tiempo RTC de cualquier microcontrolador que tengamos actualmente en uso, en lugar de tener que actualizar su código.


lo que pretendía hacer

Para configurar los registros RTC, traté de hacer los siguientes pasos, como se describe en el Manual de referencia de STM :

  • establece el bit DPB en el registro PWR_CR
  • escribe 0xCA en el registro RTC_WPR
  • escribe 0x53 en el registro RTC_WPR
  • detenga el RTC configurando el bit INIT en el registro RTC_ISR
  • seleccione el reloj de 1 Hz escribiendo en el registro RTC_PRER
  • cargar la hora actual escribiendo en el registro RTC_TR
  • cargar la fecha actual escribiendo en el registro RTC_DR
  • inicie el RTC restableciendo el bit INIT en el registro RTC_ISR

Para acceder a los registros he utilizado las siguientes direcciones:

  • PWR_CR: 0x4000 7000
  • RTC_WPR: 0x4000 2824
  • RTC_ISR: 0x4000 280C
  • RTC_PRER: 0x4000 2810
  • RTC_TR: 0x4000 2800
  • RTC_DR: 0x4000 2804

Qué salió mal

No puedo escribir en ninguno de estos registros. Con la utilidad ST-LINK, recibo el siguiente mensaje:

¡Ocurrió un error durante la escritura de la memoria!

Usando ST-LINK_CLI:

Escribiendo 0x00000100 en 0x40007000... ¡Error!

Leer estos registros no es un problema, pero no puedo escribir en ellos usando la utilidad ST-LINK o su interfaz de línea de comandos.


La pregunta

¿Cómo puedo escribir en los registros R/W usando la utilidad ST-LINK?

¿Hay algún tipo de protección contra escritura que permita escribir en los registros RTC que pasé por alto?

Posiblemente protegido contra escritura a menos que se ingrese un código clave.
Me alegra ver que has descubierto muchas cosas a partir de las sugerencias iniciales. En general, debe publicar una solución como una respuesta en lugar de una edición de la pregunta, y especialmente cuando la ha perseguido hasta aquí, sería apropiado finalmente mover su aceptación a eso.
¡En realidad no lo había pensado de esa manera! Siento que aún debería hacerlo, aunque me gustaría que tú también tuvieras algunos créditos.
¿Cuánto tiempo después de la programación tiene que funcionar su dispositivo y qué tan precisa debe ser la hora del día? Solo me preocupa que no importa cuán preciso sea su RTC, eventualmente se desviará un poco, al menos si se usa durante años y sus requisitos de tiempo son estrictos.
Se supone que funciona durante 10 años con una sola batería. Sin embargo, el esquema de tiempo ya se modifica ligeramente por un número aleatorio para evitar que todos los dispositivos envíen sus datos a la vez. Por lo tanto, la deriva del tiempo RTC no es gran cosa.

Respuestas (3)

Algunos registros solo son válidos para un ancho de acceso específico (es decir, -w32 puede no ser correcto) o pueden no leer los valores escritos, lo que podría causar un problema con la verificación.

También puede haber restricciones de secuencia o estado para acceder a las cosas.

Una opción que debería solucionar la mayoría de los problemas concebibles sería crear un pequeño programa para hacer el trabajo que se vincularía para ejecutarse en la RAM. Puede sustituir los datos en su binario después de calcular el desplazamiento, cargar la versión modificada y ejecutarla. O puede hacer que el programa obtenga valores de una región de RAM fuera de las extensiones del archivo, que configuraría antes de ejecutar. Con un control más detallado del stlink, también podría pasar valores en los registros de la CPU, aunque podría (?) necesitar el programa de línea de comando de código abierto alternativo en lugar de ST para hacer eso (esta pequeña rutina en el método RAM es, por cierto, cómo ese programa logra escribir parpadear)

Entonces, uno de los problemas fue, como señaló Chris Stratton:

Algunos registros... pueden no volver a leer los valores escritos, lo que podría causar un problema con la verificación.

Esto significó que la verificación falló, lo que provocó que se mostrara el error, aunque la operación de escritura realmente tuvo éxito.

A continuación se muestra la respuesta que obtengo al leer el registro PWR_ISR, configurar el bit INIT y luego volver a leer el registro:

0x4000280C: 00000027

Escribiendo 0x00000080 en 0x4000280C... ¡Error!

0x4000280C: 000000A7

La verificación de la utilidad ST-LINK verifica si el valor escrito en la dirección y leído de la dirección coinciden. En este caso, la operación de escritura fue exitosa, aunque los dos valores no coincidan, ya que el bit INIT ahora está establecido.

El otro problema fue que no pude notar el efecto de la operación de escritura. Mientras está conectado al microcontrolador, el ST-LINK lo mantiene en el estado de reinicio (conocido como "conectar bajo reinicio"). Necesitaba usar la opción de conexión HOTPLUG, que se conecta al microcontrolador sin detenerse ni restablecerse.

La opción "conectar bajo reinicio" permite conectarse al objetivo antes de ejecutar cualquier instrucción. Esto es útil en muchos casos, como cuando el objetivo contiene un código que desactiva los pines JTAG/SWD.

La opción “HotPlug” permite conectarse al objetivo sin detenerse ni restablecerse. Esto es útil para actualizar las direcciones de RAM o los registros de IP mientras se ejecuta la aplicación.

¡El archivo por lotes funciona completamente como yo quería! El comando ahora se ve así:

ST-LINK_CLI.exe -c HOTPLUG -w32 <Address> <data> -w32 <Address> <data> ...

Creo que lo que sucede es que después de la escritura, se realiza una lectura de verificación. Si el mismo registro devuelve la hora actual en una lectura, aunque logra actualizar el RTC, el depurador no se dará cuenta. Es menos probable que esto explique un problema con el registro de energía (a menos que el depurador esté accediendo a ese registro también debajo del capó). Compruebe el valor leído manualmente. Si hubiera un problema más significativo, esta lectura también podría fallar. Además, pruebe los otros registros en su lista.