Umgang mit mehreren Interrupts dsPIC

Ich habe eine Weile über mein Design nachgedacht, konnte aber keinen besseren Weg finden, um mit Pufferüberläufen in mehreren Interrupts umzugehen.

Ein dsPIC33EP- Chip ist mit einem TFT-Display, einem UART-Sensor, einer Micro-SD-Karte und einer UART-Kamera verbunden. Die Baudrate des UART-Sensors beträgt 921600 und die der Kamera (50k pro Bild) 57600 . Die Zeit zum Schreiben des SD-Kartensektors (512 Bytes) beträgt etwas weniger als 2 ms. Die Aktualisierung des Bildschirms (EVE FT800) dauert 20 ms .

Ziel ist es, auf den UART-Sensor zu reagieren (mindestens alle 30 ms) und den Bildschirm entsprechend zu aktualisieren (Etiketten zu aktualisieren) und gleichzeitig Bilder auf die SD-Karte zu schreiben.

Um die Aufgabe aufzuschlüsseln, habe ich erfolgreich mehrere Bilder auf der SD-Karte mit Interrupts gespeichert, wenn nur Kamera und SD-Karte laufen.

Die Interrupt-Routine:

volatile unsigned char buff[512];
volatile unsigned int ptr=0;
volatile unsigned char EOF=0;
volatile unsigned char buffReady=0;
void ISR(){
    static unsigned char temp;
    temp=UART_Read();
    buff[ptr++]=temp;
    if(ptr==512){ptr=0;buffReady=1;}
    if(...){EOF=1;}
}

Während das Programm in einer Schleife steckt, um das EOF-Flag zu prüfen

while(1){
   if(buffReady){SD_Write_Sector(buff);buffReady=0;}//write 512 bytes of image to SD card
   if(EOF){break;}//jump out if the image has been finished
}

Meine Sorge ist, wie integriere ich die Routinen zum Aktualisieren des Bildschirms, während ich Daten vom UART-Sensor empfange? Es sieht so aus, als müsste das buffReady-Flag ständig überprüft werden. Jede Verzögerung zwischen jeder Prüfung kann einige Bytes verlieren, da sie mit neuen Bytes überschrieben werden.

Da die Bildgröße etwa 50 KB und die Baudrate 57600 beträgt, werden jede Millisekunde sechs Bytes von der Kamera kommen. Wenn der Bildschirm dazwischen eine Verzögerung von 20 ms einführt , wird das Bild mit Sicherheit beschädigt.

Ich habe darüber nachgedacht, einen größeren Puffer zum Speichern von Bildern zu verwenden, aber ein größerer Puffer benötigt mehr Zeit, um auf die SD-Karte geschrieben zu werden.

Wie soll ich den Aktualisierungsbildschirm anordnen und das Bild auf die SD-Karte schreiben?

Antworten (1)

Der dsPIC33EP bietet eine DMA-Schnittstelle zum UART (siehe Kapitel 8 des Datenblatts ). Wenn Sie einen Puffer konfigurieren, der groß genug für 20 ms Daten ist, können Sie den DMA so konfigurieren, dass er in diesen Puffer schreibt und dann die Ergebnisse zwischen Bildschirmaktualisierungen liest. Beachten Sie, dass:

57 , 600   B P S 0,02   S e C = 1152   B ich T S = 144   B j T e S
Wenn Sie SPI zum Schreiben auf die SD-Karte verwenden, kann dort auch DMA verwendet werden, um die CPU-Last während der größeren Schreibvorgänge zu begrenzen (der Treiber verfügt möglicherweise bereits über eine integrierte DMA-Unterstützung).

Alternativ könnten Sie das eigentliche Lesen des Puffers im Interrupt durchführen (anstatt ein Flag abzufragen). Dies ist jedoch in den meisten Fällen aus mehreren Gründen eine schlechte Idee:

  • Es sollte so wenig Code wie möglich in Interrupts platziert werden, um die Systemlatenz zu reduzieren;
  • Es hängt von der Methode ab, die zum Ansteuern des Displays verwendet wird, aber es ist wahrscheinlich, dass Leseunterbrechungen, die während einer Bildschirmaktualisierung empfangen werden, zu visuellen Störungen führen;
  • Funktionsaufrufe innerhalb von Interrupts sind selten eine gute Idee - sie erhöhen normalerweise den vom Compiler geschriebenen Pre- und Post-Interrupt-Code (um Register usw. zu sparen) und führen Möglichkeiten für Deadlocks ein, die mit Inline-Code offensichtlicher wären .

Kurz gesagt, DMA ist für die von Ihnen beschriebene Situation gemacht. Es ist normalerweise ein mühsamer Prozess, mehrere DMA-Übertragungen einzurichten und zu debuggen, aber es ermöglicht saubere Anzeigeaktualisierungen aufgrund der längeren Lese- und Schreibvorgänge ohne CPU-Eingriff.

Danke für den Vorschlag. Ich habe vorher über DMA nachgedacht, aber der SD-Kartentreiber unterstützt es nicht. Ich teste es immer noch mit dem richtigen Interrupt und größerem Puffer. Wenn es nicht funktioniert, denke ich, dass das Hinzufügen eines weiteren Chips die endgültige Lösung ist.
Wenn Sie den Quellcode für den SD-Kartentreiber haben, können Sie ihn möglicherweise ändern, um DMA für Schreibvorgänge zu verwenden. Das wird wahrscheinlich einfacher sein, als dem Design ein weiteres Mikro hinzuzufügen. Der Grund, warum DMA in einem Treiber nicht unterstützt wird, liegt häufig darin, dass Konflikte mit anderen Verwendungen von DMA im System auftreten können, aber da Ihnen das System gehört, ist dies kein Problem.