3

I'm writing my own drivers for LPC2148 and a question came to mind. How do I receive a message of unspecified size in UART?

The only 2 things that come to mind are: 1 - Configure a watchdog and end the receiving when the time runs out. 2- make it so that whenever a meswsage is sent to it there must be an end of message character.

The first choice seems better in my opinion, but I'd like to know if anybody has a better answer, and I know there must be.

Thank you very much

Nico Erfurth
  • 3,362
  • 22
  • 26
morcillo
  • 1,091
  • 5
  • 19
  • 51

5 Answers5

8

Just give the caller whatever bytes you have received so far. The UART driver shouldn't try to implement the application protocol, the application should do that.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
3

It looks like a wrong use for a watchdog. I ended up with three solutions for this problem:

  1. Use fixed-size packets and DMA; so, you receive one packet per transaction. Apparently, it is not possible in your case.
  2. Receive message char-by-char until the end-of-message character is received. Kind of error-prone, since the EOM char may appear in the data, probably.
  3. Use a fixed-size header before every packet. In the header, store payload size and/or message type ID.

The third approach is probably the best one. You may combine it with the first one, i.e. use DMA to receive header and then data (in the second transaction, after the data size is known from the header). It is also one of the most flexible approaches.

One more thing to worry about is to keep bytestream in sync. There may be rubbish laying in the UART input buffers, which may get read as data, or you can get only a part of a packet after your MCU is powered (i.e. the beginning of the packet had already been sent by that time). To avoid that, you can add magic bytes in your packet header, and probably CRC.

EDIT

OK, one more option :) Just store everything you receive in a growing buffer for later use. That is basically what PC drivers do.

Roman Dmitrienko
  • 3,375
  • 3
  • 37
  • 48
  • I liked your answers, but I was going for something even more generic. Example: receive an unknown size string without end of message and without any kind of headers. When the case is a protocol (modbus, etc) it`s very easy to receive n bytes because there is a file for that, but my question was for unknown sizes since I`ve always wondered how a PC´s serial por works, it can receive any string of any size without any kind of header and it still works everytime – morcillo Dec 27 '12 at 06:10
  • @morcillo Edited :) Seriously, you can take a look at the Linux UART drivers. They are not really obvious and simple, though. You don't need most of that in an embedded system. – Roman Dmitrienko Dec 27 '12 at 06:14
  • 1
    I know an embedded system doesn't need that. But I've always wanted to learn how it does it. But thank you, you've been of great help – morcillo Dec 28 '12 at 03:35
  • I would put another approach. You can start a timer and each byte received, reset this timer. If the timer reach some threshold, you admit that there's no more data to receive. It's a kind of timeOuted approach. – Leandro Lima Dec 05 '13 at 20:20
2

Real embedded uart drivers usually use a ring buffer. Bytes are stored in order and the clients promise to read from the buffer before it's full. A state machine can then process the message in multiple passes with no need for a watchdog to tell it reception is over

0

better to go for option 2) append end of transmission character to the transmission string.

but i suggest to add start of transmission also to validate that you are receiving actual transmission.

Kinjal Patel
  • 405
  • 2
  • 7
0

Watchdog timer is used to reset system when there is a unexpected behavior of device. I think it is better to use a buffer which can store size of data that your application requires.

linuxchip
  • 316
  • 1
  • 5