Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


Форум

Вы не вошли.

 Поиск | Регистрация | Вход 

#27 Техническая поддержка и выбор оборудования » Сборка библиотек для e502 под Эльбрус » 27.04.2017 15:23:02

Valery
Ответов: 10

Добрый день!
Пытаюсь собрать библиотеки для е502 под Эльбрус. СMake прошел без ошибок, а вот при сборке первое с чем столкнулся - вот такое сообщение:

    lcc: ошибка: неизвестная опция "-Wlogical-op"

Подскажите как эту опцию в опциях компилятора убрать.

#28 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 17:04:25

ага, вот теперь понятна где ошибка была - я либо делал частоту больше частоты фрейма, либо меньше... с этим понятно. Теперь мне осталось только определиться с задержкой на достоверность цифровых данных..

#29 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 16:36:53

а ведь точно -поставил частоту строго равной частоте фрейма и цифры стали правильными.. спасибо, буду пытать дальше

#31 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 15:15:00

покрутил частоту X502_SetDinFreq.. чем меньше частота, тем ситуация меняется в сторону данных с АЦП. При 500 Гц получаю

12 11 1
12 11 0
12 11 0
12 11 1
ну так далее.. Но данные (якобы) с АЦП все равно неправильные идут, как случайные.
Если убрать разрешение синхронного ввода, то аналоговые данные в порядке.

#32 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 14:40:30

сделал упрощенный вариант: только чтение 11 аналоговых каналов и 1 цифровой. Получил следующее

12 7 1
12 4 1
12 0 1
...
12 0 1

здесь первая цифра - то что возвращает Recv, вторая - adc_size и последняя - inp_size...
Куда делись данные с АЦП?

#33 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 13:15:51

сейчас приведу все в порядок (это замет немного времени) и сделаю...

#34 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 12:54:10

вот спасибо! Этот вариант заработал. Сразу после

err = X502_StreamsEnable(m_dev, X502_STREAM_ADC);
    if(err < 0)
    {
        qDebug() << QString("error stream enable (%1)").arg(err);
        return;
    }

    err = X502_StreamsStart(m_dev);
    if(err < 0)
    {
        qDebug() << QString("error stream start (%1)").arg(err);
        return;
    }

я вставил

   app->dio_thread->start();
    emit startDio();

и все пошло.. До этого варианта я не додумался, наверное при последовательно старте потоков поток с цифровыми данными стартовал почему-то первым..

Если вы от меня не устали  smile , то может попробуем еще раз вернуться к полностью синхронному? обмену

#35 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 12:03:33

разобрался немного и поправил свои ошибки в варианте раздельных потоков: запускаю последовательно два потока:

1. В первом потоке - синхронное чтение данных с АЦП

    qint32 err = X502_StreamsEnable(m_dev, X502_STREAM_ADC);
    if(err < 0)
    {
        qDebug() << QString("error stream enable (%1)").arg(err);
        return;
    }
    err = X502_StreamsStart(m_dev);
    if(err < 0)
    {
        qDebug() << QString("error stream start (%1)").arg(err);
        return;
    }
    m_bRun = true;
    while(m_bRun)
    {
            qint32 rcv_size = X502_Recv(m_dev, (uint32_t*)buffer, count, 2000);
            if(rcv_size <= 0)
            {
                 qDebug() << QString("error received adc data (%1)").arg(rcv_size);
            }
           quint32 adc_size = rcv_size;
           qint32 err = X502_ProcessAdcData(m_dev, (uint32_t*)buffer, adc_data, (uint32_t*)&adc_size,  X502_PROC_FLAGS_VOLT);
           if(err < 0)
           {
              qDebug() << QString("error processing data (%1)").arg(err);
           }
     }
     app->rza->adcReady();
}

2. второй поток - асинхронное чтение/запись цифровых данных

    while(m_bRun)
    {
        out_buff[0] = address;
        if(m_relays != 0)
        {
            out_buff[0] |= m_relays;
            if(m_startRelay)
            {
                m_startRelay = false;
            }
        }
        out_buff[0] |= 0x4000;

        err = X502_AsyncOutDig(m_dev, out_buff[0], 0);
        if(err < 0)
        {
            qDebug() << QString("error write digital data (%1)").arg(err);
        }

        err = X502_AsyncInDig(m_dev, (uint32_t*)inp_buff);
        if(err < 0)
        {
            qDebug() << QString("error read digital data");
        }

        if(m_relays == 0)
        {
            m_inputs[address++] = inp_buff[0];
            if(address == 6) address = 0;
        }
        else
        {
                m_relays = 0;
                m_status[address] = inp_buff[0];
                address = 0;
            }
        }
    }

Сразу после старта поток 1 (чтение АЦП) выдает ошибку:  "error stream enable (-15)" (Истекло время ожидания освобождения мьютекса). Если я запускаю или 1=й поток или 2-й,  то по отдельности все работает.

А на счет картинок (если я правильно понял тут возникло непонимание?) - то на первой - это нормальный результат: амплитуды стабильны, относительные фазы тоже.
А на второй картинке изображены просто мгновенные значения из серии, в течении времени амплитуды нестабильны ( я бы сказал произвольные), относительные фазы тоже не соответствуют входным. Т.е. вектора входных сигналов произвольно болтаются относительно друг-друга.

Пока оставим это и если можно попытаемся разобраться почему поток с синхронным вводом с АЦП не хочет совмещаться с потоком асинхронного ввода с цифровых входов.

#36 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 10:24:21

вынес асинхронный ввод/вывод цифровых данных в отдельный поток. Данные с АЦП принимаются нормально, но с цифровых входов ничего не читается. Прямо заколдованный круг какой-то. Если в АЦП-шном цикле заменяю чтение с АЦП на чтение цифровых данных - все ок..

#37 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 18.10.2016 09:47:09

вот здесь два снимка экрана: https://cloud.mail.ru/public/GexC/rRb8ANWSN
В обоих случаях на вход АЦП подаю три напряжения и три тока. После приема данных и ДПФ в левой части прорисовываются амплитуды, а в правой - круговые диаграммы амплитуда-фаза. На первом рисунке (2016-10-18 09-27-42) просто сбор данных с АЦП, на втором (2016-10-18 09-29-51) - сбор данных с АЦП и синхронное чтение входного регистра.
В связи с тем что как-то не получается совместить чтение аналоговых и цифровых сигналов не может ли это быть связано с тем, что я использую упрощенную версию Е502 (без микроконтроллера и ЦАП)?

#38 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 17.10.2016 18:50:22

Вернулся к синхронному варианту: чисто синхронный ввод и прием данных с АЦП... что-то вообще начался бардак с АЦП-шными данными.Код примерно такой:

    qint32 rcv_size = X502_Recv(m_dev, (uint32_t*)buffer, count + 1, 2000);
    quint32 adc_size = count;
    quint32 inp_size = 1;
    qint32 err = X502_ProcessData(m_dev, (uint32_t*)buffer, rcv_size, X502_PROC_FLAGS_VOLT, adc_data, (uint32_t*)&adc_size, (uint32_t*)inp_buff, (uint32_t*)&inp_size);

т.е. я хочу принять только слово с цифровых входов.
При инициализации я задаю (дополнительно к параметрам АЦП):

    double fDIO = fAdcFrame;
    X502_SetDinFreq(m_dev, &fDIO);
    X502_StreamsEnable(m_dev, X502_STREAM_DIN);

если это это убрать и убрать добавление 1 к числу каналов АЦП (т.е. вернуться к  приему только данных с АЦП), то все работает нормально.

#39 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 14.10.2016 15:35:09

Все это интересно конечно,  но пока я отвлекся на аналоговые входы. 
И я вот что обнаружил. На АЦП подаю три фазы напряжения, сдвинутые на 0, 120 и 240 градусов. Код основного цикла выглядит так:

   while(m_bRun)
    {
        out_buff[0] = address;
        if(m_relays != 0)
        {
            out_buff[0] |= m_relays;
            if(m_startRelay)
            {
                m_startRelay = false;
                counter = 0;
            }
        }
        out_buff[0] |= 0x4000;

        err = X502_AsyncOutDig(m_dev, out_buff[0], 0);

        rcv_size = X502_Recv(m_dev, (uint32_t*)buffer, count, 2000);
        adc_size = rcv_size;
        err = X502_ProcessAdcData(m_dev, (uint32_t*)buffer, adc_data, (uint32_t*)&adc_size, X502_PROC_FLAGS_VOLT);

        err = X502_AsyncInDig(m_dev, (uint32_t*)inp_buff);
        if(m_relays == 0)
        {
            m_inputs[address++] = inp_buff[0];
            if(address == 6) address = 0;
        }        
        else
        {
            counter++;
            if(counter == 2)
            {
                counter  = 0;
                m_relays = 0;
                m_status[address] = inp_buff[0];
                address = 0;
            }
        }
        app->rza->adcReady();
    }

Теперь изменяю амплитуду или относительную фазу любого напряжения... в данных с АЦП ничего не меняется. Перезапускаю программу - все ок, пошли правильные данные.
Убираю из цикла асинхронный обмен с цифровыми портами:

   while(m_bRun)
    {
        rcv_size = X502_Recv(m_dev, (uint32_t*)buffer, count, 2000);
        adc_size = rcv_size;
        err = X502_ProcessAdcData(m_dev, (uint32_t*)buffer, adc_data, (uint32_t*)&adc_size, X502_PROC_FLAGS_VOLT);
        app->rza->adcReady();
    }

Все встает на свои места, изменения входных напряжений сразу видны в данных с АЦП.
Я опять что не так делаю или такая смесь синхронного и асинхронного вызова недопустима?

#40 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 07.10.2016 19:06:22

именно так - то что вводится зависит от 4-го бита. Если он 0, то читаются статусы с регистров одного типа, если 1 - то на железке выполняются некоторые действия и читаются уже другая статусная информация. Причем в этом случае установка 4-го бита, адреса (3 мл.бита) и содержимое старших битов происходит асинхронно из другого потока и время чтения вообще говоря имеет вторичное значение, поскольку статусная информация появится только через несколько миллисекунд, тогда как в случае нулевого 4-го бита чем быстрее тем лучше.

#41 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 07.10.2016 15:17:15

да, примерно так.. только есть еще один вариант - в адрес может асинхронно по времени добавляться 4 бит, а в  а старшие биты -  некоторая управляющая информация для внешнего оборудования.. Тогда при чтении должен читаться регистр состояний. Т.е. все несколько сложнее простого перебора чтения внешних данных по адресам от 0 до 5.

#42 Re: Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 07.10.2016 13:02:03

Вот спасибо, обновление прошивки помогло для случая асинхронного вывода/ввода - эта странная ошибка исчезла.
Для синхронного варианта вроде помог следующий вариант; добавил счетчик после чтения входных данных типа вот такого:

           counter++;
            if(counter == 20)
            {
                counter = 0;
                m_inputs[address++] = inp_buff[0];
                if(address == 6) address = 0;
            }

т.е. только  на 20-й раз считаю данные действительными при неизменном значении адреса.. но похоже это мало чем будет отличаться по скорости с асинхронным вариантом

#43 Техническая поддержка и выбор оборудования » e502: синхронный ввод/вывод » 07.10.2016 08:57:36

Valery
Ответов: 64

Помогите пожалуйста разобраться с синхронным вводом выводом. Вот такой код

void QAdcObject::init()
{
    RzaApplication* app = (RzaApplication*)qApp;
    char serial[2][X502_SERIAL_SIZE];
    qint32 err, devs;

    if(m_dev != 0)
    {
        m_bRun = false;
        X502_Close(m_dev);
        X502_Free(m_dev);
    }

    err = E502_UsbGetSerialList(serial, 2, X502_GETDEVS_FLAGS_ONLY_NOT_OPENED, (uint32_t*)&devs);
    if(devs == 0)
    {
        qDebug() << "no device found";
        return;
    }
    m_dev = X502_Create();
    err = E502_OpenUsb(m_dev, serial[0]);
    if(err != 0)
    {
        qDebug() << "open e502 failed";
        X502_Free(m_dev);
        m_dev = 0;
        return;
    }

    X502_SetMode(m_dev, X502_MODE_FPGA);
    err = X502_SetLChannelCount(m_dev, app->m_channel.count());
    for(int i = 0; i < app->m_channel.count(); i++)
    {
        err = X502_SetLChannel(m_dev, i, i, X502_LCH_MODE_COMM, X502_ADC_RANGE_10, 1);
    }

    X502_SetSyncMode(m_dev, X502_SYNC_INTERNAL);
    X502_SetSyncStartMode(m_dev, X502_SYNC_INTERNAL);

    double fAcq = 2000000.0, fAdcFrame = 50.0 * (double)app->m_pnts;
    err = X502_SetAdcFreq(m_dev, &fAcq, &fAdcFrame);

    X502_StreamsEnable(m_dev, X502_STREAM_ADC);

    X502_SetDinFreq(m_dev, &fAdcFrame);
    X502_StreamsEnable(m_dev, X502_STREAM_DIN);

    X502_SetOutFreq(m_dev, &fAdcFrame);
    X502_StreamsEnable(m_dev, X502_STREAM_DOUT);

    err = X502_Configure(m_dev, 0);

    memset(m_inputs, 0, sizeof(quint16) * 6);
}

void QAdcObject::startAdc()
{
    RzaApplication* app = (RzaApplication*)qApp;
    qint32 buffer[256];
    qint32 rcv_size, adc_size, inp_size, err;

    X502_PreloadStart(m_dev);
    out_buff[0] = 0;
    err = X502_PrepareData(m_dev, 0, 0, (uint32_t*)out_buff, 1, 0x0, (uint32_t*)buffer);
    err = X502_Send(m_dev, (uint32_t*)buffer, 1, 2000);
    X502_StreamsStart(m_dev);

    m_bRun = true;
    int count = app->m_channel.count();

    address  = 0;
    m_relays = 0;

    int counter = 0;
    while(m_bRun)
    {
        rcv_size    = count;
        out_buff[0] = address;
        err = X502_PrepareData(m_dev, 0, 0, (uint32_t*)out_buff, 1, 0x0, (uint32_t*)buffer);
        err = X502_Send(m_dev, (uint32_t*)buffer, 1, 2000);

        rcv_size = X502_Recv(m_dev, (uint32_t*)buffer, count + 1, 2000);

        adc_size = count;
        inp_size = 1;
        err = X502_ProcessData(m_dev, (uint32_t*)buffer, rcv_size, X502_PROC_FLAGS_VOLT, adc_data, (uint32_t*)&adc_size,
                                                                              (uint32_t*)inp_buff, (uint32_t*)&inp_size);

        m_inputs[address++] = inp_buff[0];
        if(address == 6) address = 0;
        }
    }
    X502_StreamsStop(m_dev);
}

ОС - Линукс, частота АЦП (на канал) 2 МГц, сбора кадра - 4 кГц, число каналов АЦП - 11.
Кроме сбора аналоговых данных от этой функции необходимо еще чтение 16 разрядов с цифровых входов по адресу некоторого внешнего регистра, указанному в out_buff[0] (3 мл.бита от 0 до 6).. Для простоты текста я не привожу вывода сообщений об ошибках потому что в этом варианте их нет.

А вот и не получается. Такое ощущение, что синхронная запись не выполняется, для всех значений  в out_buff[0] читается одно и тоже значение в inp_buff[0].
Если все тоже самое сделать (запись/чтение цифровых данных) в асинхронном режиме, то все работает (конечно при соответствующих изменениях в функции инициализации). Но этот вариант слишком медленный для моей задачи.

Да, кстати, еще замечание: при асинхронной записи функция
X502_AsyncOutDig(m_dev, out_buff[0], 0)
возвращает ошибку с кодом 1004. В списке кодов ошибок такого кода нет, но тем не менее в асинхронном режиме запись работает.

Если необходимо могу выложить код асинхронного варианта.

#44 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 24.06.2016 08:09:55

Ну вот и все, ура! Проработало почти 3-е суток, сбоев нет. Поздравляю, баг исправлен, тему можно закрывать. По мере переноса е502 на другие платформы буду вас извещать.

#45 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 21.06.2016 20:03:48

Эльбрус у нас конечно есть и планируются еще приобретения, есть удаленный доступ к машине с Эльбрусом. так что тут все ок. Avahi  - это да, это нам не нужно.

Новая прошивка проработала день без проблем, посмотрим что будет утром.

#46 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 21.06.2016 16:26:40

На Эльбрусе стоит Линукс их (МЦСТ) сборки, последняя версия ядра, которую они выпускают - 3.14. Насколько я знаю они его делали для ВПК, так что ручками в ядре как-то ковырялись на предмет защиты, закладок и прочего.
Есть Qt4 (на ней все работает), я пытался собрать ту же апликуху на их сборке Qt5 - почему-то работать не захотела.. GUI у них - на XFCE4. libusb  - в наличии. Я сделал одну попытку собрать e502 под Эльбрус из исходников, уже не помню почему, но не получилось, типа каких-то пакетов не хватило.. так что к этом вопросу вскоре вернусь.. для нас это один из важных вопросов на сегодня. Если удастся раздобыть плату с Байкалом - то на нее тоже будем софт переносить

#47 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 21.06.2016 08:40:33

Все установил как описано и запустил тестирование.. теперь это надолго  smile . в РОСЕ6 не смог установить lboot - почему-то не находит библиотеку libmodbus.so.5: в пакетах ее почему-то нет, ручками поставил ее из github и собрал - не помогло..
пришлось все проделать в Mint- все встало легко и быстро.
Вообще (просто для информации) хочу сказать - мы благодарны вам за оперативную поддержку и рассчитываем на ваши девайсы, в разработке у нас терминалы защиты, где основным элементов внешнего интерфейса ставим Е502. Причем в качестве рабочих станций используем как машинки Интел/АМД так и Эльбрус.. Это кстати возможно отдельная будет тема - перенос пакетов e502/x502  на Эльбрус.

#48 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 17.06.2016 11:31:41

Ну да, иногда эта пара вызовов не помогает и все сбивается в непрерывную череду ошибок.. но все равно факт: на USB 3.0 200 кГц работало всю ночь, а 2 кГц все еще работает без ошибок (уже больше 3-х часов). Возможно стек немного другой...
Для чистоты эксперимента возвращаю обмен на USB 2.0.

#49 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 17.06.2016 09:23:03

вот, все интереснее и интереснее.. Посмотрел на datasheet микроконтроллера, там USB 2.0, а я оказывается вчера подключил в USB-3.0 и все, ошибки похоже исчезли. Сейчас еще подожду (на 2 кГц) немного и верну подключение на USB 2.0..

#50 Re: Техническая поддержка и выбор оборудования » e502 - ошибка X502_ProcessAdcData » 17.06.2016 08:04:42

и еще такой вопрос: когда возникает ошибка обработки было бы неплохо как бы перезапустить синхронный сбор. Я использовал вариант

Х502_streamStop();
X502_StreamStart();

не очень красиво, но как правило помогало восстановить синхронный сбор данных (хотя очевидно и с потерями). А что нет другого пути ре-инициализировать синхронный сбор?

Контакты

Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4

Многоканальный телефон: +7 (495) 785-95-25

Письма и запросы: lcard@lcard.ru
Отдел продаж: sale@lcard.ru
Мы работаем с юридическими и физическими лицами, пожалуйста, прикладывайте реквизиты при оформлении заказа
Техническая поддержка: support@lcard.ru

Время работы: с 9-00 до 19-00 мск