СОМ на PocketPC вешает обработку событий.
От: slabko  
Дата: 11.10.05 09:51
Оценка:
Преведствую All!

Такая у меня происходит история, пишу программку для PocketPC в C#, которая прослушивает COM порт на наличие данных от сканера штрих кодов. Доступ к порту получаю с помощью WinAPI. Но вот что происходит, когда я открываю порт и начинаю случать порт (и даже принимать данные), все замечательно работает, до тех пор, пока я не трону экран КПК стайлом, тогда больше он на это стайло реагировать не будет, как и на другие кнопки. При всем этом он весело будет продолжать сканировать и отображать отсканированное на экране. То, что отсканированное все-таки отображается на экране, не смотря на то что, на все другие потуги КПК не обращает внимание, породило во мне подозрение, что это не хардварное повисание, а просто отказ принимать события. Так это или не так, но я все равно в тупике.
Пример, который я набросал(сам код в самом низу), упрощен до состояния подходящего для изучения ошибки, которая все равно никуда не исчезла.
Вот какой порядок действий:
1. Создаю поток.
2. Открываю порт (CreateFile())
3. Устанавливаю фильтр (SetCommMask())
4. Начинаю ждать сообщений (WaitCommEvent())
5. Дожидаюсь и делаю ReadFile()
6. Закрываю порт.
Можно упростить еще больше, т.е. создавать поток и открывать порт и через промежуток времени закрывать в новом потоке, будет тоже самое, если я трону стойлом экран в промежутке, когда порт открыт, но если позже, все будет хорошо и нечего виснуть не будет.

Вот какое оборудование используется:
КПК: RoverPC P5, проц Intel SA1110, ОС Windows CE 3.0 сборка 11171.
Сканер (На всякий случай написал, чтоб был:о) Metrologic Pulsar MS6220
Пишу в Visual Studio 2003 проект для PocketPC (для WinCE .Net писал, тоже самое получается)

А вот измучивший меня код:
public class ComPort
{
    // Эта функцая являтся точкой входа потока
    private void BeginScan()
    {
        IntPtr hPort = CreateFile("COM1:", GENERIC_READ, 0, IntPtr.Zero,
            OPEN_EXISTING, 0, IntPtr.Zero);
        if((int)hPort == ERROR_FILE_NOT_FOUND)
            throw new ApplicationException("Порт не откыт");

        
        uint mskValue = EV_RXCHAR | EV_RXFLAG |
            EV_TXEMPTY | EV_CTS | 
            EV_DSR | EV_RLSD | 
            EV_BREAK | EV_ERR | 
            EV_RING | EV_PERR;

        if( ! SetCommMask(hPort, mskValue))
            throw new ApplicationException("Ошибка при вызове SetCommMask()");

        IntPtr uMask;
        uMask = LocalAlloc(LMEM_FIXED | LMEM_MOVEABLE, 4);
        Marshal.WriteInt32(uMask, 0);

        if( ! WaitCommEvent(hPort, uMask, IntPtr.Zero))
            throw new ApplicationException("Ошибка при вызове WaitCommEvent()");

        uint recv = 0;
        uint bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];

        ReadFile(hPort, buffer, bufferSize, out recv, IntPtr.Zero);

        if( ! CloseHandle(hPort))
            throw new ApplicationException("Ошибка при вызове CloseHandle()");
    }
    
    // Стартую поток
    public void RunMe()
    {
        Thread aThread = new Thread(new ThreadStart(BeginScan));
        aThread.Start();
    }

    //--------------- Имопорт из Win32 --------------------//
    private const UInt32 GENERIC_READ = 0x80000000;
    private const UInt32 GENERIC_WRITE = 0x40000000;
    private const UInt32 OPEN_EXISTING = 3;
    private const UInt32 ERROR_FILE_NOT_FOUND = 2;

    [DllImport("coredll.dll", SetLastError=true)]
    private static extern IntPtr CreateFile(
        String lpFileName, 
        UInt32 dwDesiredAccess, 
        UInt32 dwShareMode,
        IntPtr lpSecurityAttributes, 
        UInt32 dwCreationDisposition, 
        UInt32 dwFlagsAndAttributes,
        IntPtr hTemplateFile);

    [DllImport("coredll.dll", SetLastError=true)]
    private static extern Boolean ReadFile(
        IntPtr hFile, 
        [Out] Byte[] lpBuffer, 
        UInt32 nNumberOfBytesToRead,
        out UInt32 nNumberOfBytesRead, 
        IntPtr lpOverlapped);

    [DllImport("coredll.dll", SetLastError=true)]
    private static extern Boolean CloseHandle(IntPtr hObject);

    private const UInt32 EV_RXCHAR = 0x0001;
    private const UInt32 EV_RXFLAG = 0x0002;
    private const UInt32 EV_TXEMPTY = 0x0004;
    private const UInt32 EV_CTS = 0x0008;
    private const UInt32 EV_DSR = 0x0010;
    private const UInt32 EV_RLSD = 0x0020;
    private const UInt32 EV_BREAK = 0x0040;
    private const UInt32 EV_ERR = 0x0080;
    private const UInt32 EV_RING = 0x0100;
    private const UInt32 EV_PERR = 0x0200;
    private const UInt32 EV_RX80FULL = 0x0400;
    private const UInt32 EV_EVENT1 = 0x0800;
    private const UInt32 EV_EVENT2 = 0x1000;

    [DllImport("coredll.dll", SetLastError=true)]
    private static extern Boolean WaitCommEvent(IntPtr hFile, 
        IntPtr lpEvtMask, IntPtr lpOverlapped);

    [DllImport("coredll.dll")]
    private static extern Boolean SetCommMask(IntPtr hFile, 
        UInt32 dwEvtMask);

    [DllImport("coredll.dll",SetLastError=true)]
    private static extern IntPtr LocalFree(IntPtr hMem);

    [DllImport("coredll.dll",SetLastError=true)]
    private static extern IntPtr LocalAlloc(uint uFlags, uint uBytes);

    private const uint LMEM_FIXED = 0;
    private const uint LMEM_MOVEABLE = 2;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.