¿Cómo manejan grandes transferencias de datos en la memoria muy limitada, los sistemas integrados?

StackOverflow https://stackoverflow.com/questions/359745

Pregunta

Tengo un microcontrolador que se debe descargar un archivo grande de un puerto serie del PC (115200 baudios) y escribirlo en la memoria flash en serie en la SPI (~ 2 MHz). Las escrituras Flash debe estar en 256 bloques de bytes precedidos por un comando de escritura y la dirección de la página. La RAM total disponible en el sistema es de 1 kB con un tamaño de la pila 80 byte.

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 tampón se repite hasta que se completa la operación.

Yo preferiría configuración de TX / RX de interrupción controladores para ambos puertos SPI y UART que operan en el buffer circular separadas. Así, en lugar de votación para nuevos bytes ya la espera de operaciones para completar puedo sólo tiene que rellenar los buffers TX y permiten la interrupción o comprobar los buffers para los datos entrantes. Esto daría mucho más ciclos de reloj para el trabajo real en lugar de esperar a los periféricos.

Después de la aplicación de las IRQ de 128 bytes con buffer circular, que sondean el búfer UART RX para los datos e inmediatamente se coloco en el buffer de TX SPI para hacer la transferencia de archivos. El problema que estoy teniendo con este enfoque es que no tengo suficiente memoria RAM para los tampones y el PC búfer de recepción está llenando más rápido de lo que recibo de los datos a la memoria intermedia de transmisión flash. Obviamente, la velocidad de transmisión no es el problema (115,2 kHz y 2 MHz a cabo), pero hay una espera 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 utilizar un búfer de anillo para la UART recibir interrupción y alimentar los datos en una memoria intermedia de página de 256 bytes que se envía al flash en serie mediante un sondeo para las transferencias de byte y escribir su finalización. Una memoria intermedia 128 anillo es lo suficientemente grande como para evitar desbordamientos durante la escritura de SPI.

¿Fue útil?

Solución

Me gustaría hacer algo así como una dispersión de reunir en un PC. Crear una lista enlazada de una estructura como esta:

typedef struct data_buffer {
    char flags;
    char[128] data;
}

tiene uno de los bits de la bandera significa "ReadyToFlash" y otra para "intermitente". Usted debe ser capaz de ajustar el número de buffers en su lista enlazada a mantener el flash de la captura de la UART, ya que escribe o viceversa.

Si el flash se pone a un bloque de memoria intermedia que no es "ReadyToFlash" que se detuviera y que había necesidad de tener su UART IRQ se inicia una copia de seguridad. Si la UART llega a un bloque que es "ReadyToFlash" o "intermitente" se está llenando demasiado rápido y es probable que tenga otro buffer, si tiene memoria dinámica que podría hacer esta afinación en tiempo de ejecución y añadir un tampón a la lista de la mosca , de lo contrario sólo tiene que hacer algunas pruebas empíricas.

Otros consejos

¿El UART y el lado del PC del soporte de aplicaciones RS-232 protocolo de enlace (control de flujo)? Si es así, cuando el búfer de recepción se acerca a estar lleno, tiene el ISR caer la línea CTS - si el lado del PC está configurado para respetar el control de flujo por hardware que debería dejar de enviar cuando se ve esta condición. Una vez que haya drenado (o casi drenado) el búfer de recepción, CTS valer de nuevo y el PC debe empezar a enviar de nuevo.

Tenga en cuenta que esto hace que el software en el dispositivo integrado considerablemente más complejo -. Si esto es una solución de compromiso que está dispuesto a hacer que tendría que ser el análisis hecho por usted y su gerente y equipo

Esto es exactamente lo que el control de flujo fue creado para, Sé que es un gran dolor de configuración, pero si se habilita el control de flujo en la línea serie sus problemas sería la historia.

Estoy asumiendo que usted está transfiriendo un archivo binario de modo XON-XOFF no es la mejor solución, lo que deja el control de flujo por hardware.

Otra opción es usar un protocolo con control de flujo incorporado como XModem. Tengo un proyecto embebido similar donde el flash está escrito en las páginas 128Byte. Qué casualidad que XModem envía datos en fragmentos 128Byte luego espera un ACK antes de enviar el siguiente.

No está seguro de lo que me falta aquí, pero si el hecho es que la tasa promedio de los datos procedentes del PC es más alta que la tasa promedio se puede escribir en la memoria flash, entonces está bien va a necesitar una gran cantidad de memoria RAM, o si va a necesitar de control de flujo.

Pero ¿estás diciendo que funcionó cuando tuvo buffers de bloques, pero ahora que tiene memorias intermedias de bytes no es así?

¿Se puede seguir con los buffers de bloques que se llenan por la interrupción del UART RX, y cuando cada búfer está lleno, mano apagado al código / flash SPI para vaciar ese búfer mediante la interrupción de SPI? Eso le ahorrará copiar cada byte, y en lugar de tener que hacer la lógica de buffer circular dos veces para cada byte, sólo tendrá que hacerlo para cada bloque.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top