我正在将CodeBlocks
与MinGW编译器和wxWidgets库一起使用。
我正在编写一个程序,该程序通过发送消息(使用索引和子索引)并获取带有所述数据的响应消息来从微控制器读取一些数据。
我的计划是一一发送消息,然后使用__atomic int variables__
等待响应消息,以检查何时收到响应消息。
这是我发送消息的功能:
typedef std::chrono::high_resolution_clock Clock;
void sendSDO(int index, int subindex)
{
int nSent = 0;
atomic_index.store(index);
atomic_subindex.store(subindex);
canOpenClient->SDORead(index, subindex);
auto start = Clock::now();
nSentMessages++;
nSent++;
Sleep(10);
while ((atomic_index.load() != 0) && (atomic_subindex.load() != 0))
{
auto t = chrono::duration_cast<chrono::milliseconds>(Clock::now() - start);
if(t.count() > 20)
{
if (nSent > 5)
{
MainFrame->printTxt("[LOG] response not received\n");
return;
}
atomic_index.store(index);
atomic_subindex.store(subindex);
canOpenClient->SDORead(index, subindex);
nSentMessages++;
nSent++;
start = Clock::now();
}
}
}
将伪代码设置为原子整数,以其要从微控制器读取的所需值的索引和子索引,然后向其发送消息SDORead()
,如果在20毫秒内未收到响应,请再次发送该消息,最多5次。
对于接收消息,我有一个带有回调函数的__separate thread__
,当我从控制器收到响应消息时会调用该函数:
void notifyEvent(unsigned char ev_type)
{
SDO_msg_t msg;
msg = canOpenClient->Cmd_CustomMessageGet(); //get response message
if(ev_type == CO_EVENT_SDO_READ)
{
if ((msg.index == atomic_index.load()) && (msg.subindex == atomic_subindex.load()))
{
//does stuff, like saves message data to set container
atomic_index.store(0);
atomic_subindex.store(0);
}
}
if (message data not in container)
printf("not in container!")
}
这里,当收到正确的响应消息时,将相同的atomic int值设置为0,并保存响应消息数据
我还有变量nSentMessages
和nReceivedMessages
,它们保存已发送消息和已接收消息的数量。最后,我检查这些值是否相同。通常,我不需要(因为我等待每个响应),所以我把它放在那里是一种额外的安全措施。
现在解决问题:
1)我的问题出在回调函数notifyEvent()
中,我大概在其中将响应消息数据保存到容器中,但是有时我仍然会“不在容器中!”从那if语句,我不知道为什么。 (我的容器只是普通集set<EDSobject, cmp> container
,它不是原子的,也不是任何东西,因为我知道不会同时从不同的线程对其进行读/写。)
2)如果您检查我的功能sendSDO()
,则一行Sleep(10)
。该程序可以正常运行,但是如果删除它,则该程序将为nSentMessages
和nReceivedMessages
返回一个不同的值-576和575。每次我运行该程序时都会发生这种情况,但我不理解为什么。