Wie kann ich tun, dynamische Datenübertragung und die Speicherverwaltung über Threads in C?

StackOverflow https://stackoverflow.com/questions/689514

  •  22-08-2019
  •  | 
  •  

Frage

Plattform: ARM9

Programmiersprache C

Anforderungen -. Ebene C und keine externen Libs und keinen Auftrieb

OS - REX RTOS

Ich habe zwei Threads in einer Embedded-Plattform ausgeführt wird -

  1. ist ein auf Treiberebene die Comms und alle Daten-Transfer mit dem Hardware-Handling.
  2. der zweite Thread führt die Anwendung, die die Daten zu / von der Hardware verwendet.

Die Idee ist, den App-Thread von dem Fahrer Thread zu entkoppeln, so dass wir die Hardware und die Implementierung in dem Hardware-Treiber Thread ändern können, aber haben nur minimale Auswirkungen auf dem Anwendungs-Thread.

Meine Herausforderung besteht darin, dass die Daten von der Hardware empfangen dynamisch sein kann das heißt wir wissen nicht im Voraus, wie viel Speicher die Anwendungsthread beiseite für jede Anforderung an / von der Hardware eingestellt sollte, da dies zur Laufzeit bestimmt wird.

Ich dachte den Fahrer Thread könnte die Anwendung Thread informieren, dass es so viele Daten zu lesen. Der Anwendungsthread ordnet dann den Speicher und fordert den Fahrer Thread die Daten zu lesen. Es liegt dann an den Anwendungs-Thread die Daten entsprechend zu verarbeiten. Auf diese Weise werden alle Speicherverwaltung innerhalb des Anwendungs-Thread.

War es hilfreich?

Lösung

Paar Optionen in den Sinn kommen:

1) malloc den Speicher in dem Treiber, es in der App freizugeben. Aber ... neigen wir malloc Verwendung in irgendetwas zu vermeiden, die eine Echtzeit-Anforderung zu erreichen. Wenn Sie Zugang zu malloc / free haben, und es gibt keine „Echtzeit“ Bedenken oder Speicherfragmentierungsprobleme (das heißt Ihr Haufen groß genug ist), dann ist dies ein ziemlich einfacher Ansatz. Der Treiber sendet nur den zugeordneten Zeiger auf den Thread App über eine Nachrichten-Warteschlange und die APP der Speicher, wenn fertig. Achten Sie auf Speicherlecks.

2) Ring oder Ringpuffer. Der Fahrer steuert vollständig eine feste Puffergröße Ring und sendet einfach eine Nachricht an die Anwendung, wenn ein Puffer bereit ist. Sehen Sie hier einige Details: Ringpuffer . Dann markiert die Anwendung die Daten „verfügbar“ wieder über einen Treiber-API, die die Ringpuffer Details aus dem App-Thread helfen verstecken. Wir verwenden diesen Ansatz für ein unseren Fahrer, die einen sehr ähnlichen Satz von Anforderungen haben, wie Sie beschreiben. In diesem Fall müssen Sie mit der Bestimmung der „beste“ Größe für den Ringpuffer betroffen sein, Überlauf in dem Fahrer Handhabung usw.

viel Glück!

Andere Tipps

Sie haben kein O angeben, aber Sie irgendwie „Fäden“ haben. Außer, dass eine von ihnen auf Treiberebene (Interrupt-Handler) und die anderen Töne wie eine Anwendung (Userland / kernel). Aber das ist auch nicht zusammenpassen, weil Sie Ihre Fahrer und App kommunizieren, bevor die Daten auch verarbeitet werden.

Ihre Terminologie ist verwirrend und nicht ermutigend. Ist das ein homebrew (RT) OS oder nicht?

Wenn Sie ein echtes O haben, werden Verfahren festgelegt für Fahrer und Gabe Daten an Userland zu schreiben. Lesen Sie die Dokumentation oder verwenden Sie eine der vorhandenen Treiber als Referenz.

Wenn dies eine benutzerdefinierte OS können Sie zu anderen Open-Source beziehen sich noch Treiber für Ideen, aber Sie werden klar die Dinge nicht so bequem eingerichtet haben. Preallocate der gesamten Speicher im Treibercode, mit Daten füllen, wie es kommt, und gibt es an den Anwendungscode aus. Die Größe des Speichers wird eine Funktion, wie schnell Ihre App-Daten verarbeiten kann, die größte Menge an Daten, die Sie übernehmen möchten, und wie viel interne Datenwarteschlangen benötigt wird, Ihre Anwendung zu unterstützen.

Dieses Wesen C, ich habe mit endete bis die App einen Rückruf mit dem Fahrer machen registrieren. Der Zweck des Callback ist, die Daten zu verarbeiten, nachdem der Fahrer es aus dem Gerät ausliest. Der Fahrer steuert den Speicher d.h. ordnet Speicher zu, ruft die Rückruf und schließlich gibt Speicher frei. Darüber hinaus hat der Rückruf nur die Erlaubnis auf dem Speicher gelesen. Daher sollte die App ideal kopieren Sie einfach den Inhalt des Puffers auf seinen eigenen Speicher und Ausstieg aus dem Rückruf sofort. Dann ist es frei, die Daten zu verarbeiten, wann und wie er will.

ich die Dokumentation aktualisiert, um es für die Verwendung des App-Callback deutlich zu machen, dass es angenommen wird, wenn die Rückrufzurückkehrt, sollte der Speicher nicht mehr als gültig betrachtet werden. Wenn der Rückruf andere Art und Weise verwendet wird, ist das Verhalten nicht definiert.

Mein erster Gedanke wäre Ringpuffer zu verwenden. Hier ist ein Beispiel-Code. Fühlen Sie sich frei, dies zu Ihren eigenen Anwendungen anzupassen. Sie würden wahrscheinlich nicht globale Variablen wollen. Und Sie könnten nicht #defines wollen:

#define LENGTH (1024)
#define MASK (LENGTH-1)
uint8 circularBuffer[ LENGTH ];
int circularBuffer_add = 0;
int circularBuffer_rmv = 0;

void copyIn( uint8 * circularBuffer, uint8 * inputBuffer, int n ) {
    int i;
    for( i = 0; i < n; i++ ) {
        circularBuffer[ circularBuffer_add ] = inputBuffer[ i ];
        circularBuffer_add = ( circularBuffer_add + 1 ) & MASK;
    } 
}

void copyOut( uint8 * circularBuffer, uint8 * outputBuffer, int n ) {
    int i;
    for( i = 0; i < n; i++ ) {
        outputBuffer[ i ] = circularBuffer[ circularBuffer_rmv ];
        circularBuffer_rmv = ( circularBuffer_rmv + 1 ) & MASK;
    } 
}

Auch der obige Code wird davon ausgegangen, dass Ihr Gerät von Daten-Datentyp „uint8“. Sie können es ändern, so dass es einen anderen Datentyp verwendet. Oder Sie können sogar machen es allgemeine und Verwendung Memcpy (), um zu kopieren, in das digitalen ringspeicher.

Das Hauptmerkmal dieses Codes ist, wie es das Add und rmv ptr behandelt.


Wenn Sie die Dinge der Arbeit mit dem obigen Code. Ich schlage vor, an einem gewissen Punkt Umschaltung alle liest aus dem Hardware-Plattform Direkt Gedächtnis- zu verwenden Zugang API .

Es ist wichtig direkten Speicherzugriff zu wechseln, da der obige Code eine Menge von Zyklen in Bezug auf DMA verwendet , die fast Null Zyklen verwendet.

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