Jump to content

    

USB CDC +HAL. Как правильно обрабатывать переподключение?

Ничего не пойму...

В AsynccProfessional, есть TAdpComPort.

Если выдергиваешь шнурок, а программа передает, генерируется EInOutError. Я пытался его отловить через try catch - бестолку.

Писали тут вроде бы, что это невозможно. В руководстве есть текст, который я не совсем понял

 

7pD5HAxA.png

 

Так все-таки - можно как-то побороть этот EInOutError, чтобы не заполнял экран, а по-тихому закрывался порт?

Share this post


Link to post
Share on other sites

А там случайно нет события ОnError?

Share this post


Link to post
Share on other sites

Есть что-то вроде OnLine Error - но оно не работает

 

Погодите.... я тут исходники копнул....

Идите-ка все спать, к утру наверное я эту недоработку разработчика устраню.

Share this post


Link to post
Share on other sites

Глубоко покопавшись в исходниках я нашел то место, где предположительно генерируется исключение

 

function TApdWin32Dispatcher.WriteCom(Buf: PAnsiChar; Size: Integer): Integer;
type
    PBArray = ^TBArray;
    TBArray = array[0..pred(High(Integer))] of Byte;
var
    SizeAtEnd   : Integer;
    LeftOver    : Integer;
begin
    {Add the data to the output QueueProp}


    EnterCriticalSection(OutputSection);
       try
          //we already know at this point that there is enough room for the block

        SizeAtEnd := OutQue - OBufHead;
        if SizeAtEnd >= Size then
        begin
            //can move data to output QueueProp in one block

            Move(Buf^, OBuffer^[OBufHead], Size);
            if SizeAtEnd = Size then
               OBufHead := 0
            else
             Inc(OBufHead, Size);
        end else
        begin
            // need to use two moves
            Move(Buf^, OBuffer^[OBufHead], SizeAtEnd);
            LeftOver := Size - SizeAtEnd;
            Move(PBArray(Buf)^[SizeAtEnd], OBuffer^, LeftOver);
            OBufHead := LeftOver;
        end;

     finally
     LeaveCriticalSection(OutputSection);

    end;



    {...finally, wake up the output thread to send the data}


    SetEvent(OutputEvent); 
    Result := Size;   {report all was sent}
end;

3 с конца строка SetEvent(OutputEvent); 

Если ее закомментировать, то ошибка не возникает. 

То есть, если выдернуть шнур, то все, что выше, выполняется, а на строке SetEvent происходит нечто, что приводит к появлению ошибкe EInOutError

 

Я попробовал обрамить эту строку try-except

 

try
    SetEvent(OutputEvent);
 except
     on E: EInOutError do
      begin
        ShowMessage('ERROR_1');
        result := Error;
      end;
 end;

Не ловится исключение, то есть алерт на экран вылетает, но ShowMessage не срабатывает.

Мысли кончились... МОжет у кого будут какие идеи?

Share this post


Link to post
Share on other sites

Да, тяжело искать ошибку, когда вы не понимаете, как это работает.

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

И уже в том потоке возникает исключение. Там его и надо ловить.

Share this post


Link to post
Share on other sites
1 hour ago, AHTOXA said:

Да, тяжело искать ошибку, когда вы не понимаете, как это работает.

 я пошел по этому пути, ориентируясь на описанный кем-то опыт борьбы с подобной проблемой. Там человек даже не лез в функцию writecom, а вызывал ее в блоке try except в функции put_block.

Правда у него выскакивало не EInOutError, а EAccessViolation.

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

 

Вот я и надеялся что в случае с EInOutError это тоже прокатит.

А Вам спасибо за подсказку, буду искать.

Share this post


Link to post
Share on other sites
5 часов назад, -=Женек=- сказал:

Правда у него выскакивало не EInOutError, а EAccessViolation. 

Ну правильно, EAccessViolation возникал при подготовке данных, а EInOutError - уже в процессе передачи.

Я всё же советую вам для начала поискать в документации и примерах использования. Мне кажется, что должен быть предусмотрен обработчик ошибок.

Share this post


Link to post
Share on other sites

ЗЫ. Хотя нет, быстренько глянул доку - нет такого. Видимо, в те времена, когда начинали писать эту библиотеку, ещё не было USB-портов, и сбой при записи в файл порта был невозможен.

Share this post


Link to post
Share on other sites
1 hour ago, AHTOXA said:

ЗЫ. Хотя нет, быстренько глянул доку - нет такого. Видимо, в те времена, когда начинали писать эту библиотеку, ещё не было USB-портов, и сбой при записи в файл порта был невозможен.

Как то раз при выдергивания шнура у меня выскочило  "APRO Except!" Обрабатывает он исключения, но не все.

 

Вот файл, где и работа порта и организация потоков...

Не глянете? Может вам удастся понять, где там исключение ловить?

AwUser.pas

Share this post


Link to post
Share on other sites

Посмотрел. Единственный кандидат на показ исключения: функция ShowException(). Вызывается из нескольких мест.

Но вообще там нет такого, чтоб непрерывно сыпались исключения. Если возникает ошибка, поток завершает выполнение, и однократно показывается сообщение об ошибке. Возможно, вы продолжаете писать в закрытый порт, и от этого валятся ошибки.

Share this post


Link to post
Share on other sites
2 hours ago, AHTOXA said:

Единственный кандидат на показ исключения: функция ShowException()

Ёкерный бабай.

Вы правы. Именно так.

Я почему-то думал, что сообщение выдает не программа, а система. И пытался перехватить систему. А оказывается надо было бороться с программой)

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this