写入后,IoT Core UWP应用会挂在DataReader.LoadAsync上以停止UHF阅读器

时间:2018-11-09 18:40:49

标签: uwp raspberry-pi3 rfid datareader windows-10-iot-core

我正在VS2017中编写一个解决方案,该解决方案由两个需要使用UHF RFID读取器的UWP项目组成。一个是x64系统,另一个是ARM(对于Raspberry Pi 3-Windows 10 IoT核心)。

我在两个项目中使用的部分是:

我正在考虑在两个应用程序(都是UWP)上使用相同的代码来向UHF阅读器读取和写入命令。

我的UHF读取器(具有RS-232母端口)直接连接到笔记本电脑的USB端口之一(使用RS-232-USB电缆)。相同的UHF阅读器首先连接到CP2102 USB-TTL控制器(Reader_GND <-> TTL_GND,Reader_Tx <-> TTL_Rx,Reader_Rx <-> TTL_Tx),该控制器连接到我的Pi 3的USB 2.0端口之一。

以下代码在两个应用程序上运行并标识相应的设备:

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

UWP x64应用程序(在我的笔记本电脑上运行)上的代码找到设备名称“ USB-SERIAL CH340”,而ARM应用程序(在Pi 3上运行)上的相同代码找到“ CP2102 USB至UART桥接控制器” 。到目前为止一切顺利。

按照针对我的UHF阅读器的开发人员协议手册,我能够构造用于发送命令以获取阅读器固件版本,启动阅读器,停止阅读器,获取参数,设置参数和扫描卡(标签ID)的方法。所有这些方法都可以在UWP x64应用程序(笔记本电脑)上很好地工作。但是,当我在UWP ARM应用程序(图3)上运行相同的Stop Reader方法时,它会执行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,它向变量numBytesRecvd返回6个字节的数组(值为“ 0”),而UWP ARM应用程序永远挂起,等待loadAsyncTask(实际上正在执行DataReader.LoadAsync())。 / p>

我认为问题可能与Pi 3没有用于“ CP2102 USB到UART桥控制器”的驱动程序有关,但是我在Pi 3上运行了以下PowerShell脚本,并且我假定它列出了驱动程序(除非我是错误):

// ---------------------------------
> 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 :(得分:0)

我在基于 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);
  }