1 votos

Escritura asíncrona en EEPROM

Hay Stm32l052 con EEPROM incorporado (2k). Se utilizan 4 canales ADC, los datos se recogen por el gatillo cada 40 microsegundos. Los datos del ADC se procesa en la interrupción (determinado por la salida de los valores más allá de los límites). Por lo tanto, el uso de las bibliotecas estándar Hal durante la grabación en EEPROM puntos se pierden (3 milisegundos velocidad de escritura estándar en los datos de EEPROM), incluso si se escribe un byte de la memoria intermedia del anillo. ¿Hay alguna forma de conseguir que el controlador escriba en la EEPROM de forma asíncrona sin bloquear las interrupciones del ADC?

5voto

berendi Puntos 316

STM32L052 parece tener un controlador NVM de un solo banco, por lo que un acceso de escritura a cualquier dirección EEPROM bloquearía las lecturas y recuperaciones de datos de la flash.

Sólo funcionaría si puedes reubicar todo el código relevante, excepto la inicialización, pero incluyendo la tabla de vectores, en la RAM. Sería todo un reto hacerlo en 8 kbytes, pero podría funcionar. Olvídate de HAL, tiene demasiada sobrecarga y complejidad.

Yo recomendaría hacerlo así:

  • Reubicar el NVIC en la RAM
  • El manejador de la interrupción del ADC en la RAM, pone los datos en el buffer del anillo, invoca PendSV ( SCB->ICSR=SCB_ICSR_PENDSVSET ).
  • El gestor de fallos PendSV en la RAM, mientras haya datos que escribir, pone una sola palabra de 32 bits† en la EEPROM, y espera hasta que la escritura se complete. No regresa mientras la NVM sigue ocupada.
  • El manipulador ADC debería tener mayor prioridad que PendSV.
  • El resto del código puede dejarse en flash siempre que el retraso sea aceptable. Los manejadores de interrupción en flash deben tener prioridades más bajas que PendSV.

Este arreglo evitaría que cualquier código en la flash se ejecute mientras una escritura en la EEPROM esté en progreso, pero permite que los manejadores de mayor prioridad se ejecuten siempre y cuando no toquen la memoria no volátil.

Para reubicar una función en la RAM

Con gcc, utilice __attribute__((section(".data"))) en la declaración de la función. Hágalo recursivamente a cada función que llame. Utilice -ffreestanding para evitar que gcc genere llamadas a funciones de biblioteca de forma inesperada. El .data se copiará de la flash a la RAM después del reinicio, junto con las variables inicializadas, por el código de inicio.

Para reubicar la tabla de vectores

La tabla de vectores del STM32L052 tiene 192 bytes (Manual de referencia 12.3 Vectores de interrupción y excepción). Yo simplemente movería el inicio de la RAM hacia arriba 192 bytes en el linker script

RAM (xrw) : ORIGIN = 0x200000C0, LENGTH = 8000 /* 8192 - 192 */

copiar la tabla de vectores allí, y establecer el puntero de la tabla de vectores

memcpy((void*)0x20000000, (void*)0x08000000, 192);
SCB->VTOR = 0x20000000;

antes de que se active cualquier interrupción.


Utilizando STM32L072 en cambio, sería posible dejar que el programa se ejecute desde el Banco 1, y colocar los datos de la EEPROM en el Banco 2 No se interferirían entre sí. Por supuesto, todavía tomaría 3 ms (o 6 ms si no está vacía) para escribir una palabra de 32 bits† en la EEPROM, intentar escribir más datos antes de que la primera escritura se complete todavía bloquearía la ejecución del programa hasta que la primera se complete. Consulta el manual de referencia para ver la disposición de los bancos (3.3.1 Organización de la NVM)


† Según tengo entendido, los datos de la EEPROM se escriben en unidades de 32 bits, escribir 1 o 2 bytes a la vez lleva el mismo tiempo que escribir una palabra completa de 4 bytes.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X