5 years, 7 months ago.

Best solution for serial input / SerialBase vs. RawSerial vs. Serial

Hello, I kindly ask for help regarding serial input.

I use an mbed_LPC1768. What I want to do is:

  • Read blocks of bytes from an external device. The lengths of the blocks aren't fixed as they may contain escape sequences, they are about 20+.
  • As the baud rate is 115200 and I don't want to have too many interrupts I search for a non blocking serial read for a whole block.
  • The blocks start with STX and end with ETX, data 0x02 or 0x03 inside a block are escaped, that means ETX (and STX) will never come as data.

Looking at SerialBase::read(...) in combination with SerialBase::set_dma_usage_rx(...) is encouraging, but I cannot interpret the documentation as desired as it is extremely short and really not easy to understand.

Details:

  • What does "asynchronous" (in the description of read()) mean in this context? Does it mean nonblocking, as used in "Configure DMA usage suggestion for non-blocking RX transfers."?
  • What does the parameter "char_match" do? Does it complete a read operation when it is received? Can I use this parameter to detect an end-of-block (and return from the read call) when ETX is read?
  • How would I have to use set_dma_usage_rx(DMAUsage usage)? Searching for "DMAUsage" doesn't help.
  • When would I have to call set_dma_usage_rx? After calling read or after instantiating the UART or in any other way?
  • I think I would have to program a timeout to detect an IDLE condition by myself?

If a solution like the one sketched above wouldn't work:

  • How "expensive" (in terms of interrupts and runtime) would be a getc()-solution? Such a solution would be more expensive than a read/set_dma_usage_rx combination but would have the advantage that I could resolve escaped characters immediately (ESC-STX, ESC-ETX and ESC-ESC) and that I could immediately "fish" the few bytes of the block I'm interested in. But I would have to serve an interrupt any 90 microseconds during the time interval when a burst comes in.
  • How would I have to respond to a call of my interrupt service function which I attached to an instance of SerialBase (or RawSerial)? Would it be sufficient to instanciate the UART (Rx only) and attach a reader function, which does all the rest? Would I just have to check readable() and call getc()? Or is it more complex?

What is the difference between Serial and RawSerial? The question sounds at least ...funny, but there is only one difference in the descriptions: Serial uses streams, RawSerial doesn't - I don't understand what that means.

Where can I read a good "How To" about serial data input?

Kind regards, Helmut

Question relating to:

1 Answer

5 years, 7 months ago.

SerialBase is not intended to be used directly. The other Serials inherit from this.

Problem with Stream is that when using RTOS it does not allow for using putc/getc in an interrupt routine, which makes serial interrupts useless. RawSerial circumvents that.

Second problem: The whole DMA part is not available for the LPC1768. With your requirements I would have a look at MODSERIAL, which does work on the LPC1768, is non-blocking, and allows you also to set stuff like interrupts when an incoming char matches something (although that won't work with DMA, but it can also be used with DMA). (Google MODSERIAL and mbed, since the mbed search is broken).

Accepted Answer