000
18.06.2019, 13:16 Uhr
herrmann_wst
|
Hallo zusammen, ich stehe vor einem kleinen Problem. Ich habe ein Programm das Daten dauerhaft über eine Schnittstelle senden soll. Heist ich habe eine Funktion mit der ich die zu sendenden Werte updaten kann und das Senden selbst läuft asyncron.
In meiner main lege ich nun einen Vector an, welchen ich dann an meine "update" (in meinem Programm send()) übergebe.
Diese send() Funktion kopiert den Inhalt in einen Anderen Vector. Da auf diesen zweiten Vector auch auf aus dem Thread (pthread) zugegriffen wird, ist dieser Kopiervorgang durch einen mutex lock geschützt.
füttere Ich den Vector folgendermaßen mit daten, funktioniert alles einwandfrei:
C++: |
data.push_back(1); data.push_back(1); data.push_back(1); data.push_back(1); data.push_back(1);
|
ist aber halt unschön. Daher folgende Idee:
C++: |
for(uint8_t j = 0; j < 5; j++) { data.push_back(1); }
|
ABER: mit dieser Lösung bleibt das Programm beim Aufruf von send(), genauer beim mutex lock, stehen. Der Inhalt und die größe des Vectors stimmen aber. Sieht so aus als wäre der mutex dann schon gelockt. Zu Testzwecken habe ich auch den Thread erstmal nicht gestartet, gleiches Problem. Da der Thread nicht läuft kann der mutex ja aber eigentlich garnicht gelockt sein. Raceconditions dürften da ja ausgeschlossen sein. Oder habe ich da was falsch verstanden?
Das gesamte Programm sieht folgendermaßen aus:
Main:
C++: |
#include<iostream> #include<vector> #include"./PN512/sender.h"
int main(void) {
PN512Sender snd; //snd.start(); //start Thread, vorerst auskommentiert std::vector<uint8_t> data; uint8_t counter = 0; //ja, ich weis dass der im laufe des Programms überläuft. Das ist aber so gewollt und funktioniert auch
//nicht funktionierender Teil: for(uint8_t j = 0; j < 5; j++) { data.push_back(1); }
/* //Funktionierender Teil: data.push_back(1); data.push_back(1); data.push_back(1); data.push_back(1); data.push_back(1); */
while(1) { data[0] = counter; counter++; snd.send(&data[0], data.size()); sleep(1); } }
|
Klasse PN512Sender (erst header, dann .cpp):
C++: |
#include<pthread.h> #include"./pn512.h" #include<vector> #include<unistd.h>
class PN512Sender { private: std::vector<uint8_t> sendBuffer; pthread_mutex_t lock; bool run; pthread_t snd_thd; PN512 pn;
public: PN512Sender(); void start(void); void stop(void); void send(uint8_t *dataToSend, uint8_t dataSize); void clearSendBuffer();
private: static void * sendLoopEntry(void * self); void* sendLoop(void);
};
|
C++: |
#include "sender.h"
PN512Sender::PN512Sender() { pn.PCD_Init(); run = false; }
void PN512Sender::start(void) { run = true; pthread_create(&snd_thd, NULL, sendLoopEntry, this); }
void PN512Sender::stop(void) { run = false; pthread_join(snd_thd, NULL); }
void PN512Sender::send(uint8_t *dataToSend, uint8_t dataSize) { if(dataSize > 0 && dataToSend != NULL) {
std::cout <<"send"<<std::endl; pthread_mutex_lock(&lock); //programm bleibt hier stehen std::cout <<"send2"<<std::endl;
this->sendBuffer.clear();
sendBuffer.push_back(dataSize + 2); for(uint8_t i = 0; i < dataSize; i++) this->sendBuffer.push_back(dataToSend[i]); sendBuffer.push_back(dataSize + 2);
pthread_mutex_unlock(&lock); } }
void PN512Sender::clearSendBuffer() { pthread_mutex_lock(&lock); this->sendBuffer.clear(); pthread_mutex_unlock(&lock); }
void * PN512Sender::sendLoopEntry(void * self) { return static_cast<PN512Sender*>(self)->sendLoop(); }
void* PN512Sender::sendLoop(void) { while(run) { //clear FIFO pn.PCD_WriteRegister(pn.FIFOLevelReg, 0x80); //pn wird ausschließlich vom Thread genutzt, daher kein mutex
pthread_mutex_lock(&lock); if(sendBuffer.size() > 0) { pn.PCD_WriteRegister(pn.FIFODataReg, sendBuffer.size(), &sendBuffer[0]); pthread_mutex_unlock(&lock); } else { pthread_mutex_unlock(&lock); continue; }
//start Transmission pn.PCD_WriteRegister(pn.CommandReg, pn.PCD_Transmit); //wait for Transmission to complete while(pn.PCD_ReadRegister(pn.CommandReg) == pn.PCD_Transmit);
} pthread_exit(NULL); }
|
Kann mir jemand erklären was ich da falsch mache?
MfG herrmann_wst Dieser Post wurde am 18.06.2019 um 13:21 Uhr von herrmann_wst editiert. |