Escritura asincrónica en EEPROM

1

Hay Stm32l052 con EEPROM incorporada (2k). Se utilizan 4 canales ADC, los datos se recopilan por el activador cada 40 microsegundos. Los datos del ADC se procesan en la interrupción (determinada por la salida de valores más allá de los límites). Por lo tanto, el uso de las bibliotecas Hal estándar durante la grabación en puntos EEPROM se pierde (3 milisegundos de velocidad de escritura estándar en datos EEPROM), incluso si se escribe un byte desde el búfer de anillo. ¿Hay alguna forma de hacer que el controlador escriba en la EEPROM de forma asíncrona sin bloquear las interrupciones de ADC?

    
pregunta Egor Vasilyev

1 respuesta

5

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

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

Recomiendo hacerlo de esta manera:

  • reubicar NVIC a RAM
  • El controlador de interrupciones ADC en la RAM, coloca los datos en el búfer de anillo, invoca PendSV ( SCB->ICSR=SCB_ICSR_PENDSVSET ).
  • El controlador de fallas PendSV en la RAM, siempre que haya datos para escribir, coloca una sola palabra de 32 bits † en EEPROM, y espera hasta que finalice la escritura. No regrese mientras NVM aún esté ocupado.
  • El controlador ADC debería tener una prioridad más alta como PendSV.
  • El resto del código se puede dejar en el flash siempre que la demora sea aceptable. Los manejadores de interrupciones en flash deberían tener prioridades más bajas que PendSV.

Esta disposición evitaría que cualquier código en flash se ejecute siempre que una escritura EEPROM esté en curso, pero permite que los manejadores de mayor prioridad se ejecuten siempre que no toquen la memoria no volátil.

Para reubicar una función en la RAM

Con gcc, use __attribute__((section(".data"))) en la declaración de la función. Hazlo recursivamente a cada función que llame. Use -ffreestanding para evitar que gcc genere llamadas a funciones de biblioteca de forma inesperada. La sección .data se copiará de flash a RAM después del restablecimiento, junto con las variables inicializadas, mediante el código de inicio.

Para reubicar la tabla vectorial

La tabla de vectores de STM32L052 tiene 192 bytes de longitud (Manual de referencia 12.3 Vectores de interrupción y excepción). Acabo de mover el comienzo de la RAM hasta 192 bytes en el script del enlazador

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

copie la tabla de vectores allí y configure el puntero de la tabla de vectores

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

antes de que se habilite cualquier interrupción.

En su lugar, utilizando STM32L072 , sería posible dejar que el programa se ejecute desde el Banco 1 y, al colocar los datos de la EEPROM en el Banco 2 , no interferirán entre sí. Por supuesto, aún tomaría 3 ms (o 6 ms si no está vacío) escribir una palabra † de 32 bits en la EEPROM, intentar escribir más datos antes de que se complete la primera escritura aún bloquearía la ejecución del programa hasta que se complete la primera. Consulte el manual de referencia para el diseño del banco (3.3.1 Organización NVM)

† Los datos de AFAIK EEPROM se escriben en unidades de 32 bits, escribir 1 o 2 bytes a la vez toma tanto tiempo como escribir una palabra completa de 4 bytes.

    
respondido por el berendi

Lea otras preguntas en las etiquetas