AnsweredAssumed Answered

Best way to bridge two UARTs?

Question asked by Robert York on Jul 15, 2015
Latest reply on Jul 22, 2015 by Robert York

I have an application where I have a K70 running MQX 4.1, with Codewarrior 10.6. On one UART, I have a console I connect to my PC. Through this I can send commands to a shell I've written. On another UART on the K70, I've connected an embedded linux computer, right into it's console. Eventually, I'll likely have my K70 build its own commands and send them into the linux console, and parse the outputs. But for now, I would like to be able to slave the one UART connected to the PC right over to the linux UART, so I can just use the same serial connection to the computer to jump into the linux console. I don't need to be able to get back out for now. Something like this pseudo-code below:

 

while(1)

{

     // Take chars in from uart 0 and put them into uart 1

     in0 = fgetc(p_uart0)

     fputc(in0, p_uart1)

 

     // Take chars from uart 1 and put them into uart 0

     in1 = fgetc(p_uart1)

     fputc(in1, p_uart0)

}

 

First off, lets not get caught up in semantics. This is just pseudo-code. I also don't ever need to exit at this point.

 

The first challenge is of course the blocking nature of fgetc(). Even when opening the file pointer as IO_SERIAL_NON_BLOCKING, it still blocks. No idea why. For the curious, or those who think fixing this may be the solution, here's what I use to initialize the pointer:

 

p_uart0 = fopen("ittye:", BSP_DEFAULT_IO_OPEN_MODE);

ioctl(p_uart0 , IO_IOCTL_SERIAL_SET_FLAGS, (void *)(IO_SERIAL_TRANSLATION | IO_SERIAL_NON_BLOCKING));

 

Another challenge is that input and output could happen entirely asynchronously. Input could come in at any time from either source, and output returned could take some indeterminate amount of time. So it's hard to have one task just piping data from one port into the other, without pausing for other tasks to watch the other port.

 

I basically just want it to check if it's gotten a character in a buffer from one UART, and if so, throw it in the output of the other, and vice versa. It seems like the pseudo-code should work, but (probably due to the blocking nature of serial port drivers in MQX), it won't.

 

If we can't get around the blocking fgetc(), another implementation is what I've done with my K70's shell; set up tasks to continually poll the UARTs, buffer characters, and let another task pull off captured data and forward it along. I thought this is what the interrupt driven UART drivers in MQX were for? To re-invent this seems, frankly, to be ridiculously complex for what I'm trying to do, and the purist in me seems there should be a way to make the something more like the pseudo-code above, work.

 

Any thoughts or suggestions would be appreciated.

Outcomes