Uart/GPS 驱动程序样本缓冲区溢出 [英] Uart / GPS driver sample buffer overflow

查看:88
本文介绍了Uart/GPS 驱动程序样本缓冲区溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 raspberry pi 3 和 Ultimate GPS V3 分线板的 GPS 驱动程序示例.

这里是完整的源代码:

启动示例应用程序时,出现以下错误:

com.example.androidthings.driversamples E/AndroidRuntime:致命异常:main进程:com.example.androidthings.driversamples,PID:1299java.nio.BufferOverflowException在 java.nio.Buffer.nextPutIndex(Buffer.java:508)在 java.nio.HeapByteBuffer.put(HeapByteBuffer.java:142)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule.processBuffer(NmeaGpsModule.java:178)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule.readUartBuffer(NmeaGpsModule.java:160)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule.access$000(NmeaGpsModule.java:35)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule$1.onUartDeviceDataAvailable(NmeaGpsModule.java:139)在 com.google.android.things.pio.UartDevice$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDevice.java:507)在 com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:127)在 android.os.MessageQueue.dispatchEvents(MessageQueue.java:282)在 android.os.MessageQueue.nativePollOnce(本机方法)在 android.os.MessageQueue.next(MessageQueue.java:323)在 android.os.Looper.loop(Looper.java:136)在 android.app.ActivityThread.main(ActivityThread.java:6077)在 java.lang.reflect.Method.invoke(Native Method)在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)在 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:使用的调试版本12-28 17:53:29.451 1378-1378/com.example.androidthings.driversamples I/Choreographer:跳过 34 帧!应用程序可能在其主线程上做了太多工作.12-28 17:53:29.862 1378-1378/com.example.androidthings.driversamples W/NmeaParser:校验和无效 (62),预期为 10812-28 17:53:29.862 1378-1378/com.example.androidthings.driversamples D/XXX:缓冲区重置12-28 17:53:30.427 1378-1378/com.example.androidthings.driversamples D/AndroidRuntime:关闭虚拟机12-28 17:53:30.428 1378-1378/com.example.androidthings.driversamples E/AndroidRuntime:致命异常:主要进程:com.example.androidthings.driversamples,PID:1378java.nio.BufferOverflowException在 java.nio.Buffer.nextPutIndex(Buffer.java:508)在 java.nio.HeapByteBuffer.put(HeapByteBuffer.java:142)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule.processBuffer(NmeaGpsModule.java:179)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule.readUartBuffer(NmeaGpsModule.java:161)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule.access$000(NmeaGpsModule.java:35)在 com.google.android.things.contrib.driver.gps.NmeaGpsModule$1.onUartDeviceDataAvailable(NmeaGpsModule.java:140)在 com.google.android.things.pio.UartDevice$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDevice.java:507)在 com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:127)在 android.os.MessageQueue.dispatchEvents(MessageQueue.java:282)在 android.os.MessageQueue.nativePollOnce(本机方法)在 android.os.MessageQueue.next(MessageQueue.java:323)在 android.os.Looper.loop(Looper.java:136)在 android.app.ActivityThread.main(ActivityThread.java:6077)在 java.lang.reflect.Method.invoke(Native Method)在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)12-28 17:53:30.439 1378-1378/com.example.androidthings.driversamples I/Process:发送信号.PID:1378 SIG:9

<小时>

更新 2

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

12-28 23:38:17.393 2366-2366/?D/XXX:消息:  GPGGA,233817.000,3742.1931,N,12208.3976,W,1,04,1.96,164.3,M,-25.5,M,,*5812-28 23:38:17.394 2366-2366/?D/XXX:缓冲区复位12-28 23:38:17.394 2366-2366/?D/XXX:消息:GPGSA,A,3,23,03,26,22,,,,,,,,,2.20,1.96,1.00*0B12-28 23:38:17.395 2366-2366/?D/XXX:缓冲区复位12-28 23:38:17.544 2366-2366/com.example.androidthings.driversamples D/XXX:消息:GPRMC,233817.000,A,3742.1931,N,12208.3976,W,0.42,205.67,281216,,,,A*7112-28 23:38:17.545 2366-2366/com.example.androidthings.driversamples D/XXX:缓冲区重置12-28 23:38:17.545 2366-2366/com.example.androidthings.driversamples D/XXX:消息:GPVTG,205.67,T,,M,0.42,N,0.78,K,A*3212-28 23:38:17.546 2366-2366/com.example.androidthings.driversamples D/XXX:缓冲区重置

我不知道那些垃圾是从哪里来的...

解决方案

在某些情况下,无论从 UART 读取多少字节,processBuffer() 都会处理整个缓冲区(512 字节).如果碰巧错过了开始或结束字符,则消息缓冲区中可能会出现很多0".您可以修改 这个是这样的:

int 计数;while ((count = uart.read(buffer, buffer.length)) > 0) {进程缓冲区(缓冲区,计数);}

然后修改这个 更像这样:

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();} 别的 {//将所有其他字符插入缓冲区mMessageBuffer.put(buffer[i]);}}}

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

I am trying the sample for the GPS driver with a raspberry pi 3 and the Ultimate GPS V3 breakout board.

Here is the full source code: https://github.com/androidthings/drivers-samples/tree/master/gps

The GPS board is connected following this schematics:

When launching the sample app, I get the following error:

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)


Update 1

After enabling the debug in the contrib-driver project, I see a new error: 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


Update 2

After increasing the buffer size by 4, I was able to get few messages in. I see some messages have some junk that would explain the overflow:

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

I have no idea where that junk could come from...

解决方案

In some cases processBuffer() will process the whole buffer (512 bytes) regardless of how many bytes are read from the UART. If it happens to miss a start or end character you can end up with a lot of '0' in the message buffer. You can modify this to be like this:

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

then modify this to be more like 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]);
        }
    }
}

Then you won't be filling the message buffer with garbage if an end character gets dropped. I noticed this happening in a project I'm working on that uses this source code. The readUartBuffer() method can read split messages, i.e., the start or end of a message. If it does, bad things happen.

这篇关于Uart/GPS 驱动程序样本缓冲区溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆