Domanda

Ho un microcontrollore che deve scaricare un file di grandi dimensioni da una porta seriale del PC (115200 baud) e scriverlo in una memoria flash seriali su SPI (~ 2 MHz). Le operazioni di scrittura flash deve essere in 256 blocchi di byte preceduto da un comando di scrittura e di indirizzo della pagina. La RAM totale disponibile sul sistema è 1 kB con una dimensione di stack di 80 byte.

Questo sta lavorando riempiendo un buffer di 256 byte dal UART e poi ping-ponging ad un altro buffer 256 byte essere riempito da un interrupt sul segnale di pronto tampone RX mentre il flash viene scritto con scrittura occupato. Lo scambio di buffer viene ripetuto fino al completamento dell'operazione.

preferirei configurazione TX / RX interrupt gestori per entrambi i SPI e porti UART che operano sui buffer circolari separate. Così, invece di polling per nuovi byte e in attesa di operazioni per completare posso semplicemente riempire i buffer TX e attivare l'allarme o controllo buffer per i dati in ingresso. Questo darebbe molto di più cicli di clock per il lavoro vero e proprio, invece di aspettare sulle periferiche.

Dopo l'implementazione delle IRQ con buffer circolari 128 byte, ho sondaggio il buffer UART RX per i dati e metterlo immediatamente nel buffer SPI TX per fare il trasferimento di file. Il problema che sto avendo con questo approccio è che non ho memoria RAM sufficiente per i buffer e il PC buffer di ricezione si sta riempiendo più velocemente di quanto ricevo i dati sopra al buffer Flash trasmissione. Ovviamente, la velocità di trasmissione non è il problema (115,2 kHz e 2 MHz out), ma c'è un ciclo di scrittura attesa dopo ogni pagina di 256 byte viene trasmesso.


Risulta frequenti interruzioni SPI bloccavano alcuni interrupt UART e causando byte perdere. La soluzione che ho scelto era di usare un buffer circolare per l'UART ricevere interrupt e alimentare i dati in un buffer di pagina 256 byte che viene inviato al flash seriale polling per i trasferimenti di byte e scrivere completamento. Un buffer 128 anello è sufficientemente grande da evitare overflow durante la scrittura SPI.

È stato utile?

Soluzione

mi piacerebbe fare qualcosa di simile a una dispersione si riuniscono su un PC. Creare una lista concatenata di una struttura come questa:

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

Avere uno dei bit nella bandiera significa "ReadyToFlash" e uno per "lampeggiante". Si dovrebbe essere in grado di sintonizzare il numero di buffer nella vostra lista collegata per mantenere il flash dalla cattura del UART come si scrive, o viceversa.

Se il flash arriva a un blocco di buffer che non è "ReadyToFlash" sarebbe stallo e ci sarebbe bisogno di avere il vostro UART IRQ avviare il backup. Se l'UART arriva a un blocco che è "ReadyToFlash" o "lampeggiante" si sta riempiendo troppo veloce e probabilmente bisogno di un altro buffer, se si dispone di memoria dinamica che si possa fare questa messa a punto in fase di esecuzione e aggiungere un buffer per la lista al volo , altrimenti avrete solo bisogno di fare qualche prova empirica.

Altri suggerimenti

L'UART e il lato PC del supporto delle applicazioni RS-232 handshaking (controllo del flusso)? Se è così, quando il buffer di ricezione si avvicina a essere pieno, hanno l'ISR cadere la linea CTS - se il lato PC è configurato in modo da rispettare il controllo di flusso hardware dovrebbe interrompere l'invio quando vede questa condizione. Una volta che avete svuotato (o quasi prosciugato) il buffer di ricezione, affermare ancora una volta CTS e il PC dovrebbe iniziare a inviare di nuovo.

Si noti che questo rende il software sul dispositivo embedded molto più complessa -. Che sia un trade-off si è disposti a fare avrebbe dovuto essere l'analisi fatta da voi e il vostro manager e team di

Questo è esattamente ciò che il controllo di flusso è stato creato per, so che è un dolore enorme set up, ma se si attiva il controllo di flusso sulla linea seriale vostri problemi sarebbe storia.

sto supponendo che si sta trasferendo un file binario in modo XON-XOFF non è la soluzione migliore, che lascia il controllo di flusso hardware.

Un'altra opzione è quella di utilizzare un protocollo di controllo di flusso incorporato come XModem. Ho un progetto incorporato simile dove il flash è scritto nelle pagine 128byte. Che coincidenza che XModem invia i dati in blocchi 128byte quindi attende un ACK prima di inviare il successivo.

Non so cosa mi manca qui, ma se il fatto è che il tasso medio di dati provenienti dal PC è superiore al tasso medio è possibile scrivere al flash, allora sei o avrà bisogno di un sacco di RAM, o si sta andando ad avere bisogno di controllo del flusso.

Ma stai dicendo che ha funzionato quando si aveva buffer di blocco, ma ora che avete i buffer di byte non lo fa?

Si può rimanere con il buffer di blocchi che vengono riempite dal interrupt UART RX, e quando ogni buffer è pieno, passarlo al codice / Flash SPI svuotare tale buffer utilizzando l'interrupt SPI? Che vi farà risparmiare la copia di ogni byte, e, invece di dover fare la logica buffer circolare due volte per ogni byte, si avrà solo a farlo per ogni blocco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top