Ich mache eine einfache Kommunikation zwischen einem ARM-MCU und einem GSM-Modul.
Das Problem, mit dem ich konfrontiert bin, ist, wie ich mit dem gleichzeitigen Schreiben und Lesen in und aus dem FIFO-Puffer umgehen soll.
Aufgrund der Größe des Programms habe ich ein großes Pufferarray von 1000 Bytes Länge.
Im Moment wird jedes Mal, wenn ein Byte im Datenregister des UART empfangen wird, ein Interrupt ausgelöst, und die Interrupt-Routine füllt meinen 1-KB-FIFO.
Meine Leseroutine berechnet die verfügbaren Daten im FIFO und kopiert einige der Daten in einen zweiten Puffer zur weiteren Verarbeitung.
Die Interrupt-Routine stoppt, um mehr Daten zu speichern, wenn kein Platz mehr im FIFO-Puffer vorhanden ist, um ein Überschreiben des Lesezeigers zu verhindern, falls mein Hauptprogramm nicht die Zeit hatte, die Daten zu verarbeiten.
Jetzt versuche ich, die beste Lösung zu finden, um das Überschreiben des Lesezeigers zu verhindern, während die Interrupt-Routine nie aufhört, Daten zu speichern. Gibt es dafür eine Lösung oder ist das Überschreiben unvermeidlich?
Auf UART-Empfangsereignis:
FIFO[Wr_pointer]= UART_Char;
WR_Pointer++;
WR_Pointer & = 3FF;// FIFO[1024] roll over 1022..1023...0...1...2
if WR_Pointer==RD_Pointer then
Overrun= true;
else
{
SizeFIFO = (WR_Pointer - RD_Pointer);
SizeFIFO & = 3FF;
}
Beispiel Ringspeicher. Es besteht keine Notwendigkeit, Daten vom FIFO an einen anderen Ort zu kopieren, da die Daten einfach überschrieben werden.
In der Bewerbung:
SizeFIFO_temp = SizeFIFO; //you don't want a bug when ISR will insert new data while processing the buffer
for i=0 to SizeFIFO_temp do
{
Data[i]=FIFO[RD_Pointer]; //it's all up to you how you process the FIFO's data
RD_Pointer++;
RD_Pointer &= 3FF;
}
SizeFIFO = (WR_Pointer - RD_Pointer);
SizeFIFO & = 3FF;
Das Problem, mit dem ich konfrontiert bin, ist, wie ich mit dem gleichzeitigen Schreiben und Lesen in und aus dem FIFO-Puffer umgehen soll.
Sequentiell Nicht parallel.
Jetzt versuche ich, die beste Lösung zu finden, um das Überschreiben des Lesezeigers zu verhindern, während die Interrupt-Routine nie aufhört, Daten zu speichern
Code darf nie immer im ISR vorhanden sein (allgemein je nach Anwendung). Sie brauchen Zeit, um Daten zu kopieren, Daten zu verarbeiten, Flags und verschiedene Zustände zurückzusetzen usw., bevor eine neue Anfrage verarbeitet werden kann. Wenn Sie immer Daten empfangen, wann erledigen Sie den Rest?.
1.Wenn ein Interrupt auftritt: Deaktivieren Sie den Interrupt (viele vergessen dies)
2.Da Sie einen 1K-Puffer haben (Speicherverschwendung, implementieren Sie einen Ringpuffer mit geringerer Länge), kopieren Sie die Daten in einen Puffer und beobachten Sie einen Zähler, wenn die für eine Verarbeitung erforderliche Mindestanzahl von Bytes empfangen wird. Vergessen Sie nicht, ISR wieder zu aktivieren und den Zähler zurückzusetzen, bevor Sie ISR verlassen.
3. Wenn die für eine Verarbeitung erforderliche Mindestanzahl von Bytes empfangen wurde, verarbeiten Sie die Daten.
Alternativ können Sie den uC zum Master machen, der den GSM bei Bedarf nach Daten abfragt, sodass Sie die Kontrolle haben, anstatt dass GSM Ihnen immer Daten sendet.
Andi aka
Trevor_G
TurboJ
MrBit
Marko Buršič
Marko Buršič
Trevor_G
Bruce Abbott
MrBit
Sean Houlihane
Benutzer105652
KalleMP
Lundin