Hi i am working on embedded system which controls a elevator through serial bus. Every time i send a message (packet contains adress,data length, data, crc) i need to wait for elevator response, which is represented by acknowledgement packet.
ACK is set every time when I receive packet from elevator. Receiving messages is done through Interrupt. ACK packet looks like:
0xA0,0x00,0x00,0x00,0x00
and when it comes I set ACK to true
Here is my send function:
bool TransferService::send(char recAddr,char dataLength, char *data){
pc.putc(startByte);
pc.putc(recAddr);
pc.putc(controllerAddress);
pc.putc(dataLength);
for (int i = 0; i < dataLength; i++) {
pc.putc(data[i]);
}
pc.putc(getCrc(recAddr,controllerAddress,data, dataLength));
_messageReceived = false;
timer.reset();
timer.start();
ACK = false;
do {
if (ACK) {
break;
}
} while(timer.read_ms()<=15);
timer.stop();
if (!ACK) {
send(recAddr,dataLength,data);
}
}
This is only try, it not work.
bool TransferService::send(char recAddr,char dataLength, char *data){
PT_BEGIN();
timer.reset();
timer.start();
do {
pc.putc(startByte);
pc.putc(recAddr);
pc.putc(controllerAddress);
pc.putc(dataLength);
for (int i = 0; i < dataLength; i++) {
pc.putc(data[i]);
}
pc.putc(getCrc(recAddr,controllerAddress,data, dataLength));
_messageReceived = false;
PT_WAIT_UNTIL(!timer.read_ms() <=10 || ACK);
} while(timer.read_ms() <=10);
PT_END();
}
My question is how to make first function work correctly using protothreads.
The structure of a thread function in Adam Dunkels' implementation of Protothreads is quite clear, and your function clearly does not follow it.
A Protothread thread function must return
int
and normally has the signature:and must be defined using the
PT_THREAD
macro thus:From the Protothread documentation...
Looking at the definition of
PT_THREAD
I can see nothing that would prevent its use with a C++ member function, or the use of additional arguments other thanpt
, in which case, the following is closer to correct:In your attempt you had both a do-while loop and a
PT_WAIT_UNTIL
, but the WAIT makes the loop unnecessary. It is not in fact necessary to pass thept
argument, the requiredstruct pt
might be a class member or even a global (although that would be ill-advised).Note that the above follows the pattern evident in the question, but would be an unusual design pattern; most often a thread runs indefinitely rather than for a single transaction. Without knowledge of your entire application, I would suggest that the thread should operate at a higher level than the single transaction
send()
function, such that you have a "sender" thread that can repeatedly perform send operations without exiting as in the following outline (i.e. not complete or "real" code, and with a great many assumptions):Note that due to the manner in which the
PT_...
API works, thePT_WAIT_UNTIL
must be in the same function as thePT_BEGIN
andPT_END
, hence moving the timer wait in the code above.