You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/hardware/02.uno/boards/uno-q/tutorials/01.user-manual/content.md
+96-9Lines changed: 96 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -785,22 +785,109 @@ The `Bridge` library provides a communication layer built on top of the `Arduino
785
785
-**MPU side (Qualcomm QRB, Linux)**: Runs higher-level services and can remotely invoke MCU functions.
786
786
-**MCU side (STM32, Zephyr RTOS)**: Handles time-critical tasks and exposes functions to the MPU via RPC.
787
787
788
+
#### The Arduino Router (Infrastructure)
789
+
790
+
Under the hood, the communication is managed by a background Linux service called the Arduino Router (`arduino-router`).
791
+
792
+
While the `Bridge` library is what you use in your code, the Router is the traffic controller that makes it possible. It implements a **Star Topology** network using MessagePack RPC.
793
+
794
+
**Key Features:**
795
+
796
+
-**Multipoint Communication:** Unlike simple serial communication (which is typically point-to-point), the Router allows multiple Linux processes to communicate with the MCU simultaneously (and with each other).
797
+
798
+
**Linux ↔ MCU:** Multiple Linux processes can interact with the MCU simultaneously (e.g., a Python® script reading sensors while a separate C++ application commands motors).
799
+
800
+
**Linux ↔ Linux:** You can use the Router to bridge different applications running on the MPU. For example, a Python script can expose an RPC function that another Python® or C++ application calls directly, allowing services to exchange data without involving the MCU at all.
801
+
802
+
-**Service Discovery:** Clients (like your Python® script or the MCU Sketch) "register" functions they want to expose. The Router keeps a directory of these functions and routes calls to the correct destination.
803
+
804
+
**Managing the Router Service**
805
+
806
+
The arduino-router runs automatically as a system service. In most cases, you do not need to interact with it directly. However, if you are debugging advanced issues or need to restart the communication stack, you can control it via the Linux terminal:
807
+
808
+
**Check Status** To see if the router is running and connected:
809
+
```bash
810
+
systemctl status arduino-router
811
+
```
812
+
**Restart the Service** If the communication seems stuck, you can restart the router without rebooting the board:
813
+
```bash
814
+
sudo systemctl restart arduino-router
815
+
```
816
+
**View Logs** To view the real-time logs for debugging (e.g., to see if RPC messages are being rejected or if a client has disconnected):
817
+
```bash
818
+
journalctl -u arduino-router -f
819
+
```
820
+
821
+
To capture more detailed information in the logs, you can append the `--verbose` argument to the systemd service configuration.
- You must reload the systemd daemon for the configuration changes to take effect.
853
+
854
+
```bash
855
+
sudo systemctl daemon-reload
856
+
```
857
+
858
+
- Restart the Router:
859
+
860
+
```bash
861
+
sudo systemctl restart arduino-router
862
+
```
863
+
864
+
- View the verbose logs:
865
+
866
+
```bash
867
+
journalctl -u arduino-router -f
868
+
```
869
+
788
870
#### Core Components
789
871
790
-
`BridgeClass`
791
-
- Main class managing RPC clients and servers. Provides methods to:
792
-
- Initialize the bridge (`begin()`)
793
-
- Call remote procedures (`call()`)
794
-
- Notify without waiting for a response (`notify()`)
795
-
- Expose local functions for remote execution (`provide()`, `provide_safe()`)
796
-
- Process incoming requests (`update()`)
872
+
`BridgeClass` The main class managing RPC clients and servers.
873
+
-`begin()`: Initializes the bridge and the internal serial transport.
874
+
-`call(method, args...)`: Invokes a function on the Linux side and waits for a result.
875
+
-`notify(method, args...)`: Invokes a function on the Linux side without waiting for a response (fire-and-forget).
876
+
-`provide(name, function)`: Exposes a local MCU function to Linux. Note: The function executes in the high-priority background RPC thread. Keep these functions short and thread-safe.
877
+
-`provide_safe(name, function)`: Exposes a local MCU function, but ensures it executes within the main `loop()` context. Use this if your function interacts with standard Arduino APIs (like `digitalWrite` or `Serial`) to avoid concurrency crashes.
878
+
879
+
***__Warning:__ Do not use `Bridge.call()` or `Monitor.print()` inside `provide()` functions. Initiating a new communication while responding to one causes system deadlocks.***
797
880
881
+
`RpcCall`
882
+
- Helper class representing an asynchronous RPC. If its `.result` method is invoked, it waits for the response, extracts the return value, and propagates error codes if needed.
798
883
799
-
`RpcResult`
800
-
-Helper class representing the result of a remote call. It waits for the response, extracts the return value, and propagates error codes if needed.
884
+
`Monitor`
885
+
-The library includes a pre-defined Monitor object. This allows the Linux side to send text streams to the MCU (acting like a virtual Serial Monitor) via the RPC method mon/write.
801
886
802
887
**Threading and Safety**
803
888
- The bridge uses Zephyr mutexes (`k_mutex`) to guarantee safe concurrent access when reading/writing over the transport. Updates are handled by a background thread that continuously polls for requests.
889
+
-**Incoming Updates**: Handled by a dedicated background thread (`updateEntryPoint`) that continuously polls for requests.
890
+
-**Safe Execution**: The provide_safe mechanism hooks into the main loop (`__loopHook`) to execute user callbacks safely when the processor is idle.
0 commit comments