Parallelitätsprobleme mit Ringpuffer im eingebetteten Programm

Ich arbeite an einem eingebetteten Programm auf dem Mikrocontroller TM4C123GH6PM des LaunchPad der Tiva C-Serie von Texas Instruments.

Das Programm soll einen externen ADC in einem Timer-Interrupt abtasten und die konvertierten Werte in eine Warteschlange (in diesem Fall einen Array-basierten Ringpuffer) schieben.

Die Hauptschleife überträgt die Werte (Knallen von Bytes aus der Warteschlange) über den UART an einen PC.

Innerhalb des Timer-Interrupts wird überprüft, ob in der Warteschlange Platz verfügbar ist. Wenn dies der Fall ist, werden Bytes in die Warteschlange geschoben. Wenn nicht, stoppt es den Timer. Die Hauptschleife überträgt die verbleibenden Bytes und startet den Timer erneut, sobald die Warteschlange leer ist (alle Bytes wurden übertragen).

Mein Problem ist, dass der Timer nicht immer gestoppt wird, auch wenn die Warteschlange voll ist.

Könnte dies ein Parallelitätsproblem sein? Wenn ja, wie löse ich es?

Übrigens habe ich mit Sperren herumgespielt, aber das verursacht Deadlocks. Ich habe auch sichergestellt, dass die Warteschlange und die zugehörigen Variablen, auf die sowohl die Hauptschleife als auch der Timer-Interrupt zugreifen, als flüchtig deklariert sind.

Vielen Dank im Voraus :-)

Ich glaube nicht, dass jemand wirklich helfen kann, ohne Ihren Code zu sehen.
Mein Code ist zu komplex, um sofort gepostet zu werden. Wenn ich meinen Code gepostet habe, wird überhaupt nichts Sinn machen. Ich habe eher eine allgemeinere Antwort auf das Problem. Ich denke, mein Problem mit einer Hauptschleife und einem Interrupt-Handler, die mit denselben Daten interagieren, ist ein sehr häufiges Problem?
Sie müssen nicht alles posten, nur die Teile, die nicht richtig funktionieren. Vielleicht nur die Timer-ISR, wo Sie den Timer stoppen.

Antworten (1)

Wenn Ihre Warteschlange genau einen Producer und einen Consumer hat, stellen Sie sicher, dass der Consumer immer eine höhere Priorität hat. Nachdem dies erreicht ist, verursacht die Parallelität keine Probleme mehr. Die Implementierung hängt von der verwendeten Hardware ab, hier ist (mein) Code, der eine solche Warteschlange auf PIC24 micro verwendet -> https://github.com/felis/lcdtune/blob/master/lcdtune.c . Die Queue, sowie Head und Tail werden hier definiert -> https://github.com/felis/lcdtune/blob/master/lcdtune.c#L50 , der Producer ist hier -> https://github.com/ felis/lcdtune/blob/master/lcdtune.c#L233 , und der Verbraucher (der ISR) ist hier -> https://github.com/felis/lcdtune/blob/master/lcdtune.c#L102

Vielen Dank. Es wird einige Zeit dauern, bis ich herausfinde, was los ist, da ich nicht an PIC gewöhnt bin, aber es kann nicht so schwer sein. Ich schätze, mein Problem könnte sein, dass der Verbraucher (das Knallen von Bytes der Warteschlange) eine niedrigere Priorität hat (Hauptschleife) als mein Erzeuger (Timer ISR), richtig?
Nichts im Warteschlangencode ist Hardware-spezifisch. Die Priorität von allem außerhalb des Interrupts ist null, und der letzte Link zeigt auf den Interrupt.
Also habe ich mir Ihren Code angesehen und es scheint mir, dass Sie das Gegenteil von dem tun, was ich tun möchte. Ihre ISR verbraucht und Ihre Hauptschleife produziert. Vielleicht könnte ich meinen Verbrauchercode in einen Software-Interrupt mit höherer Priorität als meinen Timer-Interrupt (Produzenten) stecken?
Ich habe das Problem jetzt behoben, indem ich den Verbraucher in einen Interrupt mit höherer Priorität als meine Timer-ISR gelegt habe. vielen dank für deine lösung :-)