Page 1 of 2

Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 8:13 am
by carldong
I am looking for a good way to "link" two serial devices. Say, SDU1 and SD1, so that a board acts like a USB-TTL translator. I am stuck looking for a way to implement this elegantly. Currently I can only think about polling byte by byte and transfer them in an infinite loop, but that doesn't feel very elegant...

Searching the API, I didn't find an existing way to create data pipes between devices(maybe I missed something). MemoryStream looks something like what I want, but I am not quite sure(I will be testing it). It seems that streams can only be read into memory buffers, but not another stream.

What are some good ways to implement this?

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 8:56 am
by Giovanni
Hi,

Both SDs and SDUs implement their own buffering mechanism, you could have a single loop waiting for the RX/TX events from the ports and doing transfers. The loop would sleep inside chEvtWaitxxx() when there is no data to transfer.

Giovanni

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 6:43 pm
by carldong
Do you mean that I need two threads? I have not used Events before, but there doesn't seem like RX/TX are sending any of these. Does that mean I need to add events into the LLD?

And which section of the document should I look at?

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 8:14 pm
by carldong
After digging some docs, I found that it seems to require 2 threads for the event method. I will try this first, but is it possible to do the same in one thread, while not hard blocking others?

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 9:57 pm
by Giovanni
All time spent waiting for events will be available to other threads. I think you can use a single thread waiting for four events (RX and TX for both sides).

Giovanni

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 11:09 pm
by carldong
Can I wait for multiple events at the same time? I don't quite understand what those eventid_t parameters are assigned. Do I assign an arbitrary number to the ID, and use something like chEvtWaitAny? Does this mean I can have at most 32 events registered on a specific source?

Currently I am using a dumb solution:

Code: Select all

static uint8_t pipeByte(BaseChannel *chp1, BaseChannel *chp2) {
  int8_t b;
  b = chnGetTimeout(chp1, TIME_IMMEDIATE);
  if (b != STM_RESET && b != STM_TIMEOUT) {
    chnPutTimeout(chp2, b, TIME_IMMEDIATE);
  }
  /* ETX.*/
  if (b == 0x03) {
    return 1;
  }
  return 0;
}


Of course, it blocks every other threads. For my application it is fine, but I don't like it...

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 11:11 pm
by Giovanni
Correct, you have to use chEvtWaitAny(), you can register on up to 32 distinct sources and wait for any of those to be signaled.

Events are meant to be used when you need to wait for multiple sources.

Giovanni

Re: Is there a good way to pipe two serial devices?

Posted: Mon Feb 20, 2017 11:33 pm
by carldong
Ah, I see. So it looks like I don't need to spawn new threads. I will try that, too.

Re: Is there a good way to pipe two serial devices?

Posted: Fri Mar 03, 2017 12:07 am
by carldong
Actually, I found the document always says something like this:

mask -- the event flags set to be ORed.

Do you mean ANDed? OR doesn't make sense to me, since ORing 0 is not modifying the flag set at all.

Re: Is there a good way to pipe two serial devices?

Posted: Fri Mar 03, 2017 8:48 am
by Giovanni
It is correct, generating an event means setting a bit in the mask to 1.

Giovanni