Я использую 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();
}
}
}
Псевдокод устанавливается в atomic int для индекса и субиндекс того, что я хочу, значение, которое я хочу прочитать из микроконтроллера, затем отправьте ему сообщение 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!")
}
Здесь я устанавливаю те же атомарные значения int на 0, когда получено правильное ответное сообщение, и сохраняю данные ответного сообщения
У меня также есть переменные nSentMessages
и nReceivedMessages
, которые содержат количество отправленных и полученных сообщений. В конце я проверяю, совпадают ли эти значения. Обычно мне это не нужно (так как я жду каждого ответа), я добавляю его в качестве дополнительной меры безопасности.
Теперь на проблему:
1) Моя проблема в функции обратного вызова notifyEvent()
, где я предположительно сохраняю данные ответного сообщения в контейнер, но иногда я получаю сообщение «не в контейнере!» из этого заявления if, и я не знаю почему. (Мой контейнер просто установлен нормально set<EDSobject, cmp> container
, он не атомарный или что-то еще, поскольку я знаю, что в него не будут одновременно выполняться чтение / запись из разных потоков.)
2) Если вы проверите мою функцию sendSDO()
, появится строка Sleep(10)
. Программа работает нормально с ним, но если я удаляю его, программа возвращает другое значение для nSentMessages
и nReceivedMessages
- 576 и 575. Это происходит каждый раз, когда я запускаю программу, и я не понимаю, почему.