arnaud405 wrote:
the int check_speed is 1 when it is already gone in the other message. The problem is that it never goes in this condition because the buffer always get the GPGGA message (because of the LR terminator maybe).
I don't understand the significance of check_speed, and I really don't care As I see it, and tried to explain in my previous post about layering the code, you have to separate functionality. I would not combine a test of the receive state or condition with parsing the input.
I'd setup the UART/USART Rx ISR to store all received bytes in a large ring buffer and wake up an input task. This ISR level can handle either binary or text input from the serial line.
The input task would respond to an application getline() request by filling the supplied buffer with the received string extracted from the ring buffer. The input line is delimited by a \n, so all received input since the last getline() request is returned on this call (with all ASCII control chars stripped out) as a null-terminated string. This level handles the serial input as a text stream, and only breaks up the input into variable-length text records aka lines.
At the application level, which is aware of the message format
Code:
retstatus = getline(linebuf);
/* search for preamble '$' character */;
if ((lstartp = strchr(linebuf, '$')) == NULL) {
...
}
/* search for comma delimiter following keyword */
if ((endkeyp = strchr(lstartp, ',')) == NULL) {
...
}
/* extract message keyword string from line buffer */
strncpy(src_key, lstartp + 1, endkeyp - lstartp - 1);
To parse input that has keywords to identify the message, I'd define a set of message identifiers:
Code:
typedef enum { /* received message types */
MT_NULL = 0,
MT_GPGSV = 1,
MT_GPVTG,
MT_GPGLL,
MT_GPRMC,
MT_GPGGA
} mesg_t;
And also define the comparison table for identifying the received keywords:
Code:
typedef struct mesg_def {
mesg_t mesg_id;
char *keywd;
} mesg_def_t;
mesg_def_t mesg_keyword[] = {
{MT_GPGSV, "GPGSV"},
{MT_GPVTG, "GPVTG"},
{MT_GPGLL, "GPGLL"},
{MT_GPRMC, "GPRMC"},
{MT_GPGGA, "GPGGA"},
{MT_NULL, ""}
};
Compare the received keyword string to the list of valid keys using a string comparison routine:
Code:
kwp = mesg_keyword;
mtype = MT_NULL;
do {
if (strcmp(src_key, kw->keywd) == 0) {
mtype = kwp->mesg_id);
break;
}
++kwp;
} while (kwp->mesg_id != MT_NULL);
Once the message type has been identified, then the message contents can be processed:
Code:
switch (mtype) {
case MT_NULL:
default:
/* need to handle unknown message type gracefully */
break;
case MT_GPGSV: /* GSV message */
break;
case MT_GPVTG: /* VTG message */
if (check_speed == 1) { /* */
...
} else {
...
}
break;
case MT_GPGLL: /* GLL message */
break;
case MT_GPRMC: /* RMC message */
break;
case MT_GPGGA: /* GGA message */
break;
}