Handling Multiple Clients with OOB Interrupts
The OOB (Out-of-Band Interrupt) GPIO allows a single GPIO to act as an interrupt responding to one or more types of network connection or data ready event. See system.oob.gpio .
This demonstration starts a server on a Gecko OS device. Another Gecko OS device connects as a client. The demonstration uses TCP protocol, but the OOB interrupt GPIO approach works equally well with UDP and TLS.
In the first part of the demonstration, Handling a Single Client , GPIOs are assigned to assert on client connect and client data ready.
In the second part of the demonstration, Handling Multiple Clients , an OOB GPIO is assigned to assert on client connect and client data ready. Because the OOB GPIO resets when its status is read, this provides a way for an MCU to track connect, disconnect and data ready for multiple clients without continuous polling.
Prerequisites
This demonstration uses two Gecko OS evaluation boards.
Set Up
Open a Gecko OS Terminal to both boards. The board that runs the TCP server is designated Module A. The board that connects as a client is designated Module B.
The Module A configuration demonstrates the OOB interrupt approach. The Module B configuration simulates clients.
Module A Gecko OS Commands | Description |
---|---|
|
|
A data indicator GPIO can be set for the UDP protocol. See:
On rebooting, module A displays responses similar to the following:
Rebooting
[Disassociated]
[Ready]
SILABS-WGM160P-4.0.0, Gecko_OS-STANDARD-4.0.12-1198, WGM160P
IPv4 address: 10.10.10.1
SoftAP 'tcp_server_ap' started
TCP server listening on port: 3000
Handling a Single Client
Connect Module B as a client to the Module A server. We use the
tcp_client
-g
option to specify a data GPIO to indicate when data is ready on the client stream.
This works with TLS and UDP as well: the
-g
data GPIO option is also available for the
tls_client
and
udp_client
commands.
Module B Gecko OS Commands | Description |
---|---|
|
|
Note that Module A User LED 1 (
tcp.server.connected_gpio
) lights. It remains lit while Module B is connected. The server disconnects the client automatically after
tcp.server.idle_timeout
seconds, by default
60
. The client can disconnect by closing the stream.
If Module B disconnects, Module A registers that the stream is closed.
On Module B, close stream 0:
Module B Gecko OS Commands | Description |
---|---|
|
|
Module B Response | Description |
---|---|
|
|
Module A Response | Description |
---|---|
|
|
Note that Module A LED 1 ( tcp.server.connected_gpio ) turns off.
Reconnect Module B to the module A server:
Module B Gecko OS Commands | Description |
---|---|
|
|
Module A LED 1 ( tcp.server.connected_gpio ) lights.
Now on Module B write to stream 0.
Module B Gecko OS Commands | Description |
---|---|
|
|
Note that Module A User LED 2 ( tcp.server.data_gpio ) lights. It remains lit until Module A reads the data.
On Module A, read the data on stream 0.
Module A Gecko OS Commands | Description |
---|---|
|
|
Note that Module A User LED 2 ( tcp.server.data_gpio ) turns off when the data is read.
Send a message back from Module A to Module B:
Module A Gecko OS Commands | Description |
---|---|
|
|
Note that Module B User LED 1 (
tcp_client stream:0
) lights. It remains lit until Module B reads the data.
On Module B, read the data on stream 0.
Module B Gecko OS Commands | Description |
---|---|
|
|
The variables tcp.server.connected_gpio and tcp.server.data_gpio handle the simple case when only one client connects and sends data to the server.
Handling Multiple Clients
To avoid continuous polling, another solution is needed when multiple clients are connecting, disconnecting and sending data.
After the first client connects to the server, tcp.server.connected_gpio remains asserted. To detect a second client while the first client remains connected, it would be necessary to poll continuously with the stream_poll all command.
The same considerations apply to detecting client data on a stream. Until the data from the first client is read, it is not possible to detect data from a second client using tcp.server.data_gpio , without polling continuously.
The
system.oob.gpio
(Out-Of_Band Interrupt GPIO) provides a solution. Set up the
system.oob.gpio
to respond to the
tcp.server.connected_gpio
event. By default the
system.oob.gpio
is asserted on both the rising and falling edge of the event, so it goes high when the TCP client connects, and again when it disconnects.
On reading system.oob.status , the system.oob.gpio is de-asserted, ready to handle the next connect, disconnect or data event.
In a real-world application, the system.oob.gpio is wired to a host MCU interrupt, and the interrupt handler services the interrupt by getting system.oob.status to determine which events have taken place, and perhaps polling for stream information and taking other actions.
Provided the events do not take place faster than the MCU can handle interrupts, this approach can deal with multiple clients.
In this demonstration we simulate the interrupt handler by issuing commands manually.
Module A Setup
Module A Gecko OS Commands | Description |
---|---|
|
|
Connecting TCP Clients
Module B can simulate multiple TCP clients by connecting up to 8 times. Each time Gecko OS assigns a different stream.
Repeat the following command 9 times.
Module B Gecko OS Commands | Description |
---|---|
|
|
On the last attempt, the command fails with a response as follows:
> tcp_client 10.10.10.1 3000
Max streams exceeded
Command failed
List the open streams on Module B. Module B shows 8 TCP client streams. The response is similar to the following:
Module B Gecko OS Commands | Description |
---|---|
|
|
List the open streams on Module A. Module A has 8 TCP server streams open with ports matching those on Module B:
Module A Gecko OS Commands | Description |
---|---|
|
|
OOB Interrupt Handler
Note that Module A LED 1 turns on after the first connection from module B.
When Module A LED 1 lights we simulate the interrupt handler triggered by the system.oob.gpio . The interrupt handler gets the system.oob.status variable, then polls all streams with stream_poll all , and parses the response to determine what processing is required:
Module A Gecko OS Commands | Description |
---|---|
|
|
The response is a pipe-separated list of all open streams. Each stream entry consists of a comma-separated list of stream number and stream status:
-
0
: stream connected -
1
: data available -
2
: stream closed
We parse the poll response and determine there is no data to read.
Now Module B writes to two of the streams. We arbitrarily select stream 4 and 7:
Module B Gecko OS Commands | Description |
---|---|
|
|
Module A LED1 lights, and we simulate the interrupt handler.
Module A Gecko OS Commands | Description |
---|---|
|
|
Read data from stream 4:
Module A Gecko OS Commands | Description |
---|---|
|
|
Now on Module B close stream 6:
Module B Gecko OS Commands | Description |
---|---|
|
|
Module A LED1 lights, and we simulate the interrupt handler.
Module A Gecko OS Commands | Description |
---|---|
|
|
Now read stream 7:
Module A Gecko OS Commands | Description |
---|---|
|
|
This demonstrates that an MCU responding to an OOB interrupt can handle multiple clients, connecting, disconnecting and sending data asynchronously. Polling is required only in response to the OOB interrupt.
Supporting Gecko OS Versions
- Gecko OS 4
Change Log
Modified | Changes |
---|---|
2019-01-01 | Created |