嗨,我正在使用嵌入式系统,该系统通过串行总线控制电梯。每当我发送消息时每次我从电梯接收数据包时,
ACK都会设置。接收消息是通过中断完成的。ACK包看起来像:
0xA0,0x00,0x00,0x00,0x00
当它到来时,我将ACK设置为true
这是我的发送函数:
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);
}
}
这只是尝试,它不起作用。
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();
}
我的问题是如何使用原始Rreads使第一个功能正常工作。
Adam Dunkels在原始Reads实现中的线程函数的结构非常清楚,并且您的功能显然不会遵循它。
原始Read线程功能必须返回int
和通常具有签名:
int threadfunction( struct pt* pt ) ;
,必须使用PT_THREAD
宏来定义:
PT_THREAD( threadfunction( struct pt* pt ) )
{
PT_BEGIN(pt) ;
// thread body here
PT_END(pt) ;
}
来自 protothread 文档...
原始Rread功能必须始终返回整数,但绝对不能 明确返回 - 返回在原始Rread中执行 语句。
查看PT_THREAD
的定义,我什么也看不到它可以阻止其与C 成员函数使用或使用pt
以外的其他参数的使用,在这种情况下,以下情况更接近正确:
PT_THREAD( TransferService::send( struct pt* pt, char recAddr, char dataLength, char *data )
{
PT_BEGIN( pt );
timer.reset();
timer.start();
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( pt, timer.read_ms() > 10 || ACK );
PT_END();
}
在您的尝试中,您既有循环又有一个循环,也有一个PT_WAIT_UNTIL
,但是等待使循环不必要。实际上,通过pt
参数不是必需的,所需的struct pt
可能是班级成员,甚至是全局(尽管这将是不明智的)。
请注意,以上内容遵循问题中明显的模式,但将是一种不寻常的设计模式。大部分线程无限期地运行,而不是单个交易。在不了解您的整个应用程序的情况下,我建议 thread 应比单个事务send()
函数更高的级别运行如以下概述(即未完成或"真实"代码,并且有很多假设):
// Constructor...
TransferService::TransferService()
{
PT_INIT( &m_pt ) ; // Where thread state m_pt
// is a member variable of
// type struct pt (or just pt
// since this is C++)
...
}
// Thread function
PT_THREAD(TransferService::senderThread() )
{
PT_BEGIN(&m_pt);
for(;;)
{
PT_WAIT_UNTIL( &m_pt, ready_to_send ) ;
timer.reset();
timer.start();
send( recAddr, dataLength, data ) ;
PT_WAIT_UNTIL( &m_pt, timer.read_ms() > 10 || ACK );
}
PT_END(pt);
}
// Single send transaction 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;
}
请注意,由于PT_...
API的工作方式,PT_WAIT_UNTIL
必须与PT_BEGIN
和PT_END
相同的功能,因此将计时器在上面的代码中移动。