2017-05-23 2 views
0

Ich bin kein Entwickler, ich spiele nur mit der Programmierung, indem ich versuche, meinen Arbeitsplatz unabhängiger zu machen. Ich versuche derzeit, einen Bereich von 9 Threads mit allen unterschiedlichen Prioritäten zu erhalten (0: höchste 8: niedrigste), um den gleichen UART-Port zu verwenden.Erteilen Sie den Zugriff auf eine Ressource basierend auf Thread Priorität/Privileg

Da ich Notfall Anfrage senden Ich würde eine Sperre zu schaffen, die die höchste Priorität Thread ermöglichen, zuerst auf die Ressource zu gehen.

Ich muss auch den receive_data IRQ-Thread erhalten die Hand auf dem UART-Port, sobald es auftritt (oder so schnell wie möglich, Hardware-UART-Puffer ist 500 Bytes lang).

Ich habe mich umgesehen und die Verwendung von verschachtelten Mutex wird mich daran hindern, den Code weiterzuentwickeln, wenn ich mehr Prioritätsstufen/Thread benötige (oder zumindest eine angemessene Menge an Code benötige).

Ich habe diese Frage gelesen: How to give priority to privileged thread in mutex locking? und die zweite Antwort sieht aus wie ich mir wünsche ... aber ich kann nicht verstehen, wie man den Prozess implementiert.

Da die Frage ein bisschen alt ist, gibt es eine andere Möglichkeit zu tun, was ich will? Wenn nicht, kann ich eine lesbarere Version davon (Holzarbeiter) bekommen?

Frage: Wie schützt man den Zugriff auf den UART-Leser/Schreiber & Prioritätszugriff auf Thread auf der Grundlage ihrer Priorität Ebene?

Hinweis:

Themen gerade lesen ein Fifo jeden und schlafen, während die Fifo leer ist und starten, wenn etwas in ihren jeweiligen Fifo gesetzt wird.

Threads verarbeitet dann den Befehl/Daten in einem Format, das von der Hardware und gesendet über UART interpretiert werden kann.

Ich versuche, das zu tun, als ich erkennen, dass manchmal Notfall Befehle, wo vor ~ 1 s oder mehr warten, verarbeitet zu werden, wenn ich bevölkerungs einen einzigen Thread und die Fifo wurde mit.

Auch, sorry, wenn mein Englisch Ihnen Gänsehaut gibt.

+0

Sie bitte Ihre Frage erneut Rahmen zu geben, bessere Klarheit darüber, was Sie fragen. – Ajay

+0

Dies ist eine ziemlich nicht-triviale Arbeit. Die verknüpfte Frage scheint mehrere Beispiele für Code zu enthalten, die ein guter Ausgangspunkt (oder eine vollständige Lösung) wären. Wenn Sie dies nicht nutzen können, sollten Sie Ihr Design überdenken, um Dinge zu vereinfachen, bis Sie etwas daraus machen können funktioniert und wechselt später zu einem komplexeren System. – Rook

Antwort

1

Wie in Kommentaren erwähnt ist eine komplizierte Aufgabe.

Eine Möglichkeit, es zu tun, eine Klasse wie diese zu erstellen: kann

class UART_access_manager 

{ 

typedef std::multimap<int, dispatch_semaphore_t> priority_map_t; 
public: 

UART_access_manager(); 
~UART_access_manager(); 
void access_manager(unsigned int prio, dispatch_semaphore_t pSem); 


private: 

void amInext(unsigned int prio); 
void process_priority(unsigned int prio); 
void priority_locker(unsigned int prio); 
void priority_unlocker(unsigned int prio); 


int count; 
std::mutex data_mtx, priority_0_mtx, mtx; 
priority_map_t priority_map; 
}; 

note Ich baue den Test auf OSX und un-named Semaphore nicht verwendet werden, habe ich nicht überprüfen, ob Der Versand ist auf anderen Betriebssystemen möglich (wahrscheinlich nicht als Apple Lib).

UART_access_manager::UART_access_manager() 

{ 

} 
UART_access_manager::~UART_access_manager() 
{ 

} 



/********************************************************************* 
    * 
    * Function:  void UART_access_manager::access_manager(unsigned 

int prio, dispatch_semaphore_t pSem) 
* 
* Description:  add an UART access request to the queue based on priority & start process based on type 
* 
* Notes:   0 is highest 
* 
* Returns:   none 
* 
*********************************************************************/ 

void UART_access_manager::access_manager(unsigned int prio, dispatch_semaphore_t pSem)//, add parameters at will 
{ 
int counter = 1; //debug only 
while (counter) //should check for termination criteria 
{ 
    //check if something was pushed on the file descriptor 

    if(counter == 10) //add run condition 
    { 
     counter = 0; //debug 

     priority_locker(prio); 

     priority_map_t::iterator it = priority_map.insert(std::pair<int, dispatch_semaphore_t>(prio, pSem)); 
     printf("\n thread with priority %d added to queue(size %lu)", prio, priority_map.size()); 
     amInext(prio); 

     priority_unlocker(prio); 

     while(dispatch_semaphore_wait(pSem, DISPATCH_TIME_NOW) != 0){}; 



     priority_locker(prio); 
     // do the actual job 
     process_priority(prio); 
     // done, remove yourself 
     priority_map.erase(it); 
     if(! priority_map.empty()) 
     { 
      // let next guy run: 
      dispatch_semaphore_signal((priority_map.begin()->second)); 
     } 
     priority_unlocker(prio); 
    } 
    else 
    { 
     std::this_thread::sleep_for(std::chrono::milliseconds(50)); //test purpose only 
     counter++; 
    } 

} 
} 


/********************************************************************* 
* 
* Function:  void UART_access_manager::amInext(unsigned int prio) 
* 
* Description: check if current priority has to run next or not 
* 
* Notes:   0 is highest 
* 
* Returns:  none 
* 
*********************************************************************/ 
void UART_access_manager::amInext(unsigned int prio) 
{ 

if(priority_map.begin()->first == prio) dispatch_semaphore_signal(priority_map.begin()->second); 
} 


/********************************************************************* 
* 
* Function:  void UART_access_manager::process_priority(unsigned 
int prio) 
* 
* Description: TODO 
*********************************************************************/ 
void UART_access_manager::process_priority(unsigned int prio) 
{ 
printf("\n Priority_%d running \n",prio); 
//TODO 
} 

/********************************************************************* 
* 
* Function:  void UART_access_manager::priority_locker(unsigned 
int prio) 
* 
* Description:  lock mutex in a way to guarantee priority event 
to 
*     get the fastest lock possible 
* 
* Notes:   0 is highest 
******************************************************************/ 
void UART_access_manager::priority_locker(unsigned int prio) 
{ 
//Low-priority threads: lock mtx, lock priority_0_mtx, lock data_mtx, 
    unlock priority_0_mtx, 
//High-priority thread: lock priority_0_mtx, lock data_mtx, unlock 
    priority_0_mtx, 
    //this will insure that max priority level get privileged access to 
the data 

if(!prio) 
{ 
    priority_0_mtx.lock(); 
    data_mtx.lock(); 
    priority_0_mtx.unlock(); 
} 
else 
{ 
    mtx.lock(); 
    priority_0_mtx.lock(); 
    data_mtx.lock(); 
    priority_0_mtx.unlock(); 
} 
} 

/********************************************************************* 
* 
* Function:  void 
UART_access_manager::priority_unlocker(unsigned int prio) 
* 
* Description:  unlock mtx based on the mutex locked by the 
priority level 
* 
* Notes:   0 is highest 
* 
* Returns:   none 
* 
*********************************************************************/ 
void UART_access_manager::priority_unlocker(unsigned int prio) 
{ 
if(!prio) 
{ 
    data_mtx.unlock(); 
} 
else 
{ 
    mtx.unlock(); 
    data_mtx.unlock(); 
} 
} 

-Code ist die ausführliche leicht verständlich zu sein und nichts tun, da es, Sie sind gut voran, sehen es als eine Zuordnung, wenn Sie Fragen haben, zu kommentieren, zögern Sie nicht, ich werde antworten .

(HS: Was Sie zu tun versuchen)

Dinge lernst du: std :: multimap std :: Mutex Semaphore Klassen

+0

Versucht, änderte es ein bisschen wie du gesagt hast und es funktioniert perfekt. Will ein bisschen mehr hinein graben. –

Verwandte Themen