c++ सीरियल पोर्ट से पूरा संदेश पार्स करना




gps serial-port (2)

छोटे बाइट संख्याओं के कई पढ़ने () सिस्क्लों को बनाने के ओवरहेड को कम करने के लिए, अपने कोड में एक मध्यवर्ती बफर का उपयोग करें।
शून्य बाइट्स के रिटर्न कोड से बचने के लिए पढ़ने () एस ब्लॉकिंग मोड में होना चाहिए।

#define BLEN    1024
unsigned char rbuf[BLEN];
unsigned char *rp = &rbuf[BLEN];
int bufcnt = 0;

static unsigned char getbyte(void)
{
    if ((rp - rbuf) >= bufcnt) {
        /* buffer needs refill */
        bufcnt = read(fd, rbuf, BLEN);
        if (bufcnt <= 0) {
            /* report error, then abort */
        }
        rp = rbuf;
    }
    return *rp++;
}

सीरियल टर्मिनल के लिए उचित टर्मिओस आरंभीकरण कोड के लिए, यह उत्तर देखें। आपको वीएमिन पैरामीटर को BLEN मान के करीब कुछ में बढ़ाना चाहिए।

अब आप न्यूनतम प्रदर्शन जुर्माना के साथ एक बार प्राप्त किए गए डेटा को आसानी से एक्सेस कर सकते हैं।

#define MLEN    1024  /* choose appropriate value for message protocol */
unsigned char mesg[MLEN];

while (1) {
    while (getbyte() != 0xB5)
        /* hunt for 1st sync */ ;
retry_sync:
    if ((sync = getbyte()) != 0x62) {
        if (sync == 0xB5)
            goto retry_sync;
        else    
            continue;    /* restart sync hunt */
    }

    class = getbyte();
    id = getbyte();

    length = getbyte();
    length += getbyte() << 8;

    if (length > MLEN) {
        /* report error, then restart sync hunt */
        continue;
    }
    for (i = 0; i < length; i++) {
        mesg[i] = getbyte();
        /* accumulate checksum */
    }

    chka = getbyte();
    chkb = getbyte();
    if ( /* valid checksum */ ) 
        break;    /* verified message */

    /* report error, and restart sync hunt */
}

/* process the message */
switch (class) {
case 0x02:
    if (id == 0x13) {
        ... 
...

मैं सीरियल पोर्ट के माध्यम से अपने जीपीएस से पूरा संदेश पढ़ने की कोशिश कर रहा हूं

जो संदेश मैं देख रहा हूँ वह इस प्रकार से शुरू होता है:

0xB5 0x62 0x02 0x13

तो मैं सीरियल पोर्ट से इतना पढ़ता हूं

while (running !=0)
{

int n = read (fd, input_buffer, sizeof input_buffer); 


for (int i=0; i<BUFFER_SIZE; i++)
{   



if (input_buffer[i]==0xB5  && input_buffer[i+1]== 0x62 && input_buffer[i+2]== 0x02 && input_buffer[i+3]== 0x13    && i<(BUFFER_SIZE-1) )
     { 

            // process the message.
     }

}

मुझे जो समस्या है वह है कि मुझे पूरा संदेश प्राप्त करने की आवश्यकता है संदेश का आधा बफर एक चलना में हो सकता है और दूसरे आधे संदेश अगले आवृत्ति में आ सकता है।

किसी ने सुझाव दिया है कि बफर को पूर्ण संदेश से मुक्त करें और फिर मैं बाकी बफ़र में डेटा को बफर की शुरुआत में ले जाता हूं।

मैं यह कैसे कर सकता हूँ या किसी अन्य तरीके से यह सुनिश्चित कर सकता हूं कि मुझे पूरा पूरा संदेश मिल जाए?

संपादित //

मुझे एक विशेष वर्ग और आईडी चाहिए लेकिन मैं लंबाई में भी पढ़ सकता हूं


आप तीन भागों में पढ़ने को तोड़ सकते हैं किसी संदेश की शुरूआत खोजें फिर LENGTH प्राप्त करें फिर बाकी संदेश पढ़ें।

// Should probably clear these in case data left over from a previous read
input_buffer[0] = input_buffer[1] = 0;

// First make sure first char is 0xB5
do {
    n = read(fd, input_buffer, 1); 
} while (0xB5 != input_buffer[0]);

// Check for 2nd sync char
n = read(fd, &input_buffer[1], 1);

if (input_buffer[1] != 0x62) {
     // Error
     return;
}

// Read up to LENGTH
n = read(fd, &input_buffer[2], 4); 

// Parse length
//int length = *((int *)&input_buffer[4]);
// Since I don't know what size an int is on your system, this way is better
int length = input_buffer[4] | (input_buffer[5] << 8);

// Read rest of message
n = read(fd, &input_buffer[6], length);

// input_buffer should now have a complete message

आपको त्रुटि जांचना चाहिए ...





uart