C 中的原始Reads



嗨,我正在使用嵌入式系统,该系统通过串行总线控制电梯。每当我发送消息时每次我从电梯接收数据包时,

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_BEGINPT_END相同的功能,因此将计时器在上面的代码中移动。

相关内容

  • 没有找到相关文章

最新更新