我正在尝试使用覆盆子pi 3和Ultimate GPS V3分线板的GPS驱动程序示例。
以下是完整的源代码:https://github.com/androidthings/drivers-samples/tree/master/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)
在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
在将缓冲区大小增加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
我不知道垃圾可能来自哪里......
答案 0 :(得分: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个位置重置:
新框架开始时:
或框架结束时:
我没有硬件来调试您的问题,但我可以推荐您如何做到这一点:
对于想要调试 contrib-driver
的人来说分叉/制作这个安卓库的副本: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文件,添加日志记录。在fork / copy的NmeaGpsModule.java
中,进行两处更改:
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-samples
)https://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"
如果没有重置缓冲区..你需要检查你的硬接线或添加更多日志来找出原因。< / p>
答案 1 :(得分:1)
在某些情况下,无论从UART读取多少字节,processBuffer()都将处理整个缓冲区(512字节)。如果碰巧错过了开头或结尾字符,你最终可能会在消息缓冲区中输入很多“0”。您可以将this修改为:
int count;
while ((count = uart.read(buffer, buffer.length)) > 0) {
processBuffer(buffer, count);
}
然后修改this更像是这样:
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()方法可以读取拆分消息,即消息的开始或结束。如果是这样,就会发生坏事。