Всем привет! Всех с НГ.
Вопросик такой.
Есть код обмена по шине CAN.
while(!stop)
{
try
{
if(ss[0]!=-1)
{
try
{
close(ss[0]);
}
catch(...){}
ss[0] = -1;
}
if(pthread_mutex_trylock(&can_data->mutex_lock)==0)
{
stop = can_data->stopThread;
pthread_mutex_unlock(&can_data->mutex_lock);
if(stop)
break;
}
if((ss[0] = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->onCanStart(socketError::socket_create_error);
nanosleep(&sp, NULL);
continue;
}
if(fcntl(ss[0], F_SETFL, SOCK_NONBLOCK)<0)
{
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->onCanStart(socketError::socket_setnonblock_error);
nanosleep(&sp, NULL);
continue;
}
strcpy(ifr.ifr_name, can_data->name.data());
ioctl(ss[0], SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(ss[0], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->onCanStart(socketError::socket_bind_error);
nanosleep(&sp, NULL);
continue;
}
}
catch(...)
{
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->canOperationError(socketError::socket_unknown_error);
continue;
}
if(can_data->eventHandler!=0)
can_data->eventHandler->onCanStart();
while(!stop)
{
try
{
if(pthread_mutex_trylock(&can_data->mutex_lock)==0)
{
stop = can_data->stopThread;
pthread_mutex_unlock(&can_data->mutex_lock);
if(stop)
break;
}
FD_ZERO(&read_fs);
FD_SET(ss[0], &read_fs);
FD_ZERO(&write_fs);
FD_SET(ss[0], &write_fs);
FD_ZERO(&error_fs);
FD_SET(ss[0], &error_fs);
if ((ret = select(ss[0]+1, &read_fs, &write_fs, &error_fs, &timeout_config)) <= 0)
{
continue;
}
if (FD_ISSET(ss[0], &read_fs))//проверяем дескриптор на готовность к чтению
{
frame_read = new can_frame;
frame_read->can_id = 0;
frame_read->can_dlc = 0;
auto numBytes = read(ss[0], frame_read, CAN_MTU);
if(numBytes>0)
{
if(can_data->eventHandler!=0)
can_data->eventHandler->newCanFrame(frame_read);
continue;
}
}
if (!can_data->queueIn.isEmpty() && FD_ISSET(ss[0], &write_fs))//проверяем дескриптор на готовность к записи
{
frame_write = can_data->queueIn.dequeue();
if(frame_write != 0)
{
auto numBytes = sendto(ss[0], frame_write, sizeof(struct can_frame),
0, (struct sockaddr*)&addr, sizeof(addr));
delete frame_write;
frame_write = 0;
if(numBytes == 0)
{
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->canOperationError(socketError::socket_write_error);
break;
}
else
{
generateSignal(signoCan1GreenPulse);
continue;
}
}
}
if (FD_ISSET(ss[0], &error_fs))//проверяем дескриптор на наличие ошибок
{
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->canOperationError(socketError::socket_error);
break;
}
}
catch(...)
{
generateSignal(signoCan1Red);
if(can_data->eventHandler!=0)
can_data->eventHandler->canOperationError(socketError::socket_unknown_error);
break;
}
}
if(ss[0]!=-1)
{
try
{
close(ss[0]);
}
catch(...){generateSignal(signoCan1Red);}
ss[0] = -1;
}
}
Всё это работает.
Но не получается отследить ситуацию КЗ на шине. Т.е. замыкаем, а никаких ошибок и исключений не вылазит...
Выскочить из внутреннего цикла во внешний не получается.
Кто-нить знает, должна ли вылезать ошибка в if (FD_ISSET(ss[0], &error_fs)) ?
Понятно что можно накрутить проверку что если какое-то колво раз не выбран ни один дескриптор, то это значит, что что-то не в порядке. Но это частная ситуация, когда ты уверен что обмен идет не прерываясь и запросы по кан гуляют постоянно. А если кан тупо простаивает без регулярного обмена, то как отмониторить КЗ?