Tengo un microcontrolador que debe descargar un archivo grande del puerto serie de una PC (115200 baudios) y escribirlo en la memoria flash serial sobre SPI (~ 2 MHz). Las escrituras flash deben estar en bloques de 256 bytes precedidos por un comando de escritura y una dirección de página. La RAM total disponible en el sistema es de 1 kB con un tamaño de pila de 80 bytes.¿Cómo se manejan las grandes transferencias de datos en sistemas incrustados de memoria muy limitada?
Esto está trabajando actualmente completando un buffer de 256 bytes de la UART y después de ping-ponging a un otro buffer de 256 bytes siendo llenado por una interrupción en la señal de preparado búfer RX mientras el flash se escribe con escrituras ocupados. El intercambio de buffer se repite hasta que la operación se complete.
Preferiría configurar controladores de interrupción TX/RX para los puertos SPI y UART que operan en separadores circulares separados. Por lo tanto, en lugar de buscar nuevos bytes y esperar a que se completen las operaciones, simplemente puedo completar los buffers de TX y habilitar la interrupción o verificar los buffers para los datos entrantes. Esto daría muchos más ciclos de reloj para el trabajo real en lugar de esperar a los periféricos.
Después de implementar el IRQ con buffers circulares de 128 bytes, sondeé el buffer UART RX para datos e inmediatamente lo coloqué en el búfer SPI TX para hacer la transferencia de archivos. El problema que tengo con este enfoque es que no tengo suficiente RAM para los búferes y el búfer de recepción de PC se está llenando más rápido de lo que obtengo los datos en el búfer de transmisión de flash. Obviamente, la velocidad de transmisión no es el problema (115.2 kHz in y 2 MHz out), pero hay una espera de ciclo de escritura después de que se transmite cada página de 256 bytes.
Parece que las interrupciones frecuentes SPI bloqueaban algunas de las interrupciones UART y causando bytes se puede perder. La solución que elegí fue usar un buffer de anillo para la interrupción de recepción UART y alimentar los datos en un buffer de página de 256 bytes que se envía al flash serial por sondeo para transferencias de bytes y finalización de escritura. Un buffer de 128 anillos es lo suficientemente grande como para evitar desbordamientos durante la escritura de SPI.
Tenga en cuenta que 1 kB (1024 bytes) de RAM no permite muchos búferes. Sin embargo, es una buena idea. –
Es cierto, aunque también podría tratar de ajustar el tamaño de los búferes (quizás 64 b), pero la sobrecarga de los indicadores comienza a afectar la eficiencia de la memoria. – joshperry
Usaría una sola variable de indicador con mordiscos para cada buffer. –