crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Как отследить КЗ на шине CAN
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Litkevich Yuriy Дата 31.12.2018, 11:26
 
Цитата(demon051 @ 29.12.2018, 12:06) *
Но не получается отследить ситуацию КЗ на шине. Т.е. замыкаем, а никаких ошибок и исключений не вылазит...
В CAN-bus короткое замыкание на шине - доминантное состояние, т.е. рабочее состояние. Поэтому класического решения НЕТ.
Надо смотреть на длительность доминантного состояния, подавляющее большинство микросхем "CAN-контроллеров" сами определяют превышение времени доминантного состояния.
Iron Bug Дата 29.12.2018, 12:52
  https://stackoverflow.com/questions/2315703...d-can-low-short

это в идеальном варианте. как будет вести себя конкретный контроллер - это ещё надо проверять.
demon051 Дата 29.12.2018, 10:06
  Всем привет! Всех с НГ.

Вопросик такой.
Есть код обмена по шине 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);
                can_data->error = socketError::socket_create_error;
                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);
                pthread_mutex_lock(&can_data->mutex_lock);
                can_data->error = socketError::socket_setnonblock_error;
                pthread_mutex_unlock(&can_data->mutex_lock);
                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);
                pthread_mutex_lock(&can_data->mutex_lock);
                can_data->error = socketError::socket_bind_error;
                pthread_mutex_unlock(&can_data->mutex_lock);
                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);
                            pthread_mutex_lock(&can_data->mutex_lock);
                            can_data->error = socketError::socket_write_error;
                            pthread_mutex_unlock(&can_data->mutex_lock);
                            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);
                    pthread_mutex_lock(&can_data->mutex_lock);
                    can_data->error = socketError::socket_error;
                    pthread_mutex_unlock(&can_data->mutex_lock);
                    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)) ?
Понятно что можно накрутить проверку что если какое-то колво раз не выбран ни один дескриптор, то это значит, что что-то не в порядке. Но это частная ситуация, когда ты уверен что обмен идет не прерываясь и запросы по кан гуляют постоянно. А если кан тупо простаивает без регулярного обмена, то как отмониторить КЗ?
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 28.3.2024, 21:39