0

我正在尝试使用树莓派 3 和 Ultimate GPS V3 分线板的 GPS 驱动程序示例。

这是完整的源代码:https ://github.com/androidthings/drivers-samples/tree/master/gps

GPS板按照以下示意图连接: 在此处输入图像描述

启动示例应用程序时,我收到以下错误:

com.example.androidthings.driversamples E/AndroidRuntime: FATAL EXCEPTION: main


Process: com.example.androidthings.driversamples, PID: 1299
   java.nio.BufferOverflowException
       at java.nio.Buffer.nextPutIndex(Buffer.java:508)
       at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:142)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule.processBuffer(NmeaGpsModule.java:178)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule.readUartBuffer(NmeaGpsModule.java:160)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule.access$000(NmeaGpsModule.java:35)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule$1.onUartDeviceDataAvailable(NmeaGpsModule.java:139)
       at com.google.android.things.pio.UartDevice$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDevice.java:507)
       at com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:127)
       at android.os.MessageQueue.dispatchEvents(MessageQueue.java:282)
       at android.os.MessageQueue.nativePollOnce(Native Method)
       at android.os.MessageQueue.next(MessageQueue.java:323)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:6077)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

更新 1

在 contrib-driver 项目中启用调试后,我看到一个新错误:W/NmeaParser: Invalid checksum (62), expected 108

12-28 17:53:28.638 1378-1378/com.example.androidthings.driversamples D/XXX: Debug version used
12-28 17:53:29.451 1378-1378/com.example.androidthings.driversamples I/Choreographer: Skipped 34 frames!  The application may be doing too much work on its main thread.
12-28 17:53:29.862 1378-1378/com.example.androidthings.driversamples W/NmeaParser: Invalid checksum (62), expected 108
12-28 17:53:29.862 1378-1378/com.example.androidthings.driversamples D/XXX: Buffer reset
12-28 17:53:30.427 1378-1378/com.example.androidthings.driversamples D/AndroidRuntime: Shutting down VM
12-28 17:53:30.428 1378-1378/com.example.androidthings.driversamples E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.example.androidthings.driversamples, PID: 1378
   java.nio.BufferOverflowException
       at java.nio.Buffer.nextPutIndex(Buffer.java:508)
       at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:142)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule.processBuffer(NmeaGpsModule.java:179)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule.readUartBuffer(NmeaGpsModule.java:161)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule.access$000(NmeaGpsModule.java:35)
       at com.google.android.things.contrib.driver.gps.NmeaGpsModule$1.onUartDeviceDataAvailable(NmeaGpsModule.java:140)
       at com.google.android.things.pio.UartDevice$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDevice.java:507)
       at com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:127)
       at android.os.MessageQueue.dispatchEvents(MessageQueue.java:282)
       at android.os.MessageQueue.nativePollOnce(Native Method)
       at android.os.MessageQueue.next(MessageQueue.java:323)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:6077)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
12-28 17:53:30.439 1378-1378/com.example.androidthings.driversamples I/Process: Sending signal. PID: 1378 SIG: 9

更新 2

将缓冲区大小增加 4 后,我能够收到几条消息。我看到一些消息有一些可以解释溢出的垃圾:

12-28 23:38:17.393 2366-2366/? D/XXX: message: ��GPGGA,233817.000,3742.1931,N,12208.3976,W,1,04,1.96,164.3,M,-25.5,M,,*58
12-28 23:38:17.394 2366-2366/? D/XXX: Buffer reset
12-28 23:38:17.394 2366-2366/? D/XXX: message: GPGSA,A,3,23,03,26,22,,,,,,,,,2.20,1.96,1.00*0B
12-28 23:38:17.395 2366-2366/? D/XXX: Buffer reset
12-28 23:38:17.544 2366-2366/com.example.androidthings.driversamples D/XXX: message: GP��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������RMC,233817.000,A��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������,3742.1931,N,12208.3976,W,0.42,205.67,281216,,,A*71
12-28 23:38:17.545 2366-2366/com.example.androidthings.driversamples D/XXX: Buffer reset
12-28 23:38:17.545 2366-2366/com.example.androidthings.driversamples D/XXX: message: GPVTG,205.67,T,,M,0.42,N,0.78,K,A*32
12-28 23:38:17.546 2366-2366/com.example.androidthings.driversamples D/XXX: Buffer reset

不知道那个垃圾是从哪里来的……

4

2 回答 2

1

查看演示代码https://github.com/androidthings/drivers-samples/blob/master/gps/src/main/java/com/example/androidthings/driversamples/GpsActivity.java#L35波特率设置正确根据数据表:https ://cdn-learn.adafruit.com/downloads/pdf/adafruit-ultimate-gps.pdf

并且查看NmeaGpsModule消息缓冲区长度的 contrib-driver 是从驱动程序读取的缓冲区大小的两倍https://github.com/androidthings/contrib-drivers/blob/master/gps/src/main/java/com /google/android/things/contrib/driver/gps/NmeaGpsModule.java#L169所以它不能只读一次就溢出。

这个问题的一个理论可能是消息缓冲区在接收到数据后没有被清除- 因此BufferOverflowException在几个数据包之后你会得到一个。

缓冲区在 2 个位置重置:

当新帧开始时:

https://github.com/androidthings/contrib-drivers/blob/master/gps/src/main/java/com/google/android/things/contrib/driver/gps/NmeaGpsModule.java#L187

或者当一帧结束时:

https://github.com/androidthings/contrib-drivers/blob/master/gps/src/main/java/com/google/android/things/contrib/driver/gps/NmeaGpsModule.java#L209


我没有硬件来调试您的问题,但是我可以推荐您如何做到这一点:

这适用于任何想要调试contrib-driver的人

Fork / 复制这个 android 库:https ://github.com/androidthings/contrib-drivers/tree/master/gps

编辑build.gradle以添加此依赖项:https ://github.com/novoda/bintray-release (按照自述文件获取说明)。

添加该依赖项后,build.gradle将如下所示:

apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release' // new code

android {
    compileSdkVersion 24
    buildToolsVersion '24.0.3'

    defaultConfig {
        minSdkVersion 24
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
}

buildscript {
    repositories {
        jcenter()
   }
    dependencies {
        classpath 'com.novoda:bintray-release:0.4.0'  // new code
    }
}

dependencies {
    compile 'com.android.support:support-annotations:24.2.0'
    provided 'com.google.android.things:androidthings:0.1-devpreview'
}

publish {  // new code
    userOrg = 'google'
    groupId = 'com.google.android.things.contrib'
    artifactId = 'driver-gps'
    publishVersion = '0.1-DEBUG'
}

现在您可以发布自己的 GPS 驱动程序版本进行调试,但首先:

编辑 java 文件以添加日志记录。在NmeaGpsModule.java您的 fork/copy 中,进行两项更改:

private void init(UartDevice device, int baudRate, Handler handler) throws IOException {
    Log.d("XXX", "MY VERSION BEING USED"); // new code
    mDevice = device;
    mDevice.setBaudrate(baudRate);
    mDevice.registerUartDeviceCallback(mCallback, handler);

    mParser = new NmeaParser();
}

private void resetBuffer() {
    Log.d("XXX", "BUFFER BEING RESET");  // new code
    mMessageBuffer.clear();
    mFrameFlag = false;
}

要发布此版本,请在与以下文件夹相同的文件夹中的终端中运行此命令build.gradle

 ./gradlew clean build bintrayUpload -PdryRun=true

现在你已经发布了一个依赖!回到你的应用程序(在这种情况下driver-sampleshttps://github.com/androidthings/drivers-samples/blob/master/gps/build.gradle#L39

将 更改build.gradle为具有不同的依赖项:

 compile 'com.google.android.things.contrib:driver-gps:0.1'

变成

 compile 'com.google.android.things.contrib:driver-gps:0.1-DEBUG'

并告诉它在本地查找此依赖项:

repositories {
    mavenLocal()
    jcenter()
}

现在重新运行应用程序,您应该会看到您的日志!首先是完整性日志以证明它有效,"MY VERSION BEING USED"然后"BUFFER BEING RESET"如果缓冲区没有被重置,则缓冲区被重置..您需要检查您的硬接线或添加更多日志以找出原因。

于 2016-12-27T09:52:14.573 回答
1

在某些情况下,无论从 UART 读取多少字节,processBuffer() 都会处理整个缓冲区(512 字节)。如果它碰巧错过了一个开始或结束字符,你可能会在消息缓冲区中得到很多“0”。您可以将其修改

int count;
while ((count = uart.read(buffer, buffer.length)) > 0) {
  processBuffer(buffer, count);
}

然后将其修改更像这样:

private void processBuffer(byte[] buffer, int length) {
    for (int i = 0; i < length; i++) {
        if (mParser.getFrameStart() == buffer[i]) {
            handleFrameStart();
        } else if (mParser.getFrameEnd() == buffer[i]) {
            handleFrameEnd();
        } else {
            //Insert all other characters into the buffer
            mMessageBuffer.put(buffer[i]);
        }
    }
}

然后,如果结束字符被丢弃,您将不会用垃圾填充消息缓冲区。我注意到这发生在我正在处理的使用此源代码的项目中。readUartBuffer() 方法可以读取拆分消息,即消息的开头或结尾。如果是这样,坏事就会发生。

于 2016-12-29T06:06:18.013 回答