Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2008.08.31;
Скачать: [xml.tar.bz2];

Вниз

CE_FRAME   Найти похожие ветки 

 
balepa ©   (2007-11-13 07:50) [0]

Есть программа которая обменивается с прибором по Comm порту по принципу команда-ответ. На одном ПК программа работает без ошибок и сбоев (все передается и принимается к прибору и от него). Ставим все это на др. ПК, "команда" отправляется "ответ" приходит:
1. правильный т.е. все поля (адрес устр., команда, данные, CRC) правильные.
2. Адрес уст. = правильный, номер команды = правильный, данные неправильные, CRC = соответствует CRC пункта 1 (фактически неправильный исходя из того что поля имеют др. значения).

3. В поле "адрес" адресс неправильный, CRC соответствует п. 1, данные = правильные.
и т.д.

В последних двух случаях при ClearCommError(hComm,error) error = CE_FRAME

У обоих ПК одинаковые мат. платы (по крайней мере версия BIOS"а и модель), процы, ОЗУ и т.д.  , все шнуры и приборы одни и те же, версии ОС тоже.

Нашел про CE_FRAME:
Сбои кадра (framing errors) происходят тогда, когда биты данных в последовательном потоке не завершаются корректным стоповым битом, который всегда должен иметь значение 1. Как и в случае ошибок четности, сбои кадра обычно возникают вследствие несоответствия параметров линии между приемником и передатчиком. Получив сбои кадра, проверьте параметры обоих сторон. Сбои кадра, чаще, чем ошибки четности, могут быть вызваны электрическими помехами. И снова решением проблемы может стать укорачивание кабеля, и удаление его от источников помех.

Никто не сталкивался ?


 
atruhin ©   (2007-11-13 15:34) [1]

Ну, я сталкивался, и что? Вроде все понятно сказанно:

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


 
balepa ©   (2007-11-14 08:19) [2]


> atruhin ©   (13.11.07 15:34) [1]
> Ну, я сталкивался, и что? Вроде все понятно сказанно:

И что делали ?

И как объяснить что на одно ПК работает с тем же кабелем и прибором, а с др. нет.


 
Юрий Иванов   (2007-11-14 09:56) [3]

А вы устанавливаете из программы парметры RS-232? Скорость передачи, количество stop bit и т.п.? Если нет, то при обмене все это берется из настроек COM-порта в Windows - они одинаковые на обоих компьютерах?


 
Jeer ©   (2007-11-14 09:58) [4]


> balepa ©   (14.11.07 08:19) [2]
>
>


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


 
balepa ©   (2007-11-14 13:02) [5]


> Юрий Иванов   (14.11.07 09:56) [3]
> А вы устанавливаете из программы парметры RS-232? Скорость
> передачи, количество stop bit и т.п.? Если нет, то при обмене
> все это берется из настроек COM-порта в Windows - они одинаковые
> на обоих компьютерах?


Да.


 
tesseract ©   (2007-11-14 18:02) [6]

Кабель тот-же самый ? холодильников кругом нет ?


 
balepa ©   (2007-11-15 05:55) [7]


> tesseract ©   (14.11.07 18:02) [6]
> Кабель тот-же самый ? холодильников кругом нет ?


Нет только два компа и все.

Еще на одном компе заработало только через примерно 5 опросов CE_FRAME вылазит и все.


 
tesseract ©   (2007-11-15 10:53) [8]


> Еще на одном компе заработало только через примерно 5 опросов
> CE_FRAME вылазит и все.


Такое бывает когда кварц который частоту опроса задаёт сбоит. Но такое очень редко происходит. Причем, ты скажи когда у тебя когда ошибка при приемке или при передаче ? И установка параметров, точно проходит ? бывает, что не все драйверы COM- портов одинаковы по содержанию.


 
balepa ©   (2007-11-15 12:58) [9]


> tesseract ©   (15.11.07 10:53) [8]
>
> > Еще на одном компе заработало только через примерно 5
> опросов
> > CE_FRAME вылазит и все.
>
>
> Такое бывает когда кварц который частоту опроса задаёт сбоит.
>  Но такое очень редко происходит. Причем, ты скажи когда
> у тебя когда ошибка при приемке или при передаче ? И установка
> параметров, точно проходит ? бывает, что не все драйверы
> COM- портов одинаковы по содержанию.


При приемке. Если верить SetCommState, то проходит.


 
tesseract ©   (2007-11-15 13:03) [10]

просмотри PortMon-ом, покажет примерно где рыть. Сравни логи на двух компах.


 
guav ©   (2007-11-15 23:55) [11]

Как заполняется сруктура для SetCommState ? нет ли там неинициализированных полей или полей инициализированных GetCommState ?


 
balepa ©   (2007-11-16 05:28) [12]

TRx = packed record
   ADDR: Word;
   CMD: Byte;
   nnnn: Single;
   //nnnn: array[0..3] of BYTE;
   CODE: Byte;
   CRC: Word;
 end;//Rx


TTx = packed record
   ADDR: Word;
   CMD: Byte;
   param: Byte;
   CRC: Word;
 end; //Tx



> guav ©   (15.11.07 23:55) [11]
> Как заполняется сруктура для SetCommState ? нет ли там неинициализированных
> полей или полей инициализированных GetCommState ?


function TNagThread.OpenPort: Boolean;
begin
  hComm:= CreateFile("\\.\COM1",GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if hComm<>INVALID_HANDLE_VALUE then begin
    GetcommState(hComm,ComDCB);
    ComDCB.DCBlength:= sizeof(ComDCB);
    ComDCB.BaudRate:= CBR_9600;
    ComDCB.StopBits:= OneStopBit;
    ComDCB.Parity:= 0;
    ComDCB.ByteSize:= 8;
    ComDCB.Flags:= ComDCB.Flags xor ComDCB.Flags;
    ComDCB.Flags:= ComDCB.Flags or $00000001 or ($00000030
xor $00000020) or $00004000 or $00003000;
    //RTS_CONTROL_TOGGLE $00003000}
    SetCommState(hComm,ComDCB);
    GetCommTimeouts(hComm,ComTimeouts);
    ComTimeouts.ReadIntervalTimeout:= 0;
    ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
    ComTimeOuts.ReadTotalTimeoutConstant:= 0;
    ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
    ComTimeouts.WriteTotalTimeoutConstant:= 0;
    SetCommTimeouts(hComm,ComTimeouts);
    Result:= true;
  end
  else begin
    Result:= false;
  end;
end;


Чтение
CRCError:= 0;
 Tx.ADDR:= Addr;//1190;
 Tx.CMD:= $40;
 Tx.param:= 0;
 Tx.CRC:= CalculateCRC16(@Tx,4); // ; 44370
 RX.ADDR:= 0;
 Rx.CMD:=0;
 Rx.nnnn:=0;
 Rx.CODE:=0;
 Rx.CRC:=0;
 ClearCommError(hComm,errors,@stat);

 SetCommMask(hComm,EV_TXEMPTY);
 WriteFile(hComm,Tx,6,RWBytes,nil);
 WaitCommEvent(hComm,mask,nil);

 ReadFile(hComm,Rx,10,RWBytes,nil);

 CRC:= CalculateCRC16(@Rx,8);
 PurgeComm(hComm,PURGE_RXCLEAR or PURGE_TXCLEAR);
 sleep(6);


Выдержка из протокола обмена:
Признаком конца пакета служит отсутствие передачи на линии в течении времени, необходимого для передачи 5-6 байт, после окончания передачи стоп-бита последнего байта.


 
tesseract ©   (2007-11-16 10:38) [13]


>  WaitCommEvent(hComm,mask,nil);  ReadFile(hComm,Rx,10,RWBytes,
> nil)


А почему бы лучше overlapped не использовать?
Задержки

   ComTimeouts.ReadIntervalTimeout:= 0;
   ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
   ComTimeOuts.ReadTotalTimeoutConstant:= 0;
   ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
   ComTimeouts.WriteTotalTimeoutConstant:= 0;



Так не пишут. Особенно на скорости 9600 + задержка реакции девайса составит 100-200 мс. Перед инициализацией порта,всегда  чисть буфер - там может какая-нить дрйнь после прошлого запуска остаться.  Может поэтому и CE_FRAME.

ЗЫ:  И кстати оригинальный способ ждать окончания записи :-)


 
Slym ©   (2007-11-16 10:45) [14]

tesseract ©   (16.11.07 10:38) [13]
способ ждать окончания записи

у мня тоже на этом глаз споткнутся при беглом чтении :) с таким жестким пессимизмом подход к делу :)
а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,mask,nil) что приведет к блокировке?


 
guav ©   (2007-11-16 10:59) [15]

> ComDCB.Flags:= ComDCB.Flags xor ComDCB.Flags;

Интересный способ обнулить флаги :)


> GetcommState(hComm,ComDCB);

Это плохая идея. Те поля которые явно не инициализированы - не будут в определённом состоянии, состояние будет зависеть от предыдущих параметров
тем более ComDCB.DCBlength не заполнено перед вызовом GetcommState - имеем там Undefined Behaviour. Вомзожно в этом и дело - на одной машине в стеке на месте ComDCB.DCBlength и других структур оказываются допустимые значения, на другой - нет.

Я бы заменил  GetcommState(hComm,ComDCB); на ZeroMemory(@ComDCB, SizeOf(ComDCB));
А ComDCB.Flags:= ComDCB.Flags xor ComDCB.Flags; ComDCB.Flags:= ComDCB.Flags or ... на ComDCB.Flags:= ...;

Кстати, GetcommState, SetCommState, GetCommTimeouts и SetCommTimeouts это функции. Функции возвращают результат.


 
tesseract ©   (2007-11-16 11:25) [16]


> Кстати, GetcommState, SetCommState, GetCommTimeouts и SetCommTimeouts
> это функции. Функции возвращают результат.


Который обязательно должен проверяться.

> а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,
> mask,nil) что приведет к блокировке?


Запросто, поэтому и говорю про оригинальный.


 
balepa   (2007-11-17 06:17) [17]


> Slym ©   (16.11.07 10:45) [14]
> tesseract ©   (16.11.07 10:38) [13]
> способ ждать окончания записи
> у мня тоже на этом глаз споткнутся при беглом чтении :)
> с таким жестким пессимизмом подход к делу :)
> а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,
> mask,nil) что приведет к блокировке?

Но результат она все равно вернет, в mask будут события.
Все равно после отправки запроса надо подождать немного "время для отправки 5-6 байт", а вот как его (время это) посчитать ?


> tesseract ©   (16.11.07 11:25) [16]
>
> > Кстати, GetcommState, SetCommState, GetCommTimeouts и
> SetCommTimeouts
> > это функции. Функции возвращают результат.
>
>
> Который обязательно должен проверяться.

Ну проверял я их все возвращают положительный результат.


> А почему бы лучше overlapped не использовать?
> Задержки
>
>    ComTimeouts.ReadIntervalTimeout:= 0;
>    ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
>    ComTimeOuts.ReadTotalTimeoutConstant:= 0;
>    ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
>    ComTimeouts.WriteTotalTimeoutConstant:= 0;
> Так не пишут. Особенно на скорости 9600 + задержка реакции
> девайса составит 100-200 мс. Перед инициализацией порта,
> всегда  чисть буфер - там может какая-нить дрйнь после прошлого
> запуска остаться.  Может поэтому и CE_FRAME.
>
> ЗЫ:  И кстати оригинальный способ ждать окончания записи
> :-)

Еще вчера начал переделывать на overlapped. Буфер чищу.
Откуда цифры 100-200 мс ?


 
balepa   (2007-11-17 06:21) [18]


> Slym ©   (16.11.07 10:45) [14]
> tesseract ©   (16.11.07 10:38) [13]
> способ ждать окончания записи
> у мня тоже на этом глаз споткнутся при беглом чтении :)
> с таким жестким пессимизмом подход к делу :)
> а не может EV_TXEMPTY возникнуть раньше вызова WaitCommEvent(hComm,
> mask,nil) что приведет к блокировке?

Но результат она все равно вернет, в mask будут события.
Все равно после отправки запроса надо подождать немного "время для отправки 5-6 байт", а вот как его (время это) посчитать ?


> tesseract ©   (16.11.07 11:25) [16]
>
> > Кстати, GetcommState, SetCommState, GetCommTimeouts и
> SetCommTimeouts
> > это функции. Функции возвращают результат.
>
>
> Который обязательно должен проверяться.

Ну проверял я их все возвращают положительный результат.


> А почему бы лучше overlapped не использовать?
> Задержки
>
>    ComTimeouts.ReadIntervalTimeout:= 0;
>    ComTimeOuts.ReadTotalTimeoutMultiplier:= 0;
>    ComTimeOuts.ReadTotalTimeoutConstant:= 0;
>    ComTimeOuts.WriteTotalTimeoutMultiplier:= 0;
>    ComTimeouts.WriteTotalTimeoutConstant:= 0;
> Так не пишут. Особенно на скорости 9600 + задержка реакции
> девайса составит 100-200 мс. Перед инициализацией порта,
> всегда  чисть буфер - там может какая-нить дрйнь после прошлого
> запуска остаться.  Может поэтому и CE_FRAME.
>
> ЗЫ:  И кстати оригинальный способ ждать окончания записи
> :-)

Еще вчера начал переделывать на overlapped. Буфер чищу.
Откуда цифры 100-200 мс ?


 
guav ©   (2007-11-17 14:47) [19]

> balepa  

Попробуй таки убрать вызов GetcommState или хотя бы исправить в нём ошибку, у меня были проблемы именно с этим.


 
balepa   (2007-11-18 15:14) [20]

Переделал "чтение" с использованием overlapped, но есть подозрения что Overlapped структуру сделать одну и сбрасывать event после использования ResetEvent"ом или оставить как есть ?
Код неопробован на работоспособность, потому что писалось сие дома.
Жду замечаний, предложений и рекомендаций.

function TCP8501Thread.ReadParam(addr: Word; var param:
Single): boolean;
var
  Signaled, errors: Cardinal;
  Tx: TTx;
  Rx: TRx;
  stat: TComStat;
  OvrW,OvrR: Overlapped;
begin
  OvrW.hEvent:= CreateEvent(
         nil,    // default security attribute
         TRUE,    // manual-reset event
         TRUE,    // initial state = signaled
         nil);   // unnamed event object
  OvrW.Internal:= 0;
  OvrW.InternalHigh:= 0;
  OvrW.Offset:= 0;
  OvrW.OffsetHigh:= 0;
  Tx.ADDR:= addr;
  Tx.CMD:= $40;
  Tx.param:= 0;
  Tx.CRC16:= CalculateCRC16(@Tx,4);

  PurgeComm(hComm, PURGE_TXABORT or PURGE_RXABORT or PURGE_RXCLEAR
or PURGE_TXCLEAR);
  ClearCommError(hComm,errors,@stat);
  if not WriteFile(hComm,Tx,6,RWBytes,@OvrW) then begin
    if GetLastError = ERROR_IO_PENDING then begin
      Signaled:= WaitForSingleObject(OvrW.hEvent,WRITE_TIMEOUT);

      if (Signaled=WAIT_OBJECT_0) and (GetOverlappedResult(hComm,
OvrW,RWBytes,false)) then begin
        //ResetEvent(OvrW.hEvent);
        CloseHandle(OvrW.hEvent);
        Sleep(10);
        FillChar(Rx,sizeof(TRx),0);
        OvrR.hEvent:= CreateEvent(
            nil,    // default security attribute
            TRUE,    // manual-reset event
            TRUE,    // initial state = nonsignaled
            nil);   // unnamed event object
        OvrR.Internal:= 0;
        OvrR.InternalHigh:= 0;
        OvrR.Offset:= 0;
        OvrR.OffsetHigh:= 0;
        ClearCommError(hComm,errors,@stat);
        if not ReadFile(hComm,Rx,10,RWBytes,@OvrR) then
begin
          if GetLastError = ERROR_IO_PENDING then begin
            Signaled:= WaitForSingleObject(OvrR.hEvent,READ_TIMEOUT);

            if (Signaled=WAIT_OBJECT_0) and (GetOverlappedResult(hComm,
OvrR,RWBytes,false)) then begin
              CloseHandle(OvrR.hEvent);
              CRC:= CalculateCRC16(@Rx,8);
              if CRC=Rx.CRC16 then begin
                asm
                  PUSHA
                  mov DWORD PTR eax,Rx.nnnn
                  bswap eax
                  mov Rx.nnnn, eax
                  POPA
                end;
                param:= Rx.nnnn;
                Result:= true;
              end else begin  //if CRCfalse
                if CRCError < 4294967294 then CRCError:=
CRCError + 1
                else CRCError:= 1;
                CloseHandle(OvrR.hEvent);
                Result:= true;
              end;
            end else begin  //if read failed
              RErrors:= RErrors + 1;
              CloseHandle(OvrR.hEvent);
              Result:= false;
            end;
          end; //GetLastError Read
        end
      end else begin    //if write failed;
        WErrors:= WErrors + 1;
        CloseHandle(OvrW.hEvent);
        Result:= false;
      end;
    end else Result:= false; //GetLastError write
  end; //if not write

  if Result=false then begin
    case addr of
      1183: b1:= false;
      1182: b2:= false;
      1180: K:= false;
    end;
  end else begin
    case addr of
      1183: b1:= true;
      1182: b2:= true;
      1180: K:= true;
    end;
  end;
end;


 
Slym ©   (2007-11-19 04:26) [21]

а Вы говорите процедурный язык...


 
balepa ©   (2007-11-19 05:27) [22]


> balepa   (18.11.07 15:14) [20]
> end else begin  //if CRCfalse
>                 if CRCError < 4294967294 then CRCError:=
>
> CRCError + 1
>                 else CRCError:= 1;
>                 CloseHandle(OvrR.hEvent);
>                 Result:= true;
>               end;

CloseHandle(OvrR.hEvent); лишнее оказывается :)

А так вроде работает пока.


 
balepa ©   (2007-11-19 05:55) [23]


> balepa ©   (19.11.07 05:27) [22]
>
> > balepa   (18.11.07 15:14) [20]
> > end else begin  //if CRCfalse
> >                 if CRCError < 4294967294 then CRCError:
> =
> >
> > CRCError + 1
> >                 else CRCError:= 1;
> >                 CloseHandle(OvrR.hEvent);
> >                 Result:= true;
> >               end;
>
> CloseHandle(OvrR.hEvent); лишнее оказывается :)
>
> А так вроде работает пока.

CE_FRAME вылазит иногда.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2008.08.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.008 c
3-1204549104
Ega23
2008-03-03 15:58
2008.08.31
А насколько сильно влияет наличие вторичного ключа


2-1216799564
textExpanser
2008-07-23 11:52
2008.08.31
Простая независимая база данных (типа таблицы) для записи в файл


6-1192783761
VaRela
2007-10-19 12:49
2008.08.31
Блокирующий TServerSocket


15-1215766185
ekto
2008-07-11 12:49
2008.08.31
Создать класс или обойтись процедурками.


3-1204634091
abhtr
2008-03-04 15:34
2008.08.31
Один Master <-> несколько Detail





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский