Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.08.31;
Скачать: CL | DM;

Вниз

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 вся ветка

Текущий архив: 2008.08.31;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.021 c
8-1184845530
ZMRaven
2007-07-19 15:45
2008.08.31
Захват


15-1215912547
AFHU
2008-07-13 05:29
2008.08.31
Имя России. Исторический выбор-2008


2-1216830441
Denis__
2008-07-23 20:27
2008.08.31
Настройки


15-1215967507
No_Dead
2008-07-13 20:45
2008.08.31
Просьба не игнорировать опрос:)


1-1198005654
Punch
2007-12-18 22:20
2008.08.31
MDI и мерцания MDIChild