This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

LIBUARTE strange behaviour

Hi everyone,

I am trying to solve a bug I am facing for several days now, it is related to LIBUARTE communication with a GPS module

Communication is init at 115200 BAUD and with a timeout of 100us.

The GPS module sends data every second. This data is composed by several frames, all starting with '$' and ending with " *xx " (xx can be any number)

Here is an example of correct data:

$GNRMC,164352.97,V,,,,,,,060421,,,N,V*11
$GNGGA,164352.97,,,,,0,04,8.0,,M,,M,,*7D
$GNGLL,,,,,164352.97,V,N*5D
$GPGSV,16,,,31,26,,,20,27,,,32,1*6D
$GPGSV,2,2,07,08,,,25,26,,,21,27,,,25,8*60
$GLGSV,1,1,02,82,,,20,81,,,24,1*7D
$GNGSA,A,1,,,,,,,,,,,,,16.7,8.0,14.7,4*3C
$GNGSA,A,1,,,,,,,,,,,,,16.7,8.0,14.7,5*3D
$GNGSA,A,1,,,,,,,,,,,,,16.7,8.0,14.7,6*3E

But here is the data I actually receive from GNSS module:

"NEWFRAME" is to indicate the beginning of a new packet of data in the UART handler.

NEWFRAME$PQGNSS,001*15
$PQVER,MODULE_LC79DANR01A04S,2019/12/18,10:17:15*25
$PQVER,SUB_V03*22
$PQVER,GL_20.23*15
$PQVER,GL_ANEWFRAME000100000000000000000000000000000000000000000000000000000000000000000000*42
$PQSWCONFIG,1,2,4,000000000000000000000000NEWFRAME00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000NEWFRAME101010101010000*3E
ER,MODULE_LC79DANR01A04S,2019/12/18,10:17:15*25
$PQVER,SUB_V03*22
$PQVER,GL_20.23*15
$PQVER,GL_ANEWFRAME$GNRMC,164052.86,V,,,,,,,060421,,,N,V*12
$GNGGA,164052.86,,,,,0,00,99.0,,M,,M,,*42
$GNGLL,,,,,164052.86,V,N*5E
$GNGSNEWFRAME99.0,3*01
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,4*06
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,5*07
$GNGSA,A,1,,,,,,,,,,NEWFRAME$GNRMC,164053.86,V,,,,,,,060421,,,N,V*13
$GNGGA,164053.86,,,,,0,00,99.0,,M,,M,,*43
$GNEWFRAMENGLL,,,,,164053.86,V,N*5F
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,1*03
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,2*00
$GNGNEWFRAME,1,,,,,,,,,,,,,99.0,99.0,99.0,6*04
$GNVTG,,T,,M,,N,,K,N*32
$GNRMC,164053.88,V,,,,,,,060421,,,N,V*1D
$GNGGA,164053.88NEWFRAME,1,,,,,,,,,,,,,99.0,99.0,99.0,2*00
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,3*01
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,4NEWFRAME$GNRMC,164054.86,VNEWFRAME,,,,,,,060421,,,N,V*14
$GNGGA,164054.86,,,,,0,00,99.0,,M,,M,,*44
$GNGLL,,,,,164054.86,V,N*58
$GPGSV,1,1,01,08,,,30,1NEWFRAME
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,4*06
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,5*07
$GNGSA,A,1,,,,,,,,,,,,,99.0,99NEWFRAME$GNRMC,164055.86,V,,,,,,,060421,,,N,V*15
$GNGGA,164055.86,,,,,0,00,99.0,,M,,M,,*45
$GNGLL,,,,,1NEWFRAME64055.86,V,N*59
$GPGSV,1,1,01,16,,,24,1*64
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,1*03
$GNGSA,A,1,,,,,,,,,,,,,99.0,99NEWFRAME9.0,5*07
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,6*04
$GNVTG,,T,,M,,N,,K,N*32
64054.86,V,N*58
$GPGSV,1,1,01,08,,,30,1NEWFRAME$GNRMC,164056.86,V,,,,,,,060421,,,N,V*16
$GNGGA,164056.86,,,,,0,00,99.0,,M,,M,,*46
$GNGLL,,,,,164056.86,V,N*5A
$GPGSNEWFRAME0,99.0,99.0,1*03
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,2*00
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,3*01
$GNGSA,A,1,,,NEWFRAME$GNRMC,164057.86,V,,,,,,,060421,,,N,V*17
$GNGGA,164057.86,,,,,0,00,99.0,,M,,M,,*47
$GNGLL,,,,,164057.86,V,N*5B
$GPGSNEWFRAME,,,,,,99.0,99.0,99.0,3*01
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,4*06
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,5*07
$GNGNEWFRAME$GNRMC,164058.86,V,,,,,,,060421,,,N,V*18
$GNGGA,164058.86,,,,,0,00,99.NEWFRAME0,,M,,M,,*48
$GNGLL,,,,,164058.86,V,N*54
$GPGSV,1,1,02,16,,,25,27,,,28,1*69
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,1*NEWFRAME$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,5*07
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,6*04
$GNVTG,,T,,M,,N,,K,N*32
,V,N*5NEWFRAME$GNRMC,164059.86,V,,,,,,,060421,,,N,V*19
$GNGGA,164059.86,,,,,0,00,99.0,,M,,M,,*49
$GNGLL,,,,,164059.86,V,N*55
$GPGSNEWFRAME$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,1*03
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,2*00
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.NEWFRAME.0,6*04
$GNVTG,,T,,M,,N,,K,N*32
,V,N*54
$GPGSV,1,1,02,16,,,25,27,,,28,1*69
$GNGSA,A,1,,,,,,,,,,,,,99.0,99.0,99.0,1*NEWFRAME$GNRMC,164100.86,V,,,,,,,060421,,,N,V*14
$GNGGA,164100.86,,,,,0,00,99.0,,M,,M,,*44

Here are my two problems:

1- UART handler is not called at the end of the gps module packets, but somewhere in the middle of them

2- Sometimes, even inside one uart handler packet, I can see that NMEA frames are truncated (missing several bytes)

I already tried to increase uart timeout between 100 to 10000 whithout any improvement (I am getting the exact same output)

my UART instance is defined this way: 

NRF_LIBUARTE_ASYNC_DEFINE(libuarte_gnss, 0, 2, NRF_LIBUARTE_PERIPHERAL_NOT_USED, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);

Any idea where this issue could come from?

Best regards

  • Hi,

    It seems that libUARTE does not want to give me a break.

    My data is always coherent now, but everytime I get a fix on my GNSS module, I get truncated frames (frames are longer when there is a fix since there are more filled fields):

    $GNGGA,093207.58,,,,,0,00,99.0,,M,,M,,*4A
    $GNRMC,093208.58,V,,,,,,,270421,,,N,V*16
    $GNGGA,093208.58,,,,,0,00,99.0,,M,,M,,*45
    $GNRMC,093209.58,V,,,,,,,270421,,,N,V*17
    $GNGGA,093209.58,,,,,0,00,99.0,,M,,M,,*44
    $GNRMC,093210.58,V,,,,,,,270421,,,N,V*1F
    $GNGGA,093210.58,,,,,0,00,99.0,,M,,M,,*4C
    $GNRMC,093211.58,V,,,,,,,270421,,,N,V*1E
    $GNGGA,093211.58,,,,,0,00,99.0,,M,,M,,*4D
    $GNRMC,093212.58,V,,,,,,,270421,,,N,V*1D
    $GNGGA,093212.58,,,,,0,00,99.0,,M,,M,,*4E
    $GNRMC,093213.58,V,,,,,,,270421,,,N,V*1C
    $GNGGA,093213.58,,,,,0,00,99.0,,M,,M,,*4F
    $GNRMC,093214.58,V,,,,,,,270421,,,N,V*1B
    $GNGGA,093214.58,,,,,0,00,99.0,,M,,M,,*48
    $GNRMC,093215.58,V,,,,,,,270421,,,N,V*1A
    $GNGGA,093215.58,,,,,0,00,99.0,,M,,M,,*49
    $GNRMC,093216.58,V,,,,,,,270421,,,N,V*19
    $GNGGA,093216.58,,,,,0,00,99.0,,M,,M,,*4A
    $GNRMC,093217.58,V,,,,,,,270421,,,N,V*18
    $GNGGA,093217.58,,,,,0,00,99.0,,M,,M,,*4B
    $GNRMC,093218.58,A,4713.692362,N,00133.688716,W,0.0,,270421,,,A,V*04
    $GNGGA,093218.58,4713.692362,N,00133.688716,W,1,06,2.1,33.3,M,,M,,*48
    $GNRMC,093219.57,A,4713.691725,N,00133.695061,W,0.5,,270421,,,A,V*00
    $GNGGA,093219.57,4713.691725,N,00133.695061,W,1,06,2.1,33$GNRMC,093220.57,A,4713.690230,N,00133.694088,W,0.2,,270421,,,A,V*0B
    $GNGGA,093220.57,4713.690230,N,00133.694088,W,1,06,2.1,34.3,M,,M,,*42
    $GNRMC,093221.57,A,4713.690674,N,00133.694167,W,0.6,213.8,270421,,,A,V*2C
    $GNGGA,093221.57,4713.690674,N,00133.694167,W,1,06,2$GNRMC,093222.00,A,4713.690116,N,00133.693416,W,0.1,,270421,,,A,V*0B
    $GNGGA,093222.00,4713.690116,N,00133.693416,W,1,06,2.1,34$GNRMC,093223.00,A,4713.689873,N,00133.693244,W,0.1,,270421,,,A,V*09

    You can see everything is fine until I get a fix, then some frames get truncated and filled with the next frame since end line char is missing.

    Any ideas?

  • Not sure I see exactly what the problem is, as I do not know what your expected output is.

    Anyway, if you can post your full code used for handling\printing the received frames, I may help you pinpoint the problem in the code.

  • Ok so let's recap:

    My GNSS module sends only 2 kind of NMEA frames (GGA and RMC), formatted this way:

    $GNGGA,093207.58,,,,,0,00,99.0,,M,,M,,*4A
    $GNRMC,093208.58,V,,,,,,,270421,,,N,V*16

    When there is not enough satellites signal, and this way:

    $GNRMC,131444.00,A,4713.689658,N,00133.702428,W,0.1,,280421,,,A,V*0A
    $GNGGA,131444.00,4713.689658,N,00133.702428,W,1,05,1.8,25.3,M,,M,,*46

    When satellites signal is good enough for location computation.

    This is the kind of frames I am supposed to receive all the time.

    Note that all these frames are ended by \r\n characters.

    First, I use this "raw" UART handler, only displaying received data:

    void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
    {
        nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
    
        switch(p_evt->type)
        { 
          case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
          {
              printf("%s",p_evt->data.rxtx.p_data);
              nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
          }break;
          case NRF_LIBUARTE_ASYNC_EVT_ERROR:
          {
              printf("\nUART ERROR: %d", p_evt->data.errorsrc);
          }break;
          case NRF_LIBUARTE_ASYNC_EVT_OVERRUN_ERROR:
          {
              printf("\nUART OVERRUN ERROR");
          }break;
        }
    }

    In this case this is what I get: 

    $GNGGA,000009.00,,,,,0,00,99.0,,M,,M,,*41
    $GNRMC,000001.00,V,,,,,,,020712,,,N,V*1E
    $GNGGA,000001.00,,,,,0,00,99.0,,M,,M,,*49
    $GNRMC,000002.00,V,,,,$GNRMC,000010.00,V,,,,,,,020712,,,N,V*1E
    $GNGGA,000010.00,,,,,0,00,99.0,,M,,M,,*49
    $GNRMC,000002.00,V,,,,,,,020712,,,N,V*1D
    $GNRMC,000011.00,V,,,,,,,020712,,,N,V*1F
    $GNGGA,000011.00,,,,,0,00,99.0,,M,,M,,*48
    $GNRMC,000003.00,V,,,,,,,020712,,,N,V*1C
    $GNRMC,000012.00,V,,,,,,,020712,,,N,V*1C
    $GNGGA,000012.00,,,,,0,00,99.0,,M,,M,,*4B
    $GNRMC,000004.00,V,,,,,,,020712,,,N,V*1B
    $GNGGA,000004.00,,,,,0,00,99.0,,M,,M,,*4C
    $GNRMC,000005.00,V,,,,$GNRMC,000013.00,V,,,,,,,020712,,,N,V*1D
    $GNGGA,000013.00,,,,,0,00,99.0,,M,,M,,*4A

    You can see the "ghost" effect I explained earlier, and truncated frames due to a lack of '\0' char at the end of the p_evt->data.rxtx.p_data buffer.

    So if I add \0 char then everythings looks fine again, wheither I add it in the handler this way:

    p_evt->data.rxtx.p_data[p_evt->data.rxtx.length] = '\0';

    Or by using a copy of the buffer to avoid messing up with the buffer index as you suggested:

    char frame_buffer[p_evt->data.rxtx.length+1];
    strncpy(frame_buffer,p_evt->data.rxtx.p_data,p_evt->data.rxtx.length);
    frame_buffer[p_evt->data.rxtx.length] = '\0';
    printf("%s",frame_buffer);

    In both these cases, I get correct frames:

    $GNRMC,131431.97,V,,,,,,,280421,,,N,V*1F
    $GNGGA,131431.97,,,,,0,04,13.9,,M,,M,,*4C
    $GNRMC,131432.97,V,,,,,,,280421,,,N,V*1C
    $GNGGA,131432.97,,,,,0,04,13.9,,M,,M,,*4F
    $GNRMC,131433.97,V,,,,,,,280421,,,N,V*1D
    $GNGGA,131433.97,,,,,0,04,13.9,,M,,M,,*4E
    $GNRMC,131434.97,V,,,,,,,280421,,,N,V*1A
    $GNGGA,131434.97,,,,,0,04,13.9,,M,,M,,*49

    But then If I get good sattelites signal, I start getting truncated frames again (whithout the "ghost" effect though):

    $GNRMC,131435.97,A,4713.690609,N,00133.699195,W,0.0,,280421,,,A,V*0F
    $GNGGA,131435.97,4713.690609,N,00133.699195,W,1,05,1.8,28$GNRMC,131436.97,A,4713.690288,N,00133.699073,W,0.1,,280421,,,A,V*09
    $GNGGA,131436.97,4713.690288,N,00133.699073,W,1,05,1.8,27.3,M,,M,,*47
    $GNRMC,131437.96,A,4713.690509,N,00133.700876,W,0.0,,280421,,,A,V*0A
    $GNGGA,131437.96,4713.690509,N,00133.700876,W,1,05,1.8,27$GNRMC,131438.96,A,4713.690116,N,00133.701570,W,0.1,,280421,,,A,V*04
    $GNGGA,131438.96,4713.690116,N,00133.701570,W,1,05,1.8,27.3,M,,M,,*4A
    $GNRMC,131440.00,A,4713.689887,N,00133.701877,W,0.5,,280421,,,A,V*03
    $GNGGA,131440.00,4713.689887,N,00133.701877,W,1,05,1.8,26$GNRMC,131441.00,A,4713.689844,N,00133.701963,W,0.8,357.8,280421,,,A,V*23
    $GNGGA,131441.00,4713.689844,N,00133.701963,W,1,05,1.8,26.3,M,,M,,*42
    $GNRMC,131442.00,A,4713.689644,N,00133.702321,W,0.2,,280421,,,A,V*0C
    $GNGGA,131442.00,4713.689644,N,00133.702321,W,1,05,1.8,25$GNRMC,131443.00,A,4713.689508,N,00133.702514,W,0.4,,280421,,,A,V*00
    $GNGGA,131443.00,4713.689508,N,00133.702514,W,1,05,1.8,24.3,M,,M,$GNRMC,131444.00,A,4713.689658,N,00133.702428,W,0.1,,280421,,,A,V*0A
    $GNGGA,131444.00,4713.689658,N,00133.702428,W,1,05,1.8,25.3,M,,M,,*46
    You can see that frames are truncated when there is "$GNRMC" or "$GNGGA" in a middle of a line instead of the begining of a new line as it should. When this occurs then the previous frame is cut.

  • Sorry for the slow response. Have you tried increasing the number of buffers for the libUARTE library (last argument to NRF_LIBUARTE_ASYNC_DEFINE), or the size of the buffers? If you do not free the buffers back to the library fast enough, you may get behavior like this.

  • Hi,

    Increasing the number of buffers makes no difference. It seems like my problem could indeed be solved by increasing the size of the buffer, but size above 255 is not supported. Where does this 255 bytes limit comes from? Would there be a way to bypass this limit?

    Best regards

Related