|
| 1 | +// Transfer bidirectional data between two ports, acting as a virtual link. |
| 2 | +// poll() is used to monitor both ports for input. |
| 3 | +#include "mbed.h" |
| 4 | + |
| 5 | +// Pins for each port are specified using mbed_app.json. Assume no flow control. |
| 6 | +// (If there were flow control, being blocked by it could break the implementation, |
| 7 | +// as you would stop reading input in the opposite direction). |
| 8 | +BufferedSerial device1(MBED_CONF_APP_UART1_TX, MBED_CONF_APP_UART1_RX); |
| 9 | +BufferedSerial device2(MBED_CONF_APP_UART2_TX, MBED_CONF_APP_UART2_RX); |
| 10 | + |
| 11 | +// Precondition: "in" is readable |
| 12 | +static void copy_some(FileHandle *out, FileHandle *in) |
| 13 | +{ |
| 14 | + // To ensure performance, try to read multiple bytes at once, |
| 15 | + // but don't expect to read many in practice. |
| 16 | + char buffer[32]; |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | + // Despite the FileHandle being in its default blocking mode, |
| 21 | + // read() must return immediately with between 1-32 bytes, as |
| 22 | + // you've already checked that `in` is ready with poll() |
| 23 | + ssize_t read = in->read(buffer, sizeof buffer); |
| 24 | + if (read <= 0) { |
| 25 | + error("Input error"); |
| 26 | + } |
| 27 | + |
| 28 | + // Write everything out. Assuming output port is same speed as input, |
| 29 | + // and no flow control, this may block briefly but not significantly. |
| 30 | + ssize_t written = out->write(buffer, read); |
| 31 | + if (written < read) { |
| 32 | + error("Output error"); |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +int main() |
| 37 | +{ |
| 38 | + pollfh fds[2]; |
| 39 | + |
| 40 | + fds[0].fh = &device1; |
| 41 | + fds[0].events = POLLIN; |
| 42 | + fds[1].fh = &device2; |
| 43 | + fds[1].events = POLLIN; |
| 44 | + |
| 45 | + while (1) { |
| 46 | + // Block indefinitely until either of the 2 ports is readable (or has an error) |
| 47 | + poll(fds, 2, -1); |
| 48 | + |
| 49 | + // Transfer some data in either or both directions |
| 50 | + if (fds[0].revents) { |
| 51 | + copy_some(fds[1].fh, fds[0].fh); |
| 52 | + } |
| 53 | + if (fds[1].revents) { |
| 54 | + copy_some(fds[0].fh, fds[1].fh); |
| 55 | + } |
| 56 | + } |
| 57 | +} |
0 commit comments