Russian Qt Forum
Ноябрь 22, 2024, 23:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [Qt embedded] Посоветуйте как работать с COM Портом в Linux  (Прочитано 20060 раз)
footballer
Гость
« : Июнь 25, 2007, 06:56 »

Пишу прогу для некой Embedded железяки.
Железяка на АРМ под Линухом. Управление все делается по Serial.
Вывод графики под QT  вносит существенные задержки
и поэтому в основном MessageLoop невозможно реализовать
некий наш протокол. Софтина работает великолепно под QT Win32
Однако под Линухом выплывают траблы...

Пытаюсь написать обработку входящих
пакетов в асинхронном режиме:
Код:

    saio.sa_handler = signal_handler_IO;
    sigaction(SIGIO,&saio,NULL);
    fcntl(m_fd, F_SETOWN, getpid());    
    fcntl(m_fd, F_SETFL, FASYNC);


signal_handler_IO - позволяет вроде реагировать мгновенно на входящие байтики, однако необходимо использовать mutex-ы
для блокировки ввода вывода. Реализовал блокировки на
pthread_mutex_t  (пробовал и QMutex)

Все блоки которые используются
pthread_mutex_lock  -  pthread_mutex_unlock
сделаны на коротких участках кода
причем в одном scope
(на самом деле я использую конструктор - деструктор нотацию
а-ля CSingleLock )
тем не менее софтина попадает все время в залоченное состояние
(deadlocks).
Облазил сорцы в инете, никто ничего загадочного не делает в этом месте

Вопрос к Linux-QT девелоперам:

1.  Объясните PLS какие ограничения при работе с SIGIO
сигналом? Какие подводные камни?

Могу я считать сигнал просто другой ниткой?
Или это та же нитка что и основная?

2. SIGIO может случаться рекурсивно?
(в принципе я это могу проверить
но хотелось бы сначала теорию).

3.  Какие могут возникнуть проблемы с QT очередью?
  или с графикой (у меня Frame Buffer) при работе с pthread_mutex_t

У кого есть  опыт написания подобных вещей?
Поделитесь PLS!
Записан
Steven_Orko
Гость
« Ответ #1 : Июнь 25, 2007, 09:03 »

Цитата: "footballer"

Могу я считать сигнал просто другой ниткой?
Или это та же нитка что и основная?
2. SIGIO может случаться рекурсивно?
(в принципе я это могу проверить
но хотелось бы сначала теорию).


Нет. Исходя из моих знаний, обработчик сигнала, если таковой имеется,
вызывается в основной нити процесса. Дело в том, что потоки тоже могут получать сигналы, и в них могут быть обработчики.

Не понял, с каким смыслом здесь употребляется слово "рекурсивно". Обработчик сигнала вызывается сразу, как пришел сигнал... При этом может прерваться выполнявшийся до этого обработчик сигнала...
Записан
vaprele07
Гость
« Ответ #2 : Июнь 25, 2007, 10:15 »

http://qextserialport.sourceforge.net/
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Июнь 25, 2007, 10:31 »

Цитата: "vaprele07"


footballer нужен асинхроный режим. Насколько я помню qextserialport работает в синхронном
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Tonal
Гость
« Ответ #4 : Июнь 25, 2007, 10:41 »

А может проще вынести всю работу с портом в отдельный поток, а сним уже налаживать коммуникацию?
Записан
footballer
Гость
« Ответ #5 : Июнь 25, 2007, 11:49 »

Цитата: "Tonal"
А может проще вынести всю работу с портом в отдельный поток, а сним уже налаживать коммуникацию?
Похоже действительно единственный выход.
Просто я надеялся что SIGIO  позволит мне работать в однонитевой модели

Похоже это невозможно.

Просто однонитевость позволяет планировать (хотя это все тоже условно)  что будет происходить в Real Time c задержками. Два
потока мне ничего не гарантируют. И придется уповать на бога.
Ну что ж попробую...
Записан
Tonal
Гость
« Ответ #6 : Июнь 25, 2007, 12:18 »

1) Разве ты не можешь выставить приоритет потока?
2) Т.к. обработчик сигнала выполняется в основной нити, то нет никакой надобности в мутексах. А вот в volatile - есть.
3) Из чего ты заключил, что на сигналах Real Time получиться, а на потоках нет?
Записан
Alex Forth
Гость
« Ответ #7 : Июнь 25, 2007, 13:41 »

Цитата: "footballer"

Просто однонитевость позволяет планировать (хотя это все тоже условно)  что будет происходить в Real Time c задержками. Два
потока мне ничего не гарантируют. И придется уповать на бога.
Ну что ж попробую...

1)Посмотри на политики планирования выполнения процессов/тредов.
2)Если для тебя критично время переключения контекста, то лезь в ядро.
Записан
footballer
Гость
« Ответ #8 : Июнь 26, 2007, 06:53 »

Спасибо всем.
Как все делать в двунитевой модели мне в общем то понятно
и про приоритеты потоков я думал...
Просто внутри сидит некое предубеждение,
что вторая нить приведет к потере общей производительности.
Проц который я применяю уж больно долго выводит на экран.

( Sharp LH79520 со встроенным контроллером LCD ,
я применил LCD 800x480x16 ) В первоначальной модели все построил на событиях основного Message Loop. В Виндах хватило производительности а на
этом кристалле не хватило.

Теперь завожу вторую нить и в ней пытаюсь отработать все протокольные таймауты.

А вот еще вопрос :

Существует вариант чтения по Serial под Линухом, когда read или select
вываливается, если встретился некий терминирующий байт?
Записан
Alex03
Гость
« Ответ #9 : Июнь 28, 2007, 06:06 »

Есть мнение что в линухе нет приоритетов потоков....
Записан
Steven_Orko
Гость
« Ответ #10 : Июнь 28, 2007, 08:46 »

2Alex03
Почитайте Процессы и потоки, а также Потоки (часть 1) и Потоки (часть 2).
Приоритеты есть. Я сам их использовал под МСВС. ))))
Записан
Alex03
Гость
« Ответ #11 : Июнь 29, 2007, 08:53 »

Цитата: "Steven_Orko"


Третья ссылки видимо д.б. такая Потоки (часть 2)?
Ну и где по приведённым ссылкам хоть одно упоминание слова "приоритет" или pthread_attr_setinheritsched()?

Цитировать

Приоритеты есть. Я сам их использовал под МСВС. ))))

Что есть МСВС? Российская военная версия линуха?

То что есть вызовы и т.д. я знаю. Но повторю:
Есть мнение (не моё, сам пока не проверял) что в линухе нет приоритетов потоков....

добавлено спустя 45 минут:

 Попробовал, эксперимент подтверждает мои слова.
Посмотрите на вывод примерчика в линуксе и, например, в винде:
Код:
#include <qthread.h>

class MyThread : public QThread
{
    unsigned int m_tId;
    public:
        MyThread(unsigned int tId, unsigned int stackSize = 0);
        virtual void run();
};

MyThread::MyThread(unsigned int tId, unsigned int stackSize) :
          QThread(stackSize)
{
    m_tId = tId;
}

void MyThread::run()
{
    volatile int n, m;
    for(n = 0; n < 20; n++)
    {
        for(m = 0; m < 100000000; m++)
        {
        }
        qWarning( "Thread %u n=%d", m_tId, n);
    }
}

int main()
{
    MyThread t1(1);
    MyThread t2(2);
    MyThread t3(3);
    MyThread t4(4);
    t1.start(QThread::IdlePriority);
    t2.start(QThread::LowestPriority);
    t3.start(QThread::HighestPriority);
    t4.start(QThread::TimeCriticalPriority);

    t1.wait();
    t2.wait();
    t3.wait();
    t4.wait();
}
Записан
Steven_Orko
Гость
« Ответ #12 : Июнь 29, 2007, 09:31 »

хм... Я тут подправил твой тестик. Результаты не очень. Я в самом начале как-то делал тоже самое, запустит пару раз и все. Подумал, что результаты достоверны ((((

Вот тест:
Код:

#include <unistd.h>
#include <qdatetime.h>
#include <qthread.h>
#include <qmutex.h>
#include <qwaitcondition.h>

class MyThread : public QThread
{
public:
    MyThread(unsigned int tId, unsigned int stackSize = 0);
    virtual void run();
   
    static void runAll();
   
private:
    QTime _tm;
    unsigned int m_tId;
};

QMutex g_mutex;
QWaitCondition g_cond;

 
MyThread::MyThread(unsigned int tId, unsigned int stackSize)
: QThread(stackSize)
{
    m_tId = tId;
}
 
void MyThread::run()
{
   
    g_mutex.lock();
    g_cond.wait(&g_mutex);
    g_mutex.unlock();
   
   
    _tm.start();
    volatile long int n, m, t;
    for(n = 0; n < 20; n++)
    {
t = 0;
        for(m = 0; m < 100000000; m++)
        {
   t += 1;
}
    }
    t = _tm.elapsed();
    qWarning("Elapsed  ID%u - %ld", m_tId, t);
}

void MyThread::runAll()
{
    g_mutex.lock();
    g_cond.wakeAll();
    g_mutex.unlock();
}
 
int main()
{
    MyThread t1(1);
    MyThread t2(2);
    MyThread t3(3);
    MyThread t4(4);
    t1.start(QThread::IdlePriority);
    t2.start(QThread::LowestPriority);
    t3.start(QThread::HighestPriority);
    t4.start(QThread::TimeCriticalPriority);
   
    ::sleep(2);
    MyThread::runAll();
 
    t1.wait();
    t2.wait();
    t3.wait();
    t4.wait();
}  


В Линуксе выводит как попало. Иногда все верно, иногда первый поток первым завершался ((((

Цитировать

Elapsed  ID1 - 13335
Elapsed  ID2 - 14011
Elapsed  ID3 - 14105
Elapsed  ID4 - 14167


Так что... я теперь тоже присоединяюсь ко мнению об отсутствие реализации приоритетов потоков в Линуксе... В МСВС (Мобильная система Вооруженных сил) та же фигня, если хотя бы десяток раз тестик прогнать.
Записан
Alex03
Гость
« Ответ #13 : Июнь 29, 2007, 12:31 »

Мой тест в винде давал такие результаты:
Код:

Thread 4 n=0
Thread 3 n=0
Thread 4 n=1
Thread 3 n=1
Thread 4 n=2
Thread 3 n=2
Thread 4 n=3
Thread 3 n=3
Thread 4 n=4
Thread 3 n=4
Thread 4 n=5
Thread 3 n=5
Thread 4 n=6
Thread 3 n=6
Thread 4 n=7
Thread 3 n=7
Thread 4 n=8
Thread 3 n=8
Thread 4 n=9
Thread 3 n=9
Thread 4 n=10
Thread 3 n=10
Thread 4 n=11
Thread 3 n=11
Thread 4 n=12
Thread 3 n=12
Thread 4 n=13
Thread 3 n=13
Thread 4 n=14
Thread 3 n=14
Thread 4 n=15
Thread 3 n=15
Thread 4 n=16
Thread 3 n=16
Thread 4 n=17
Thread 3 n=17
Thread 4 n=18
Thread 3 n=18
Thread 4 n=19
The thread 'Win32 Thread' (0xa68) has exited with code 0 (0x0).
Thread 3 n=19
The thread 'Win32 Thread' (0xe98) has exited with code 0 (0x0).
Thread 2 n=0
Thread 1 n=0
Thread 2 n=1
Thread 1 n=1
Thread 2 n=2
Thread 1 n=2
Thread 2 n=3
Thread 1 n=3
Thread 2 n=4
Thread 1 n=4
Thread 2 n=5
Thread 1 n=5
Thread 2 n=6
Thread 1 n=6
Thread 2 n=7
Thread 1 n=7
Thread 2 n=8
Thread 1 n=8
Thread 2 n=9
Thread 1 n=9
Thread 2 n=10
Thread 1 n=10
Thread 2 n=11
Thread 1 n=11
Thread 2 n=12
Thread 1 n=12
Thread 2 n=13
Thread 1 n=13
Thread 2 n=14
Thread 1 n=14
Thread 2 n=15
Thread 1 n=15
Thread 2 n=16
Thread 1 n=16
Thread 2 n=17
Thread 1 n=17
Thread 2 n=18
Thread 1 n=18
Thread 2 n=19
The thread 'Win32 Thread' (0x988) has exited with code 0 (0x0).
Thread 1 n=19
The thread 'Win32 Thread' (0xf44) has exited with code 0 (0x0).
The program '[1376] ptest.exe: Native' has exited with code 0 (0x0).


добавлено спустя 26 минут:

 
Цитата: "Steven_Orko"

В Линуксе выводит как попало. Иногда все верно, иногда первый поток первым завершался ((((
Цитировать

Elapsed  ID1 - 13335
Elapsed  ID2 - 14011
Elapsed  ID3 - 14105
Elapsed  ID4 - 14167


Я бы предложил переделать засечку времени на одновременную:
Цитировать

QMutex g_mutex;
QWaitCondition g_cond;
QTime g_tm;

Цитировать

    t = g_tm.elapsed();
    qWarning("Elapsed  ID%u - %ld", m_tId, t);

Цитировать

    ::sleep(2);
    g_tm.start();
    MyThread::runAll();
Записан
vaprele07
Гость
« Ответ #14 : Июнь 29, 2007, 12:41 »

приоритет выставляется POSIX функцией pthread_setschedparam
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.056 секунд. Запросов: 22.