Exemplo n.º 1
0
        /// <summary>
        /// Открывает драйвер порта
        /// </summary>
        /// <exception cref="InvalidOperationException"></exception>
        public override void Open()
        {
            String         msg;
            F_CAN_RESULT   result;
            F_CAN_SETTINGS settings;

            settings = new F_CAN_SETTINGS();
            settings.acceptance_code = 0;
            settings.acceptance_mask = 0;
            settings.baud_rate       = ConvertNim351.ConvertToF_CAN_BAUDRATE(this.BitRate);
            //settings.error_mask = CAN_OPMODE_ERRFRAME.CAN_ERR_CRTL | CAN_OPMODE_ERRFRAME.CAN_ERR_BUSOFF ;
            settings.error_mask = 0xFFFF;

            settings.opmode = (UInt16)Api.OpModeBuilder(this.Mode, this.FrameFormat, this.ErrorFrameEnable);

            // Инициализация библиотеки
            result = Api.fw_can_init();
            if (!Api.f_can_success(result))
            {
                msg = String.Format("Ошибка при иницилизации fwcan.dll, Error: {0}", result);
                throw new InvalidOperationException(msg);
            }

            // Открываем адаптер CAN и получаем дескриптор порта
            result = Api.fw_can_open(Api.GetPortNumber(this.PortName), out this._DeviceHandle);
            if (!Api.f_can_success(result))
            {
                msg = String.Format("Ошибка при открытии CAN адаптера, Error: {0}", result);
                throw new InvalidOperationException(msg);
            }

            // Конфигурируем контроллер
            result = Api.fw_can_set_controller_config(_DeviceHandle, ref settings);
            if (!Api.f_can_success(result))
            {
                msg = String.Format("Ошибка при записи настроек в контроллер. Error: {0}", result);
                throw new InvalidOperationException(msg);
            }

            // Конфигурируем таймауты
            result = Api.fw_can_set_timeouts(_DeviceHandle, ref _Timeouts);
            if (!Api.f_can_success(result))
            {
                msg = String.Format("Ошибка при установке таймаутов. Error: {0}", result);
                throw new InvalidOperationException(msg);
            }

            // Обновляем и проверяем статус порта
            if (!this.UpdatePortStatus())
            {
                msg = String.Format("Ошибка. При открытии порта его статус остался неизменным: {0}",
                                    this.PortStatus);
                throw new Exception(msg);
            }

            return;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Читает текущий статус адаптера и сравнивает с предыдущим. Если
        /// отличается генерирует событие и сохраняет новый статус
        /// </summary>
        /// <returns>true - если статус изменился</returns>
        private Boolean UpdatePortStatus()
        {
            F_CAN_STATE newStatus;
            Boolean     result;

            if (this.IsOpen)
            {
                newStatus = this.GetPortStatus();

                if (this._PortStatus != newStatus)
                {
                    // Статус изменился.
                    this._PortStatus = newStatus;
                    this.OnPortChangesStatus(ConvertNim351.ConvertToCanPortStatus(this._PortStatus));
                    result = true;
                }
                else
                {
                    result = false;
                }
            }
            else
            {
                // Если порт закрыт, есго статус должен быть F_CAN_STATE.CAN_STATE_STOPPED.
                // Если это не так, то устанавливаем и генерируем событие
                if (this._PortStatus == F_CAN_STATE.CAN_STATE_STOPPED)
                {
                    result = false;
                }
                else
                {
                    // Статус изменился.
                    this._PortStatus = F_CAN_STATE.CAN_STATE_STOPPED;
                    this.OnPortChangesStatus(ConvertNim351.ConvertToCanPortStatus(this._PortStatus));
                    result = true;
                }
            }

            return(result);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Записывает сообщение в порт
        /// </summary>
        /// <param name="message">Сообщение для оправки</param>
        public override void Write(Frame message)
        {
            String       msg;
            F_CAN_RESULT result;
            F_CAN_TX     buffer;
            F_CAN_STATE  status;
            uint         count = 0;

            // Если прот закрыт, отсылка сообщения не возможна
            if (!this.IsOpen)
            {
                msg = "Невозможно отправить сообщение, CAN-порт закрыт";
                throw new InvalidOperationException(msg);
            }

            status = this.GetPortStatus();
            if (this.PortStatus != CanPortStatus.IsActive)
            {
                msg = "Невозможно отправить сообщение, CAN-порт отключён от физической сети";
                throw new InvalidOperationException(msg);
            }

            // Разбираем сообщение и подготавливаем его для отправки
            buffer.msg = ConvertNim351.ConvertToF_CAN_MSG(message);

            result = Api.fw_can_send(this._DeviceHandle, ref buffer, 1, ref count);
            //result = Api.fw_can_post_message(this._DeviceHandle, ref buffer);

            if (!Api.f_can_success(result))
            {
                // При отправке сообщения возникла ошибка
                msg = String.Format("Не удалось отправить сообщение. Error: ", result);
                throw new InvalidOperationException(msg);
            }
            return;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Метод для чтения порта. Запускается во вторичном потоке. Поток на чтение запускается при открытии порта
        /// и завершается при закрытии.
        /// </summary>
        private void HandleQueueIncomingMessages()
        {
            String       msg;
            F_CAN_RESULT result;
            F_CAN_RX     buffer;
            F_CAN_WAIT   wait;
            UInt32       timeout = 500; // мсек
            Frame        message;

            //uint count;

            // Если прот закрыт, чтение его буфера не возможно
            //if (this.IsOpen == false)
            //{
            //    msg = "Невозможно прочитать очередь сообщений, CAN-порт закрыт";
            //    throw new InvalidOperationException(msg);
            //}

            // Читаем порт всё время пока открыт
            while (this._FlagMustQuit > 0)
            {
                wait.waitMask = F_CAN_STATUS.CAN_STATUS_EMPTY | F_CAN_STATUS.CAN_STATUS_TXBUF;
                wait.status   = F_CAN_STATUS.CAN_STATUS_EMPTY;

                result = Api.fw_can_wait(this._DeviceHandle, ref wait, timeout);

                if ((result == F_CAN_RESULT.CAN_RES_OK) ||
                    (result == F_CAN_RESULT.CAN_RES_TIMEOUT))
                {
                    if (result == F_CAN_RESULT.CAN_RES_TIMEOUT)
                    {
                        //Console.WriteLine("Сработал таймаут ожидания");
                        // Произошло что-то нехорошее, нужно анализировать и что-то делать
                        // Проверяем текущий статус
                        //if (wait.status == wait.waitMask)
                        //{ }
                        // Останавливаем порт
                        this.Stop();
                        // Генерируем событие
                        OnErrorReceived(ERROR.Other);
                        // Закрываем порт
                        this.Close();
                        // Завершаем работу потока
                        Interlocked.Exchange(ref this._FlagMustQuit, 0);
                        continue;
                    }

                    // Если  флаг установлен, то есть принятые сообщения. Читаем их
                    // и помещаем в буфер исходящих сообщений
                    if (F_CAN_STATUS.CAN_STATUS_RXBUF ==
                        (wait.status & F_CAN_STATUS.CAN_STATUS_RXBUF))
                    {
                        // Читаем буфер адаптера
                        result = Api.fw_can_peek_message(_DeviceHandle, out buffer);
                        // Разбираем принятое сообщение и формируем событие
                        message = new Frame();
                        message = ConvertNim351.ConvertToFrame(buffer.msg);
                        // Помещает принятое сообщение в буфер входных сообщений и генерируем событие приёма
                        lock (_SyncRoot)
                        {
                            this._InputBufferMessages.Enqueue(message);
                        }
                        this.OnMessageReceived();
                    }

                    // Произошла ошибка читаем её и сбрасываем
                    if (F_CAN_STATUS.CAN_STATUS_ERR ==
                        (wait.status & F_CAN_STATUS.CAN_STATUS_ERR))
                    {
                        F_CAN_ERRORS errors;
                        result = Api.fw_can_get_clear_errors(this._DeviceHandle, out errors);

                        if (Api.f_can_success(result))
                        {
                            // Анализируем счётчики и генерируем событие
                            this.OnErrorReceived(ERROR.Other);
                        }
                        else
                        {
                            msg = String.Format(
                                "При чтении и сбросе счётчика ошибок CAN-адаптера возникла ошибка: {0}", result);
                            throw new InvalidOperationException(msg);
                        }
                    }
                }
                else
                {
                    msg = String.Format("При выполнении функции fw_can_wait произошла ошибка: {0}",
                                        Enum.GetName(typeof(F_CAN_RESULT), result));
                    throw new InvalidOperationException(msg);
                }
            }
            return;
        }