我正在尝试编写一个程序来将文件上传到 arduino。该程序可以打开一个串行端口并从 arduino 接收数据。当我尝试对处于状态图状态的函数使用回调时,问题就出现了,程序崩溃了。
我以前从未使用过 boost,并决定这是一个尝试的好机会。
我有一个带有基本转换的状态图对象:空闲;-> 开港;-> 端口开放;-> 等待曲线选择确认;-> 选择文件;-> 等待文件接收;-> 比较文件;-> 关闭程序;
还有一个端口关闭状态,但工作正常。
我的主程序只有以下
int main(int argc, char* argv[]){
if(argc!=4){
cerr<<"Usage: serialPort baudRate file"<<endl;
return 1;
}
try {
myInterface deviceInterface;
stateMachine fsm(deviceInterface);
fsm.initiate();
} catch (std::exception& e) {
cerr<<"Exception: "<<e.what()<<endl;
}
}
我可以打开串口并完美接收数据。当我尝试对处于 WaitForCurveChoiceConfirmation 状态的函数使用回调时,问题就出现了。arduino 每隔几秒钟发送一条消息,当程序收到完整消息时,我使用回调。一旦收到消息并调用回调,我的程序就会崩溃。
WaitForCurveChoiceConfirmationState 如下
class WaitForCurveChoiceConfirmation: public sc::state< WaitForCurveChoiceConfirmation, Active > {
public:
WaitForCurveChoiceConfirmation(my_context ctx);
typedef boost::mpl::list<
sc::custom_reaction< EvSensorChoiceConfirm > ,
sc::custom_reaction< EvSensorChoiceTimeout >
> reactions;
sc::result react( const EvSensorChoiceConfirm & );
sc::result react( const EvSensorChoiceTimeout & );
void curveChoiceConfirmed(myMessage & msg);
};
WaitForCurveChoiceConfirmation::WaitForCurveChoiceConfirmation(my_context ctx): my_base( ctx ){
context< stateMachine >().getInterface().setfullMsgReceivedCallback(boost::bind(&WaitForCurveChoiceConfirmation::curveChoiceConfirmed, this, _1));
}
void WaitForCurveChoiceConfirmation::curveChoiceConfirmed(my1100Message & msg){
std::cout << "curveChoiceConfirmed callback " << std::endl;
if(msg.isExpectingTemperatureCurve()){
post_event( EvSensorChoiceConfirm() );
}
}
sc::result WaitForCurveChoiceConfirmation::react( const EvSensorChoiceConfirm & ){
std::cout<<"EvSensorChoiceConfirm"<<std::endl;
return transit<ChooseFile>();
}
sc::result WaitForCurveChoiceConfirmation::react( const EvSensorChoiceTimeout & ){
return transit<PortClosing>();
}
myInterface类的相关部分如下
class myInterface: public CallbackAsyncSerial
{
/** Default constructor */
myInterface();
/** Default destructor */
virtual ~myInterface();
void processReceivedData(const char *data, unsigned int len);
void setfullMsgReceivedCallback( boost::function<void(myMessage &msg )>);
void clearfullMsgReceivedCallback( );
private:
boost::circular_buffer<char> * incomingMsg;
static const int MESSAGE_DATA_LENGTH = 73; //length of data, not including flags or checksum
static const uint8_t PROTOCOL_OUTGOING_LENGTH = 22; // number of characters in received message
uint8_t receive_buffer[MESSAGE_DATA_LENGTH + 2]; // plus 2 for checksum
char outgoingMsg[PROTOCOL_OUTGOING_LENGTH + 1];
uint8_t statusByte;
uint8_t statusByte2;
uint8_t userByte;
uint8_t userByte2;
uint8_t notificationByte;
uint8_t errorByte;
uint8_t actionByte;
int msgIndex ;
int flagIndex ;
int byteCount;
int checkSum ;
int dispPreambleCount ;
int rcvCalculatedCheckSum ;
char rcvdFlag;
dispMsgState_t dispMsgState ;
static const int FLAG_COUNT = 17;
static const char flags[FLAG_COUNT] ;
boost::function<void(myMessage & msg )> fullMsgReceivedCallback;
};
// this is used as a callback in CallBackAsyncSerial. It takes the data received by serial and processes it
void myInterface::processReceivedData(const char *data, unsigned int len)
{
for (unsigned int i = 0; i < len; i++)
{
incomingMsg->push_back(data[i] );
switch (dispMsgState){
case DISP_PREAMBLE: {//msg start flags
//std::cout << "DISP_PREAMBLE " <<std::endl;
if(incomingMsg->back() == START_FLAG){
dispPreambleCount++;
if (dispPreambleCount == 5){
dispMsgState = DISP_BYTE;
msgIndex = 0;
flagIndex = 0;
rcvCalculatedCheckSum = 5 * START_FLAG;
dispPreambleCount = 0;
rcvdFlag = 0;
}
}
else{
dispPreambleCount = 0; //reset counter if a different character was found
}
incomingMsg->pop_back();
}
break;
case DISP_BYTE:{ //status, user, notification, error bytes
rcvCalculatedCheckSum += incomingMsg->back();
receive_buffer[msgIndex] = incomingMsg->back();
msgIndex++;
incomingMsg->pop_back();
if (msgIndex == 7){
dispMsgState = DISP_INTEGER_FLAG;
}
}
break;
case DISP_INTEGER_FLAG:{ //integer flag
rcvCalculatedCheckSum += incomingMsg->back();
rcvdFlag = incomingMsg->back();
incomingMsg->pop_back();
dispMsgState = DISP_INTEGER;
}
break;
case DISP_INTEGER:{ // integers
rcvCalculatedCheckSum += incomingMsg->back();
if(rcvdFlag == flags[flagIndex]){
receive_buffer[msgIndex] = incomingMsg->back();
}
incomingMsg->pop_back();
msgIndex++;
byteCount++;
if (byteCount >= 2){
if(msgIndex < 21){
dispMsgState = DISP_INTEGER_FLAG;
}
else{
dispMsgState = DISP_FLOAT_FLAG;
}
byteCount = 0;
flagIndex++;
}
}
break;
case DISP_FLOAT_FLAG:{ // float flag
rcvCalculatedCheckSum += incomingMsg->back();
rcvdFlag = incomingMsg->back();
incomingMsg->pop_back();
dispMsgState = DISP_FLOAT;
}
break;
case DISP_FLOAT:{ // floats
rcvCalculatedCheckSum += incomingMsg->back();
if(rcvdFlag == flags[flagIndex]){
receive_buffer[msgIndex] = incomingMsg->back();
}
incomingMsg->pop_back();
msgIndex++;
byteCount++;
if (byteCount >= 4){
if(msgIndex < 49){
dispMsgState = DISP_FLOAT_FLAG;
}
else{
dispMsgState = DISP_STRING_FLAG;
}
byteCount = 0;
flagIndex++;
}
}
break;
case DISP_STRING_FLAG:{ // pressure flag
rcvCalculatedCheckSum += incomingMsg->back();
rcvdFlag = incomingMsg->back();
incomingMsg->pop_back();
dispMsgState = DISP_STRING;
}
break;
case DISP_STRING:{ // pressure string
rcvCalculatedCheckSum += incomingMsg->back();
if(rcvdFlag == flags[flagIndex]){
receive_buffer[msgIndex] = incomingMsg->back();
}
incomingMsg->pop_back();
msgIndex++;
byteCount++;
if (byteCount >= 8){
if(msgIndex < 73){
dispMsgState = DISP_STRING_FLAG;
}
else{
dispMsgState = DISP_CHECKSUM;
}
byteCount = 0;
flagIndex++;
}
}
break;
case DISP_CHECKSUM:{ // rcv checksum
if (byteCount == 0){
receive_buffer[msgIndex ] = incomingMsg->back() ;
byteCount ++;
}
else{
receive_buffer[msgIndex ] = incomingMsg->back();
if (rcvCalculatedCheckSum == ((receive_buffer[msgIndex - 1 ] << 8) | receive_buffer[msgIndex ])) {
std::cout<<"FULL MSG CONFIRMED "<<std::endl;
statusByte = receive_buffer[0];
statusByte2 = receive_buffer[1];
userByte = receive_buffer[2];
userByte2 = receive_buffer[3];
notificationByte = receive_buffer[4];
errorByte = receive_buffer[5];
actionByte = receive_buffer[6];
myMessage * msg = new myMessage();
msg->initialise(statusByte,statusByte2,userByte,userByte2,notificationByte,errorByte,actionByte) ;
std::cout<<"made new msg"<<std::endl;
fullMsgReceivedCallback(*msg); //THIS IS WHERE IT CRASHES
std::cout<<"callback returned"<<std::endl;
delete msg;
std::cout<<"msg deleted"<<std::endl;
/* to convert string to float
#include <sstream>
using namespace std;
string s = "1.60000000000000000000000000000000000e+01";
istringstream os(s);
double d;
os >> d;
cout << d << endl;
*/
}
else{
std::cout<<"FULL MSG NOT CONFIRMED "<<std::endl;
std::cout << std::hex << rcvCalculatedCheckSum <<" " << std::hex<< int((receive_buffer[msgIndex - 1 ] ) )<<" "<< std::hex << int(receive_buffer[msgIndex ] )<<std::endl;
}
dispMsgState = DISP_PREAMBLE;
rcvCalculatedCheckSum = 0;
msgIndex = 0;
byteCount = 0;
}
msgIndex++;
incomingMsg->pop_back();
}
break;
}
}
//incomingMsg->insert( incomingMsg->end(), data, data + len );
//for( boost::circular_buffer<char>::const_iterator i = incomingMsg->begin(); i != incomingMsg->end(); ++i)
// std::cout << *i ;
for( int i = 0; i < MESSAGE_DATA_LENGTH + 1; i++){
//std::cout << std::hex<< (uint8_t)*i << ' ' ;
std::cout << std::hex << receive_buffer[i] << ' ';
}
std::cout <<endl;
}
void myInterface::setfullMsgReceivedCallback(boost::function<void(my0Message & msg)> cb){
fullMsgReceivedCallback = cb;
}
void myInterface::clearfullMsgReceivedCallback( ){
fullMsgReceivedCallback = NULL;
}
崩溃发生在“fullMsgReceivedCallback(*msg);”行 在处理接收数据中。我确定我只是错误地绑定了函数或错误地声明了函数指针对象。
谁能看到我哪里出错了?
感谢您的帮助