Прога с RS232 в 98 работает, а в XP - нет. почему ?

Тема в разделе "WASM.WIN32", создана пользователем ACF_muti1atoR, 25 май 2005.

  1. ACF_muti1atoR

    ACF_muti1atoR New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    30
    Адрес:
    Провода
    На работе пишу прогу которая общаеться с шкафом по COM-порту. На работе всё работает отлично, там 98 винда SE у меня на компе. Принёс её домой и она начала дико глючить: виснет ("не отвечает") при вызове CloseHandle хэндла порта и при вызове WriteFile в этот порт. При этом всякие открытия порта и настройка его проходит успешно (у меня на всё проверки стоят). Я в непонятках. Порт настраиваеться вот по такому ini-шнику:





    ===============================================

    ; Channel1=COMPort1

    [CHAN1]

    ; Port number. Available values: (1, 2, 3, 4)

    PORT_NUMBER=2

    ;

    ; Baud rate. Available values: (110, 300, 600, 1200, 2400, 4800, 9600, 14400,

    ; 19200, 38400, 56000, 57600, 115200)

    BAUD_RATE=115200

    ;

    ; Data bits on controller. Available values: (7, 8)

    DATA_BITS=8

    ;

    ; Parity check. Available values: (0-None, 1-Odd parity, 2-Even parity,

    ; 3-Mark parity, 4-Space parity)

    PARITY=2

    ;

    ;Stop bits quantity. Available values: (0-1 Stop bit, 1-1.5 Stop bits,

    ; 2-2 Stop bits)

    STOP_BITS=0

    ;

    ; DTR/DSR flow control. Available values: (0-Disable, 1-Enable, 2-Handshake)

    DTR_DSR=0

    ;

    ; RTS/CTS flow control. Available values: (0-Disable, 1-Enable,

    ; 2-Handshake, 3-Toggle)

    RTS_CTS=0

    ;

    ; XON/XOFF flow control. Available values: (0-Disable, 1-Enable)

    XON_XOFF=0

    ;

    ; XON/XOFF characters. Actual only if XON_XOFF=1. Available values: (0..255)

    ; Default values: (XON_CHAR=17, XOFF_CHAR=19)

    XON_CHAR=17

    XOFF_CHAR=19

    ;

    ; Send address (for RS-485)

    SEND_ADDR=0x48

    ;

    ; Receive address (for RS-485)

    RECV_ADDR=0x48

    =====================================================================



    Всё остальное по дефолту !. Может быть по каким-то причинам в разных виндах порт надо настраивать по разному ??? но почему он тогда успешно открываеться и почему всякие там SetCommState возаращают результат что типа всё нормально настроено ?



    помогите пожалуйста. прога должна в любой винде нормально пахать, а то мне конец 8).
     
  2. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    Исходники бы сюда, да прогу вместе со шкафом :)
     
  3. ACF_muti1atoR

    ACF_muti1atoR New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    30
    Адрес:
    Провода
    Ну код настройки порта и его закрытия я наверное могу выложить ... но не более 8) ибо государственная тайна.


    Код (Text):
    1.  
    2. typedef struct tagRsConfig {
    3.   HANDLE        RsDev;
    4.   COMMTIMEOUTS  RsTimeouts;
    5.   DCB           RsDcb;
    6.   unsigned char SndAddr;
    7.   unsigned char RecvAddr;
    8.   BYTE          RsID;
    9.   DWORD         NRecvPack;
    10.   DWORD         NSendPack;
    11. } /*RS_CONFIG, *LPRS_CONFIG,*/ RsConfigType;
    12.  
    13. typedef struct tagRsParam
    14. { DWORD PortNum;  /* COM-port number       */
    15.   DWORD Baud;     /* Baud rate             */
    16.   DWORD DataBits; /* Quantity of data bits */
    17.   DWORD Parity;   /* Parity check          */
    18.   DWORD StopBits; /* Quantity of stop bits */
    19.   DWORD DtrDsr;   /* DTR/DSR flow control  */
    20.   DWORD RtsCts;   /* RTS/CTS flow control  */
    21.   DWORD XonXoff;  /* XON/XOFF flow contol  */
    22.   DWORD XonCh;    /* XON character         */
    23.   DWORD XoffCh;   /* XOFF character        */
    24.   DWORD SndAddr;
    25.   DWORD RecvAddr;
    26. } /*RS_PARAM, *LPRS_PARAM,*/ RsParamType;
    27.  
    28.  
    29. Открытие:
    30. int RsSetup( RsParamType *SetupParam, RsConfigType *RsCfg )
    31. {
    32.   char PortName[16];
    33.  
    34.   memset( RsCfg, 0, sizeof(RsConfigType) );
    35.  
    36.   RsCfg->SndAddr = (unsigned char)SetupParam->SndAddr;
    37.   RsCfg->RecvAddr = (unsigned char)SetupParam->RecvAddr;
    38.   sprintf( PortName, "COM%d", SetupParam->PortNum );
    39.  
    40.   RsCfg->RsDev = CreateFile( PortName,
    41.                              GENERIC_READ|GENERIC_WRITE,
    42.                              0,         /* Exclusive access  */
    43.                              NULL,      /* No security attrs */
    44.                              OPEN_EXISTING,
    45.                              FILE_ATTRIBUTE_NORMAL/*|*/  /* overlapped I/O */
    46.                              /*FILE_FLAG_OVERLAPPED*/,
    47.                              NULL );
    48.   if ( RsCfg->RsDev == (INVALID_HANDLE_VALUE) ) {
    49.     return RS_ERR_OFILE;
    50.   }
    51.  
    52.   if ( SetCommMask(RsCfg->RsDev,EV_RXCHAR) == FALSE ) {
    53.     return RS_ERR_COMM_MASK;
    54.   }
    55.  
    56.   if ( SetupComm(RsCfg->RsDev,RS_RX_SIZE,RS_TX_SIZE) == FALSE ) {
    57.     return RS_ERR_SETUP_COMM;
    58.   }
    59.  
    60.   if ( PurgeComm(RsCfg->RsDev,PURGE_TXABORT|PURGE_RXABORT|
    61.        PURGE_TXCLEAR|PURGE_RXCLEAR) == FALSE ) {
    62.     return RS_ERR_PURGE_COMM;
    63.   }
    64.  
    65.   RsCfg->RsTimeouts.ReadIntervalTimeout = 0;//MAXDWORD;
    66.   RsCfg->RsTimeouts.ReadTotalTimeoutMultiplier = 0;
    67.   RsCfg->RsTimeouts.ReadTotalTimeoutConstant = 0;//RS_RX_MAXTIME;
    68.   RsCfg->RsTimeouts.WriteTotalTimeoutMultiplier = 10;
    69.   RsCfg->RsTimeouts.WriteTotalTimeoutConstant = RS_TX_SIZE;
    70.   if ( SetCommTimeouts(RsCfg->RsDev,&(RsCfg->RsTimeouts)) == FALSE ) {
    71.     return RS_ERR_TIMEOUTS;
    72.   }
    73.  
    74.   RsCfg->RsDcb.DCBlength = sizeof( DCB );
    75.   if ( GetCommState(RsCfg->RsDev,&(RsCfg->RsDcb)) == FALSE ) {
    76.     return RS_ERR_GETCOMMSTATE;
    77.   }
    78.   // main parameters setup
    79.   RsCfg->RsDcb.BaudRate = SetupParam->Baud;
    80.   RsCfg->RsDcb.ByteSize = (BYTE)(SetupParam->DataBits);
    81.   RsCfg->RsDcb.fParity = (SetupParam->Parity) ? (1) : (0);
    82.   if ( RsCfg->RsDcb.fParity ) {
    83.     RsCfg->RsDcb.Parity = SetupParam->Parity;
    84.   }
    85.   RsCfg->RsDcb.fBinary = TRUE;
    86.   RsCfg->RsDcb.StopBits = (BYTE)(SetupParam->StopBits);
    87.  
    88.   // setup hardware flow control
    89.   switch( SetupParam->DtrDsr ) {
    90.     case 0 : RsCfg->RsDcb.fDtrControl = DTR_CONTROL_DISABLE;
    91.              RsCfg->RsDcb.fDsrSensitivity = FALSE;
    92.              break;
    93.     case 1 : RsCfg->RsDcb.fDtrControl = DTR_CONTROL_ENABLE;
    94.              RsCfg->RsDcb.fDsrSensitivity = TRUE;
    95.              break;
    96.     case 2 : RsCfg->RsDcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
    97.              RsCfg->RsDcb.fDsrSensitivity = TRUE;
    98.              break;
    99.     default: MessageBox( NULL, "Incorrect value of DTR/DSR parameter",
    100.                          "Parameters error", MB_OK|MB_ICONHAND );
    101.   }
    102.   switch( SetupParam->RtsCts ) {
    103.     case 0 : RsCfg->RsDcb.fRtsControl = RTS_CONTROL_DISABLE;
    104.              break;
    105.     case 1 : RsCfg->RsDcb.fRtsControl = RTS_CONTROL_ENABLE;
    106.              break;
    107.     case 2 : RsCfg->RsDcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
    108.              break;
    109.     case 3 : RsCfg->RsDcb.fRtsControl = RTS_CONTROL_TOGGLE;
    110.              break;
    111.     default: MessageBox( NULL, "Incorrect value of RTS/CTS parameter",
    112.                          "Parameters error", MB_OK|MB_ICONHAND );
    113.   }
    114.   switch( SetupParam->XonXoff ) {
    115.     case 0 : RsCfg->RsDcb.fOutX = FALSE;
    116.              RsCfg->RsDcb.fInX = FALSE;
    117.              break;
    118.     case 1 : RsCfg->RsDcb.fOutX = TRUE;
    119.              RsCfg->RsDcb.fInX = TRUE;
    120.              RsCfg->RsDcb.XonChar = (BYTE)SetupParam->XonCh;
    121.              RsCfg->RsDcb.XoffChar = (BYTE)SetupParam->XoffCh;
    122.              break;
    123.     default: MessageBox( NULL, "Incorrect value of XON/XOFF parameter",
    124.                          "Parameters error", MB_OK|MB_ICONHAND );
    125.   }
    126.  
    127.   if ( SetCommState(RsCfg->RsDev,&(RsCfg->RsDcb)) == FALSE ) {
    128.     return RS_ERR_SETCOMMSTATE;
    129.   }
    130.  
    131.   RsCfg->NRecvPack = 0;
    132.   RsCfg->NSendPack = 0;
    133.   RsCfg->RsID = SetupParam->PortNum;
    134.  
    135. Закрытие соответственно:
    136.  
    137. int RsClose( RsConfigType *RsCfg )
    138. {
    139.  //ВОТ НА ЭТОМ САМОМ if И ВИСНЕТ
    140.  if ( CloseHandle(RsCfg->RsDev) ) {
    141.     memset( RsCfg, 0, sizeof(RsConfigType) );
    142.     return RS_OK;
    143.   }
    144. }
    145.  
    146.  
     
  4. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    ACF_muti1atoR

    Перед закрытием попробуйте очистить буфер:
    Код (Text):
    1. PurgeComm(RsCfg->RsDev,PURGE_TXCLEAR | PURGE_RXCLEAR);


    Вместо WriteFile, если вы пишете побайтно, лучше использовать TransmitCommChar.



    DCB желательно заполнить сначала через GetCommState.



    Настройка таймаутов тоже не самая стандартная. Лучше так:
    Код (Text):
    1. COMMTIMEOUTS timeouts = {MAXDWORD,0,0,512,512};


    Через Гипертерминал с девайсом получается общаться?
     
  5. Grenader

    Grenader New Member

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    23
    Адрес:
    Russia
    верный ли хендл RsCfg->RsDev - проверял? Это из очевидного. Из менее очевидного - траблы с тем, что ты где-то чего-то портишьс в том же кренеле, и 98й прощает, а ХР - нет.



    самый просто способ найти ошибку - помести CloseHandle сразу за CreateFile. работает? тогда чуток пониже. и так найти место, когда начнутся глюки. При желании можно утилиткой от руссиновича посмотреть список открытых дескрипторов и их типов для процесса.
     
  6. Grenader

    Grenader New Member

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    23
    Адрес:
    Russia
    Quantum

    дык ведь общение идет нормально, виснет закрытие порта, насколько я понял.



    Кстати:

    RsCfg->RsTimeouts.ReadIntervalTimeout = 0;//MAXDWORD;

    разве 0 это MAXDWORD?
     
  7. ACF_muti1atoR

    ACF_muti1atoR New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    30
    Адрес:
    Провода
    Спасибо попробую.



    Grenader нет. Общения никакого нет (в ХР) при WriteFile виснет намертво.



    у меня стоят проверки: если вдруг RsCfg->RsDev станет INVALID_HANDLE_VALUE, то об этом сразу же сообщиться. Это же касается и всех функции конфигурирования порта (если я чего-то не забыл).





    В 98 прога общаеться с железом или с TTY на пример или с прогой написанной специально для тестирования этой. Без каких либо глюков.
     
  8. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    ACF_muti1atoR



    INVALID_HANDLE_VALUE == -1



    Причём CloseHandle не виснет на попытке закрыть такой хендл.



    Grenader правильно советует проследить за значением RsDev. Если оно вдруг станет отличным от того, что вернула CreateFile (не обязательно -1), что легко увидеть в отладчике.
     
  9. uni

    uni New Member

    Публикаций:
    0
    Регистрация:
    23 май 2005
    Сообщения:
    67
    > помогите пожалуйста. прога должна в любой винде нормально пахать, а то мне конец 8).



    Если всё настолько плохо, почему бы не использовать уже готовое? Ридико Л.И., к примеру, для общения с одним устройством пользовался библиотекой, находящейся в отдельной dll.

    http://www.telesys.ru/projects/proj065/index.shtml

    Я сам пробовал в XP Pro - прога работает с этим устройством. Но это на крайний случай, если не найдете решения проблемы. Вам только заголовочник нужно будет написать и lib файл сделать по паскалевскому описанию в коде, а может и так найдете где нить.
     
  10. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    Хендл порта не меняется во время выполнения программы.



    Quantum

    DCB заполняется через GetComState а потом уже из инишника.
     
  11. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    NoName



    Глаза продрал - теперь вижу :)





    Откуда такая информация? У вас есть доступ к программе и вы её проверили под отладчиком?
     
  12. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    Quantum

    Совершенно верно.
     
  13. ACF_muti1atoR

    ACF_muti1atoR New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    30
    Адрес:
    Провода
    Quantum

    программа-то моя 8) поэтому доступ у меня к ней есть.