Author Topic: ChibiOS Event listener losing data  (Read 5428 times)

0 Members and 1 Guest are viewing this topic.

Offline TorrentulaTopic starter

  • Regular Contributor
  • *
  • Posts: 91
  • Country: de
    • My blog
ChibiOS Event listener losing data
« on: September 05, 2013, 12:08:52 pm »
Hello ChibiOS users!

I'm currently trying to read NMEA data from a GPS module (9600 baud 8N1) and have some trouble reading the data correctly. It seems that I am losing data from the serial port and I don't know why. My event listener thread looks like this:
Code: [Select]
static msg_t Thread6(void *arg)
{
(void)arg;
chRegSetThreadName("GPSdata");

// Activates the Serial driver 2, PA2(TX) and PA3(RX) are routed to USART2, 9600 8N1.
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
sdStart(&SD2, NULL);

EventListener elGPSdata;
        flagsmask_t flags;
chEvtRegisterMask((EventSource *)chnGetEventSource(&SD2), &elGPSdata, EVENT_MASK(1));

        while (TRUE)
{

chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));
chSysLock();
flags = chEvtGetAndClearFlagsI(&elGPSdata);
                chSysUnlock();

if ( flags & 128 )
{
chprintf((BaseSequentialStream*)&SDU1, "%c", chnGetTimeout(&SD2, TIME_IMMEDIATE));
}
}

return 0;
}

As you can see I'm currently just reading the data from serial port 2 (USART2) one character at a time as soon as an event fires.

I'm a bit lost when it comes to the ChibiOS documentation as I have no idea how to really check what the value of flags should be when there is a character available. The value of 128 I got by observation (printing flags along with read character).
If this is because I don't understand the fundamental concepts of the events in ChibiOS then please feel free to educate me...

(BTW I couldn't register in the ChibiOS support forum, otherwise I would've asked there)
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: ChibiOS Event listener losing data
« Reply #1 on: September 05, 2013, 03:34:33 pm »
You should figure out how to register on the ChibiOS forum because Giovanni could probably point out the issue with your code in five minutes. He's very helpful with those kinds of things.

I haven't used events with serial drivers, but here's a thought... It could be that the serial driver's internal buffer is overflowing because your code doesn't read all the available data each time it gets an event notification. I.e., you're only reading one character, but there may be more in the driver's buffer.

BTW, is there a reason you're not using chSequentialStreamGet(BaseSequentialStream *)? It returns a single character from the driver's buffer and blocks the calling thread if there's no data.

Code: [Select]
static msg_t Thread6(void *arg)
{
(void)arg;
chRegSetThreadName("GPSdata");

// Activates the Serial driver 2, PA2(TX) and PA3(RX) are routed to USART2, 9600 8N1.
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
sdStart(&SD2, NULL);

        while (TRUE)
{
char c = chSequentialStreamGet(&SD2);
chprintf((BaseSequentialStream *) &SDU1, "%c", c);
}

return 0;
}
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: ChibiOS Event listener losing data
« Reply #2 on: September 06, 2013, 07:53:39 am »
Also, shouldn't you be using chEvtGetAndClearFlags instead of chEvtGetAndClearFlagsI? Since you are using it from a loop in a thread, as opposed to an interrupt handler.
« Last Edit: September 06, 2013, 08:10:54 am by mrflibble »
 

Offline TorrentulaTopic starter

  • Regular Contributor
  • *
  • Posts: 91
  • Country: de
    • My blog
Re: ChibiOS Event listener losing data
« Reply #3 on: September 07, 2013, 07:52:35 am »
Quote
Also, shouldn't you be using chEvtGetAndClearFlags...
Yes I should, corrected.

Okay I finally managed to register on the ChibiOS forum and sure enough Giovanni provided help, almost instantly  :-+

Here is the code if anyone is interested:
Code: [Select]
static msg_t Thread6(void *arg)
{
(void)arg;
chRegSetThreadName("GPSdata");

// Activates the Serial driver 2, PA2(TX) and PA3(RX) are routed to USART2, 9600 8N1.
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
sdStart(&SD2, NULL);

EventListener elGPSdata;
flagsmask_t flags;
chEvtRegisterMask((EventSource *)chnGetEventSource(&SD2), &elGPSdata, EVENT_MASK(1));

while (TRUE)
{
chEvtWaitOneTimeout(EVENT_MASK(1), MS2ST(10));
chSysLock();
flags = chEvtGetAndClearFlags(&elGPSdata);
chSysUnlock();

if (flags & CHN_INPUT_AVAILABLE)
{
msg_t charbuf;
do
{
charbuf = chnGetTimeout(&SD2, TIME_IMMEDIATE);
if ( charbuf != Q_TIMEOUT )
{
chprintf((BaseSequentialStream*)&SDU1, "%c", (char)charbuf);
}
}
while (charbuf != Q_TIMEOUT);
}
}

return 0;
}

The if-statement in the do-while loop just prevents the Q_TIMEOUT flag being printed to the debug output.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf