Frage

Ich habe einen Mikrocontroller, der eine große Datei von einem PC seriellen Schnittstelle (115200 Baud) und schreiben Sie es auf seriellen Flash-Speicher über SPI (~ 2 MHz) heruntergeladen werden muß. Die Flash-Schreibvorgänge müssen durch einen Schreibbefehl und Seitenadresse voran in 256-Byte-Blöcken sein. Die gesamte RAM auf dem System verfügbar ist 1 kB mit einer 80-Byte-Stack-Größe.

Dies arbeitet derzeit durch einen 256-Byte-Puffer aus dem UART Füllung und dann Ping-Pong auf einem anderen 256-Byte-Puffer durch einen Interrupt auf dem RX-Puffer bereit Signal gefüllt wird, während der Blitz mit beschäftigt schreibt geschrieben. Der Puffer-Swapping wird wiederholt, bis der Vorgang abgeschlossen ist.

Ich würde die Einrichtung bevorzugen TX / RX-Interrupt-Handler für sowohl den SPI und UART-Ports, die auf separaten Ringpuffer arbeiten. Anstatt also die Abfrage von neuem Bytes und warte auf Operationen, die ich vervollständigen kann einfach die TX-Puffer füllen und das Interrupt aktivieren oder die Puffer für eingehende Daten überprüfen. Dies würde viel mehr Taktzyklen für echte Arbeit geben, anstatt auf Peripheriegeräte des Wartens.

Nachdem die IRQ mit 128-Byte-Ringpuffer Implementierung ich den UART RX-Puffer für Daten abfragen und sofort legen Sie sie in dem SPI-TX-Puffer um die Dateiübertragung zu tun. Das Problem, das ich mit diesem Ansatz habe ist, dass ich nicht über genügend RAM für die Puffer und dem PC-Empfangspuffer füllt sich schneller als ich die Daten über in den Flash-Sendepuffer erhalten. Offensichtlich Übertragungsgeschwindigkeit ist nicht das Problem (115,2 kHz in und 2 MHz out), aber es gibt ein Schreibzyklus Warten nach jeder 256-Byte-Seite übertragen wird.


Es scheint, die häufigen Unterbrechungen SPI wurden einige der UART-Interrupts blockiert und verursachen Bytes zu verpassen. Die Lösung, die ich wählte, war einen Ringpuffer für die UART-Interrupt empfangen zu verwenden und die Daten in einen 256-Byte-Seitenpuffer zuzuführen, die für Byte-Übertragungen an den seriellen Flash durch eine Abfrage gesendet wird und die Fertigstellung schreiben. Ein 128-Ringpuffer ist groß genug, um überläuft während des SPI Schreib zu verhindern.

War es hilfreich?

Lösung

ich tun würde, so etwas wie eine Streuung auf einem PC sammeln. Erstellen Sie eine verknüpfte Liste mit einer Struktur wie folgt aus:

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

Haben Sie eines der Bits in der Flagge bedeuten „ReadyToFlash“ und eine für „Blinken“. Sie sollten die Anzahl der Puffer in verknüpften Liste zu stimmen der Lage sein, um den Blitz zu verhindern, fängt die UART, wie sie schreibt oder umgekehrt.

Wenn der Blitz in einen Pufferblock erhält, die nicht „ReadyToFlash“ es ist, würde abgewürgt und müssen Sie Ihre UART IRQ es beginnt wieder nach oben haben. Wenn der UART zu einem Block bekommt die „ReadyToFlash“ oder „Blinken“ ist es zu schnell füllt und Sie wahrscheinlich einen weiteren Puffer benötigen, wenn Sie die dynamische Speicher haben Sie diese Abstimmung zur Laufzeit tun könnte und einen Puffer in die Liste im laufenden Betrieb hinzufügen , sonst werden Sie nur einige empirische Tests tun müssen.

Andere Tipps

Ist die UART und der PC-Seite der Anwendung Unterstützung RS-232-Handshaking (Flusskontrolle)? Wenn ja, wann Ihre Empfangspuffer ist voll nahe kommt, haben die ISR die CTS-Leitung fallen - wenn der PC-Seite konfiguriert ist, Hardware-Flusskontrolle respektieren sollte es das Senden stoppen, wenn es um diesen Zustand sieht. Sobald Sie (oder nahezu entleert) den Puffer erhalten, behauptet CTS wieder und der PC erneut zu senden soll abgelassen haben beginnen.

Beachten Sie, dass dies die Software auf dem Embedded-Gerät wesentlich komplexer macht -., Ob das ist ein Trade-off Sie bereit sind, zu würde von Ihnen und Ihrem Manager & Team zu Analyse durchgeführt machen

Das ist genau das, was Flusskontrolle erstellt wurde, weiß ich, es ist ein großer Schmerz eingerichtet, aber wenn Sie Flusssteuerung auf der seriellen Leitung Ihrer Probleme Geschichte wäre zu ermöglichen.

Ich gehe davon aus Sie eine Binärdatei sind die Übertragung so XON-XOFF nicht die beste Lösung ist, die Hardware-Flusssteuerung lässt.

Eine weitere Option ist ein Protokoll, mit einem in der Flusssteuerung wie XModem zu verwenden. Ich habe ein ähnliches eingebettetes Projekt, bei dem der Blitz in 128 Byte Seiten geschrieben. Was für ein Zufall, dass XModem Daten in 128 Byte Blöcken sendet dann wartet auf eine ACK, bevor er die nächste sendet.

Nicht sicher, was ich hier fehle, aber wenn die Tatsache ist, dass die durchschnittliche Rate von Daten aus dem PC kommt, ist höher als die durchschnittliche Rate Sie es in den Flash schreiben können, dann sind Sie entweder ein benötigen, viel RAM, oder Sie gehen Flusskontrolle benötigen.

Aber sagen Sie, dass es funktioniert, wenn Sie Blockpuffer hatten, aber jetzt, dass Sie Byte-Puffer haben es nicht?

Können Sie mit den Blockpuffern halten, die durch das UART RX-Interrupt gefüllt sind, und wenn jeder Puffer voll ist, geben Sie es an den SPI / Flash-Code aus, dass der Pufferalarm mit den SPI zu leeren? Das erspart Ihnen jedes Byte zu kopieren, und anstatt die Kreispufferlogik zweimal für jedes Byte zu tun, werden Sie es nur für jeden Block zu tun haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top