Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ещё раз о ком-порте, или как с ним работать. 
:(
    Опции темы
takedo
Дата 12.12.2006, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: -1
Всего: 3



UniBomb, по поводу моих советов: объяснять долго, посмотри чего мы тут обсуждали. Меня никто не переубедил, сейчас я отказался таки от асинхронной работы - создал свою очередь RX и сделал все это в потоке!
http://forum.vingrad.ru/topic-64813/hl/com/index.html
http://forum.vingrad.ru/topic-63763/hl/com/index.html
там много лишнего, но может поймёшь, что при работе в асинхронном режиме может возникнуть непреодолимые (так как микрософт не засинхронизировал событие "пришел символ" и длину очереди) заковыки.

Я по поводу извинений - так не обиделся smile Я тоже про ком порт ждал ответов месяц! И не только здесь.

Добавлено @ 15:34 
UniBomb,
Цитата
 я не умею работать с потоками.... я ничего о них не знаю... 
 - надо Федя, надо. Иначе ничего путного под виндовс не напишеь, к сожалению smile

Добавлено @ 15:35 
Про Федю то не обижайся - я к слову  smile 


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
UniBomb
Дата 12.12.2006, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 97



serge_mok, 

Цитата

а по поводу иниц , я ж говорю, на СИ перешёл, там встроенный билдер периферии - иниц автоматич делается, только нужно крыжиком не ошибиться 


А что за компилятор? Я вот всё тоже хочу на Си перейти, но как то руки не доходят... И кстати вопрос не по теме - как там обстоят дела с числами с плавающей точкой? Просто на асме математические функции с такими числами получаются уж дюже грамозкими...

Цитата

а ты наверно немецкий учил, или мне показалось? 


С чего ты взял? Если чесно, то я никакого языка не учил (ещё со школы так сложилось, что преподы мне попадаются сплошь халявщики). Правда какое-то время занимался на доп.занятиях Английского...


takedo

Чтож, посмотрю, покумекаю... Может оно действительно лучше...

Цитата

так как микрософт не засинхронизировал событие "пришел символ" и длину очереди


Это как раз есть... Посмотри в моём коде функцию Receive_Data(); - это по поводу длины очереди, а поп поводу пришёл символ - WaitEvent кажися...



Это сообщение отредактировал(а) UniBomb - 12.12.2006, 16:24
PM MAIL ICQ Skype   Вверх
serge_mok
Дата 13.12.2006, 05:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 6.12.2006

Репутация: нет
Всего: нет



У меня тоже руки не доходили...всё думал, вот дождусь первой звездыsmile, да и в голове плохо укладывалось, как на СИ например прерыв организовать...а потом просто сел, да перешёл на СИ..

Мне что под руку попало тем и занимаюсь, а именно Image Craft 6.3. Прошиваю из под него же(но ему для этого обязательно нужен AvrStudio). С плавающей всё работает с полпинка...но занимает ВОТ СТОЛЬКО... . Например применение  sin/cos/операции с плав точкой, - это займёт  добрых 60-70 % памяти для например ATmega8... 
но зато: 
структурированные данные(с классами ещё не пробовал), 
удобство условных оперций ( if/ else), 
организация циклов,
ну и вообще более логичная логика работы smile

кстати, многопоточное прогр - мне это тоже предстоит.. smile..

PM MAIL   Вверх
UniBomb
Дата 13.12.2006, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 97



takedo, 

Слушай, если не жалко, то выложи рабочий кусок кода с созданием нового потока, организации циклического чтения в потоке ну и т.д. Короче кусок, который я смогу вставить в свой проект, что бы всё заработало...  smile 
PM MAIL ICQ Skype   Вверх
serge_mok
Дата 14.12.2006, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 6.12.2006

Репутация: нет
Всего: нет



промежуточня стадия между одно-  и многопоточ :
Цитата

 Речь идет о "тревожном вводе-выводе". Эта возможность реализуется функциями ReadFileEx, WriteFileEx и SleepEx. Суть использования данных функий такова. Вы вызываете расширенную функцию записи или чтения, которая имеет еще один параметр - адрес функции завершения. После чего, вызвав расширенную функцию засыпания, освобождаете процессор. После завершения ввода/вывода Ваша функция завершения будет вызвана системой. Причем вызвана ТОЛЬКО в том случае, если ваша программа вызвала SleepEx. Нетрудно заметить, что данный вариант работы подходит для систем с большим количеством портов и работающих в режиме ответа по требованию. Например, сервер с мультипортовым контроллером последовательного порта, к которому подключены модемы. 



...таки посмотрел твой код...нууу...тогда уж не дожидаясь никаких событий, раз в 2-3 мс читать предыд посылку buf_in, вызывать подряд WriteFile(..buf_out...&ovr),ReadFile(..buf_in...&ovr). тут же проверять успешный старт для передачи, и кол. реально принятых байт для приёма(+ ошибки предыд приёма) и сразу выходить ...приём/передача пусть сами собой работают( в асинх режиме), останавливаются по таймауту, выдают ошибки и тд., через 2 мс, сам зайдёшь и всё увидишь... .Это конечно не спортивно, по крайней мере тормозов не должно быть...

Добавлено @ 10:49 
...и то и другое не пробовал, - это мысли вслух...так что сразу по голове не пинайте smile
PM MAIL   Вверх
UniBomb
Дата 14.12.2006, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 97



serge_mok, 

Надо будет посмотреть крафт..... Руки не доходили до него потому, что все проекты (которые были до меня) написаны на асме и соответсвенно надо всё с нуля делать...

Цитата

..таки посмотрел твой код...нууу...тогда уж не дожидаясь никаких событий, раз в 2-3 мс читать предыд посылку buf_in, вызывать подряд WriteFile(..buf_out...&ovr),ReadFile(..buf_in...&ovr). тут же проверять успешный старт для передачи, и кол. реально принятых байт для приёма(+ ошибки предыд приёма) и сразу выходить ...приём/передача пусть сами собой работают( в асинх режиме), останавливаются по таймауту, выдают ошибки и тд., через 2 мс, сам зайдёшь и всё увидишь... .Это конечно не спортивно, по крайней мере тормозов не должно быть...


брр... Мне нужно время что бы это всё дело переварить...

Цитата

 ReadFileEx, WriteFileEx и SleepEx


Кстати то же вариант... Эти функции были разработаны специально для работы с файлами в асинхронном режиме...
PM MAIL ICQ Skype   Вверх
UniBomb
Дата 24.2.2007, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 97



up

И всё таки непонятно... Если всё делать в два потока - в одном только передача данных, в другом только приём, то что именно писать во втором потоке? Сработает ли такой кусок:

Код

up:
 lasterr = ReadFile(port,&rdata,rdata_count,&bc,&OL);
 if ((rdata_count == 0) && (GetLastError() == ERROR_IO_PENDING))
  {
   goto up;
  }

?

В смысле всё время смотреть гетластеррором нет ли еррор_ои_пендинг и если нет, то читать файл... Все кто делал подобные программы в два потока - отзовитесь!!!
PM MAIL ICQ Skype   Вверх
Vsts
Дата 28.2.2007, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.1.2007

Репутация: 1
Всего: 1



попробуй так
Код

#include <windows.h>
#include <stdio.h>
#include <conio.h>

#define  BUFF_READ_SIZE 1024

HANDLE hCom=NULL;
HANDLE phandle=NULL;

int counter=0;

bool  openComPort(int argc, char *argv[]);

inline 
void ClearCommPort()
{
    if(!PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
    {
        //logError("PurgeComm error\n");
    }
    FlushFileBuffers(hCom);
}


DWORD WINAPI ComReadDate(LPOVERLAPPED rOverlapped) 
{
    DWORD ErrorMask = 0; 
    COMSTAT CStat;

    ClearCommError(hCom, &ErrorMask, &CStat);

    DWORD quelen = CStat.cbInQue;

    BYTE data[BUFF_READ_SIZE + 1];

    if(quelen>sizeof(data))
    {
        //logError("Error: buffer overflow\n");
        ClearCommPort();
        return -1;
    }

    DWORD readed=0;

    static bool purge_com = false;

    if(!purge_com)
    {
        purge_com = true;
        ClearCommPort();
    }
    
    if ( ReadFile(hCom,data,quelen,&readed,rOverlapped) == 0 ) 
    {
        if ( GetLastError() == ERROR_IO_PENDING ) 
        {
            // если ничего не прочитано и GetLastError() возвратила ERROR_IO_PENDING
            // операция не успела за установленный в COMMTIMEOUTS
            // период времени выполниться и выполняется в фоне, 
            if ( GetOverlappedResult(hCom, rOverlapped,&readed, TRUE) == 0 )
            {
                goto end;
            }
        } 
        else if ( GetLastError() == ERROR_HANDLE_EOF )
        {
            goto end; 
        }
        else 
        {
            CloseHandle(rOverlapped->hEvent);
            return(-1);
        }    
    }
    end:
        ResetEvent(rOverlapped->hEvent);
        CloseHandle(rOverlapped->hEvent);
    data[readed] =0; 

    printf("ComReadDate  :: \"%s\"\n",data);

    return readed;
}

DWORD writeComData(HANDLE fh, void *buf, size_t nbyte, DWORD offset =0)
{
    DWORD       NumberOfBytesWrite;
    OVERLAPPED  Overlapped;
    ZeroMemory (&Overlapped, sizeof(OVERLAPPED));

    Overlapped.Offset     = offset;
    Overlapped.OffsetHigh = 0;
    Overlapped.hEvent     = CreateEvent(NULL,TRUE,FALSE,NULL);//NULL;

    if(!Overlapped.hEvent)
    {
        //logError("writeComData error :: CreateEvent error\n");
        return (-1);
    }   
    if ( WriteFile((HANDLE)fh, buf, (DWORD)nbyte,&NumberOfBytesWrite, &Overlapped) == 0 ) 
    {
        if ( GetLastError() == ERROR_IO_PENDING ) 
        {
            if ( GetOverlappedResult(fh, &Overlapped,&NumberOfBytesWrite, TRUE) == 0 )
            {
                CloseHandle(Overlapped.hEvent);
                //logError("writeComData error:: %d",GetLastError());
                return(-1); 
            }
        } 
        else    
        {
            CloseHandle(Overlapped.hEvent);
            //logError("writeComData error:: %d",GetLastError());
            return(-1);
        }
    }
    ResetEvent(Overlapped.hEvent);
    CloseHandle(Overlapped.hEvent);
    return(NumberOfBytesWrite);
}

DWORD WINAPI ComProcess(LPVOID lpNoData)
{
    //logDebug("\n\n\nComProcess start\n");
    printf("\n\n\nComProcess start\n");

    OVERLAPPED Overlapped;

    ZeroMemory(&Overlapped,sizeof(Overlapped));
    Overlapped.OffsetHigh = 0;
    Overlapped.hEvent     = CreateEvent(NULL,TRUE,FALSE,NULL);

    if(!Overlapped.hEvent)
    {
        //logError("writeComData error :: CreateEvent error\n");
        return (-1);
    }   

    for(DWORD EventMask(0);;EventMask=0)
    {
        if(!WaitCommEvent(hCom, &EventMask,&Overlapped) && GetLastError()==ERROR_IO_PENDING)
        {
            WaitForSingleObject(Overlapped.hEvent,INFINITE);
        }
        if(EventMask & EV_RXCHAR) 
        {   
            if(ComReadDate(&Overlapped) == -1)
            {
                //logError("Fack!!!\n");
            }
        }
        if(EventMask & EV_TXEMPTY) 
        {
            // ..
        }
        ResetEvent(Overlapped.hEvent);
    }
    CloseHandle(Overlapped.hEvent);
    return 0;
}

int main(int argc, char *argv[])
{
        //logInit(argc > 3 ? argv[4] :NULL );
    if(!openComPort(argc-1,argv+1))
    {
        //logError("openComPort error\n");
        return 1;
    }
    phandle=CreateThread(NULL,0,ComProcess,NULL,0,NULL);

    if(!phandle) 
    {
        //logError("main error :: CreateThread error\n");
        CloseHandle(hCom);
        Sleep(500);
        return 1;
    }

    WaitForSingleObject(phandle,500);
    printf("esc - exit\n");

    bool esc = false;

    for(char c=0;!esc;)
    {
        for(;!_kbhit();Sleep(50));

        while(_kbhit())
        {
            if( (c = _getch()) )
            {
                writeComData(hCom,&c,1);
                printf("writeComData  \"%c\"\n",c);
               //logMessage("%c",c);
            }
            if(c == 27)   esc = true;
        }
    }
    //logMessage("Exit ....\n");
    if(phandle) TerminateThread(phandle,0);
    WaitForSingleObject(phandle,1000);
    CloseHandle(phandle);   

    //logMessage("Please wait one second.\n");
    Sleep(500);
    CloseHandle(hCom);
    
    Sleep(500);
    return 0;
}

bool  openComPort(int argc, char *argv[])
{
        const char *PortStr = NULL;

        const char *_speed = NULL;
        unsigned int speed = CBR_9600;

        if(argc)
        {
            PortStr = argv[0];
            ++PortStr;
        }
        if(argc>1)
        {
            _speed = argv[1] ;
            ++_speed ;
            speed = atoi (_speed);
            //logMessage("bound rate  = %d \n",speed);
       }
      //logMessage("send file \"%s\"\n",_fname);    
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
        // Инициализация порта
        hCom = CreateFile(PortStr,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, 
                  NULL,
                  OPEN_EXISTING, 
                  FILE_FLAG_OVERLAPPED, 
                  NULL);


        if(hCom==INVALID_HANDLE_VALUE)
        {
            hCom=NULL;
            //logMessage("Open port error");
            return false;
        }   
        //logMessage("Open port \"%s\"\n",PortStr);


        ClearCommPort();

        if(!ClearCommBreak(hCom))
        {
            //logMessage("ClearCommBreak error");
            return  false;
        }
        DCB dcb;

        if(!GetCommState(hCom,&dcb))
        {
             //logMessage("GetCommState error");
             return false;
        }
        // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.

        dcb.BaudRate=speed;    // set the baud rate
        dcb.ByteSize=8;             // data size, xmit, and rcv
        dcb.Parity  =NOPARITY;//SPACEPARITY;   // no parity bit
        dcb.fParity = TRUE;         // Ловить ошибки CRC
        dcb.fErrorChar= FALSE;      // Не подменять символ
        dcb.StopBits=ONESTOPBIT;    // one stop bit

        if(!SetCommState(hCom,&dcb)) 
        {
            //logMessage("SetCommState error");
            return false;
        }

        // All Event
        const DWORD CommEventMask = EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_RING|EV_RLSD|EV_RXCHAR|EV_RXFLAG|EV_TXEMPTY;

        // инициализация события
        if(!SetCommMask(hCom,CommEventMask))
        {
            //logMessage("SetCommMask error");
            return false;
        }
/*
        COMMTIMEOUTS ts;
        if(!GetCommTimeouts(hCom,&ts))             return false;
         ...
        if(!SetCommTimeouts(hCom,&ts))               return false;
*/              
        return true;
}



PM MAIL   Вверх
UniBomb
Дата 28.2.2007, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
***
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 1754
Регистрация: 24.10.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 97



Vsts, 

спасибо, надо попробовать))
PM MAIL ICQ Skype   Вверх
Vsts
Дата 5.3.2007, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.1.2007

Репутация: 1
Всего: 1



а плюсик де ?;) .. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0579 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.