serial line ringbuf implementation + increased default buffer size to 128 bytes

This commit is contained in:
fros4943 2009-10-27 16:20:31 +00:00
parent edd94c00b0
commit 6f4a537aa0

View file

@ -28,23 +28,29 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* @(#)$Id: serial-line.c,v 1.1 2009/03/17 15:56:33 adamdunkels Exp $ * @(#)$Id: serial-line.c,v 1.2 2009/10/27 16:20:31 fros4943 Exp $
*/ */
#include "dev/serial-line.h" #include "dev/serial-line.h"
#include <string.h> /* for memcpy() */ #include <string.h> /* for memcpy() */
#include "lib/ringbuf.h"
#ifdef SERIAL_LINE_CONF_BUFSIZE #ifdef SERIAL_LINE_CONF_BUFSIZE
#define BUFSIZE SERIAL_LINE_CONF_BUFSIZE #define BUFSIZE SERIAL_LINE_CONF_BUFSIZE
#else /* SERIAL_LINE_CONF_BUFSIZE */ #else /* SERIAL_LINE_CONF_BUFSIZE */
#define BUFSIZE 80 #define BUFSIZE 128
#endif /* SERIAL_LINE_CONF_BUFSIZE */ #endif /* SERIAL_LINE_CONF_BUFSIZE */
#if (BUFSIZE & (BUFSIZE - 1)) != 0
#error SERIAL_LINE_CONF_BUFSIZE must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...).
#error Change SERIAL_LINE_CONF_BUFSIZE in contiki-conf.h.
#endif
#define IGNORE_CHAR(c) (c == 0x0d) #define IGNORE_CHAR(c) (c == 0x0d)
#define END 0x0a #define END 0x0a
static char buffer[BUFSIZE], appbuffer[BUFSIZE]; static struct ringbuf rxbuf;
static volatile unsigned char bufwptr; static uint8_t rxbuf_data[BUFSIZE];
static volatile char buffer_full = 0;
PROCESS(serial_line_process, "Serial driver"); PROCESS(serial_line_process, "Serial driver");
@ -55,18 +61,31 @@ process_event_t serial_line_event_message;
int int
serial_line_input_byte(unsigned char c) serial_line_input_byte(unsigned char c)
{ {
if(!buffer_full && !IGNORE_CHAR(c)) { static uint8_t overflow = 0; /* Buffer overflow: ignore until END */
if(c == END) {
/* terminate the string */ if(!IGNORE_CHAR(c)) {
buffer[bufwptr++] = '\0'; if(!overflow) {
buffer_full++; /* Add character */
process_poll(&serial_line_process); if(ringbuf_put(&rxbuf, c) == 0) {
return 1; /* Buffer overflow: ignore the rest of the line */
overflow = 1;
process_poll(&serial_line_process);
}
} else {
/* Buffer overflowed:
* Only (try to) add terminator characters, otherwise skip */
if(c == END && ringbuf_put(&rxbuf, c) != 0) {
overflow = 0;
} else {
process_poll(&serial_line_process);
}
} }
/* reserve space for the terminating zero character */ if(c == END && !overflow) {
if(bufwptr < (BUFSIZE - 1)) { /* Tell process at least one (potentially cropped due to overflow)
buffer[bufwptr++] = c; * line exists in the buffer */
process_poll(&serial_line_process);
return 1;
} }
} }
return 0; return 0;
@ -74,21 +93,40 @@ serial_line_input_byte(unsigned char c)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_line_process, ev, data) PROCESS_THREAD(serial_line_process, ev, data)
{ {
static char buf[128];
static int ptr;
PROCESS_BEGIN(); PROCESS_BEGIN();
bufwptr = 0;
buffer_full = 0;
serial_line_event_message = process_alloc_event(); serial_line_event_message = process_alloc_event();
ptr=0;
while(1) { while(1) {
PROCESS_YIELD();
if(buffer_full) { /* Fill application buffer until newline or empty */
memcpy(appbuffer, buffer, bufwptr); int c = ringbuf_get(&rxbuf);
process_post(PROCESS_BROADCAST, serial_line_event_message, appbuffer); if(c == -1) {
bufwptr = 0; /* Buffer empty, wait for poll */
buffer_full = 0; PROCESS_YIELD();
} else {
if(c != END) {
buf[ptr++] = (uint8_t)c;
} else {
/* Terminate */
buf[ptr++] = (uint8_t)'\0';
if (ptr > 1) {
/* Broadcast event */
process_post(PROCESS_BROADCAST, serial_line_event_message, buf);
/* Wait until all processes have handled the serial line event */
if(PROCESS_ERR_OK ==
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL)) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE);
}
}
ptr = 0;
}
} }
} }
@ -98,6 +136,7 @@ PROCESS_THREAD(serial_line_process, ev, data)
void void
serial_line_init(void) serial_line_init(void)
{ {
ringbuf_init(&rxbuf, rxbuf_data, sizeof(rxbuf_data));
process_start(&serial_line_process, NULL); process_start(&serial_line_process, NULL);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/