Приложение IoT Core UWP зависает на DataReader.LoadAsync после записи, чтобы остановить UHF Reader - PullRequest
0 голосов
/ 09 ноября 2018

Я пишу решение в VS2017, состоящее из двух проектов UWP, которые требуют использования UHF RFID Reader. Один представляет собой систему x64, а другой - ARM (для Raspberry Pi 3 - Windows 10 IoT Core).

Части, которые я использую для обоих проектов:

Я думаю об использовании одного и того же кода в обоих приложениях (оба UWP) для чтения и записи команд в мой UHF Reader.

Мой UHF-ридер (который имеет гнездо RS-232) подключается напрямую к одному из портов USB моего ноутбука (с помощью кабеля RS-232 - USB). Тот же UHF-ридер сначала подключается к USB-TTL-контроллеру CP2102 (Reader_GND <-> TTL_GND, Reader_Tx <-> TTL_Rx, Reader_Rx <-> TTL_Tx), который подключается к одному из портов USB 2.0 моего Pi 3.

Следующий код работает в обоих приложениях и идентифицирует соответствующее устройство:

// ...
aqs = SerialDevice.GetDeviceSelector(); 
DeviceInformationCollection dis = await 
DeviceInformation.FindAllAsync(aqs);
// ...

Код в приложении UWP x64 (работает на моем ноутбуке) находит имя устройства «USB-SERIAL CH340», тогда как тот же код в приложении ARM (работает на Pi 3) находит «CP2102 USB to UART Bridge Controller» , Пока все хорошо.

Следуя руководству по протоколу разработчика для моего UHF-ридера, я смог создать методы, которые отправляют команды для получения версии прошивки ридера, запуска ридера, остановки ридера, получения параметров, установки параметров и сканирования карты (ID тега). Все эти методы хорошо работают в приложении UWP x64 (ноутбук); однако, когда я запускаю тот же метод Stop Reader в своем приложении UWP ARM (Pi 3), он выполняет команду Write, а затем, после этого, зависает в строке кода DataReader.LoadAsync ().

Это строки кода, через которые он проходит перед зависанием:

// ...
private SerialDevice _serialRFPort = null;
...

public RfidCardReader(SerialDevice device) //SerialDevice device
{
    //configures the serial settings for interfacing with the RFID-Reader board

    _serialRFPort = device;
    _serialRFPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
    _serialRFPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
    _serialRFPort.BaudRate = 9600;
    _serialRFPort.Parity = SerialParity.None;
    _serialRFPort.StopBits = SerialStopBitCount.One;
    _serialRFPort.DataBits = 8;
    _serialRFPort.Handshake = SerialHandshake.None;

    // Create cancellation token object to close I/O operations when closing the device
    ReadCancellationTokenSource = new CancellationTokenSource();
}
...

private async Task<byte[]> SendCommand(byte[] command)
{
   var writeResult = await Write(command); 
   if (writeResult.IsSuccessful)
   {
      //get response from the RFID-Reader
      var readResult = await Read(ReadCancellationTokenSource.Token);
...

private async Task<RfidReaderResult> Write(byte[] writeBytes)
{
    var dataWriter = new DataWriter(_serialRFPort.OutputStream);
...

private async Task<RfidReaderResult> Read(CancellationToken cancellationToken)
{
   DataReader dataReader = new DataReader(_serialRFPort.InputStream);
   ...
        loadAsyncTask = dataReader.LoadAsync(1024).AsTask(childCancellationTokenSource.Token);
        uint numBytesRecvd = await loadAsyncTask;  // <-- HANGS HERE FOREVER! .... :'(
...
// ...

Код приложения UWP x64 обрабатывает loadAsyncTask, возвращая массив из 6 байтов (со значениями «0») в переменную numBytesRecvd, в то время как приложение UWP ARM зависает навсегда в ожидании loadAsyncTask (который действительно выполняет DataReader.LoadAsync ()).

Я подумал, что проблема, возможно, связана с тем, что у Pi 3 нет драйвера для "контроллера моста USB-UART CP2102", но я запустил следующий сценарий PowerShell на Pi 3, и я предполагаю, что он перечисляет драйвер (если я не неправильно):

// ---------------------------------
> devcon.exe driverfiles *
...
USB\VID_10C4&PID_EA60\0001
    Name: Silicon Labs CP210x USB to UART Bridge
...
// ---------------------------------

Кто-нибудь из вас имеет представление о том, что приводит к зависанию DataReader.LoadAsync () в моем приложении UWP ARM (Pi 3), а также в моем приложении UWP x64 (ноутбуке)? Любые предложения о том, как решить эту проблему? ...: (

1 Ответ

0 голосов
/ 10 ноября 2018

У меня есть класс для управления последовательной шиной в UWP ARM проекте, вы можете увидеть это ниже:

class SerialDataBus : IDisposable
{
    private DataReader dataReader;
    private DataWriter dataWriter;

    public SerialDataBus(SerialDevice serialDevice)
    {
        dataReader = new DataReader(serialDevice.InputStream);
        dataWriter = new DataWriter(serialDevice.OutputStream);
        dataReader.InputStreamOptions = InputStreamOptions.Partial;
    }

    public DataReaderLoadOperation LoadAsync(uint count)
    {
        return dataReader.LoadAsync(count);
    }

    public DataWriterStoreOperation StoreAsync()
    {
        return dataWriter.StoreAsync();
    }

    public void ReadBytes(byte[] value)
    {
        dataReader.ReadBytes(value);
    }

    public void Dispose()
    {
        if (dataReader != null)
        {
            dataReader.DetachStream();
            dataReader.Dispose();
        }

        if (dataWriter != null)
        {
            dataWriter.DetachStream();
            dataWriter.Dispose();
        }
    }

    public void WriteBytes(byte[] value)
    {
        dataWriter.WriteBytes(value);
    }
}

И я использую SerialDataBus для чтения из модулей и записи в модули следующим образом:

  using (SerialDataBus dataBus = new SerialDataBus(serialDevice))
  {
       //If you want write command to module or reader
       dataBus.WriteBytes('Your Command in Byte[] format');
       await dataBus.StoreAsync().AsTask();

       //Read data from module
       uint readByteLenght = await dataBus.LoadAsync(1024).AsTask();
       byte[] buffer = new byte[readByteLenght];
       dataBus.ReadBytes(buffer);
  }
...