SerialBuffered

SerialBuffered is a helpful class which wraps Serial and provides read buffering and timeouts.

 

I built it to deal with a serial camera, which spits out whole images as a single serial stream, and which I wanted to run at the highest baud rate possible. I had an implementation which used Serial, but I found that I often dropped incoming bytes if (for example) I did any debug logging at all. During  the time the logging was doing its work, the mbed had filled its hardware buffer (which is only 16 bytes) and data was being lost.

 

SerialBuffered uses an interrupt handler, so it will catch data at all times. It maintains a circular buffer to store the stuff in. The buffer size is up to the caller, but it needs to be at least as big as the largest backlog of inbound data that will ever occur.

 

For the camera example, I set the buffer to be as large as a whole image frame, which was the worst possible case. If you are pushed for memory, you may want to experiment to find the smallest buffer that works for you reliably.

 

It also provides timeouts, which by default are set to 1 second. SerialBuffered::getc() will return -1 when it has failed to read because a timeout intervened. I found that debugging was a lot less painful when my app timed out when I made a mistake, instead of hanging up in a plain getc().

 

Here's the code, and a tiny test app to illustrate usage:

SerialBufferedDemo

To move your project from Serial to SerialBuffered, just add the .cpp and .h to your project, and change Serial to SerialBuffered in your variable declarations. You will also want to add a check for -1 to the return value from getc().

 

If you're reading in a block of bytes, you may want to use the handy readBytes method, which will read in a whole bufferful of bytes for you in one go.


12 comments

05 Dec 2009

Does this have the ability to do a buffered transmit as well as receive?

thanks.

Ian.

05 Dec 2009

No, this only adds buffering to receive.

 

It would be easy to add a send buffer and a ticker to do the sending, if you also needed buffered send.

Ideally you'd use an interrupt on the UART rather than a timer - Simon did say somethign about that as a possibility, but I am not sure if that's implemented or not.

 

Richard

05 Dec 2009

The best would probably be to use DMA which the LPC1768 has. See AN10850.

The LPC1700 features a DMA controller that has the ability to transfer data from memory-to-memory, memory-to-peripheral, peripheral-to-peripheral, and peripheral-to-memory.
Using all eight of its channels, the DMA can transfer eight simultaneous 32-bit wide words at a given time.
Some of the peripherals that are supported by the DMA include the SSP, I2S, UART, A/D Converter, and the D/A Converter. For the DMA controller, the GPIO registers are considered as “memory” sources/destinations. For example, to have the DMA copy data from the internal SRAM to the GPIOs, it needs to be configured for a memory-to-memory transfer.
The LPC1700’s DMA controller has scatter (or gather) support. This new feature allows the DMA to transfer a non-contiguous block of memory with the guidance of a linked list data structure.

05 Dec 2009

Igor - is that kind of thing even available to programs written in the mbed compiler ? I'm not at all clear how much we can do.

 

R.

 

05 Dec 2009

Hi Richard,

To be clear, you can do what you want! Poke the peripheral registers directly if you feel the need! The libraries are there for the common case, but can be suplemented by totally bespoke LPC1768 C code if you want.

I'll aim to start writing some tutorials in the future to help explain all this, but obviously our priority up until now (and for the near future) has been to create something worthy of explaining!

Simon

06 Dec 2009

Simon - thanks - that's good to know, and I totally understand your priorities.

 

There's another question that has been wandering about in the back of my mind - if I want to do something ambitious which really requires using a debugger, I know I can't do it with the mbed compiler.

But can I do it with the mbed hardware and some kind of debugger pod, along with a third-party toolchain ? I guess that you must use something along those lines, but i don;'t know enough about ARM tools to know what kind of pod would be required.

 

Thanks,

 

Richard

06 Dec 2009

Hi Richard,

No, there is no support for using a debugger with mbed hardware at the moment.

Simon

06 Dec 2009

Thanks. Just for the sake of my curiosity, what do you use for development of the libraries & so on ?

 

Richard

06 Dec 2009

For the mbed libraries, we use the mbed compiler. Eat your own dogfood!

For the mbed interface chip, we use Keil uVision (that is more suited to the complex custom USB/JTAG/real-time productised solution needed here)

06 Dec 2009

Well, at least I know you have an incentive to make debugging easy... :-)

 

thanks,

 

R.

29 Mar 2010

Hi Richard,

Is there any way to know when data is available in the buffer? Let's say I have packets coming in of different sizes and I just want to read them without iterating the whole buffer (I want to read only the bytes that are available).

Thank you,

Abraham

21 Jun 2010

With the latest library update (http://mbed.org/blog/entry/Library-Update-CAN-Serial-transmit-and-1/), serial now adds attach to the transmit side. Anyone done buffered serial transmit with it?

You need to log in to post a comment