xref: /aosp_15_r20/external/pigweed/pw_hdlc/rpc_example/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_hdlc-rpc-example:
2
3=====================
4RPC over HDLC example
5=====================
6.. pigweed-module-subpage::
7   :name: pw_hdlc
8
9The :ref:`module-pw_hdlc` module includes an example of bringing up a
10:ref:`module-pw_rpc` server that can be used to invoke RPCs. The example code
11is located at `//pw_hdlc/rpc_example/
12<https://cs.opensource.google/pigweed/pigweed/+/main:pw_hdlc/rpc_example/>`_.
13This tutorial walks through invoking RPCs interactively and with a script using
14the RPC over HDLC example.
15
16The example implementation of the ``system_server`` facade from ``pw_rpc``
17sends HDLC-encoded RPC packets via ``pw_sys_io``. It has blocking sends and
18reads so it is not suitable for performance-sensitive applications. This
19mostly serves as a simplistic example for quickly bringing up RPC over HDLC
20on bare-metal targets.
21
22.. note::
23
24   This tutorial assumes that you've got a :ref:`target-stm32f429i-disc1`
25   board, but the instructions work with any target that has implemented
26   :ref:`module-pw_sys_io`.
27
28-----------
29Get started
30-----------
31
321. Set up your board
33====================
34Connect the board you'll be communicating with. For the
35:ref:`target-stm32f429i-disc1` board, connect the mini USB port, and note which
36serial device it appears as (e.g. ``/dev/ttyACM0``).
37
382. Build Pigweed
39================
40Activate the Pigweed environment and run the default build.
41
42.. code-block:: console
43
44   . ./activate.sh
45   pw package install nanopb
46   gn gen out --args='dir_pw_third_party_nanopb="//environment/packages/nanopb"'
47   ninja -C out
48
493. Flash the firmware image
50===========================
51After a successful build, the binary for the example will be located at
52``//out/<toolchain>/obj/pw_hdlc/rpc_example/bin/rpc_example.elf``.
53
54Flash this image to your board. If you are using the
55:ref:`target-stm32f429i-disc1` board you can flash the image with
56`OpenOCD <http://openocd.org>`_.
57
58.. code-block:: console
59
60   openocd -f \
61     targets/stm32f429i_disc1/py/stm32f429i_disc1_utils/openocd_stm32f4xx.cfg \
62     -c "program \
63     out/stm32f429i_disc1_debug/obj/pw_hdlc/rpc_example/bin/rpc_example.elf \
64     verify reset exit"
65
664. Invoke RPCs from an interactive console
67==========================================
68The RPC console uses :ref:`module-pw_console` to make a rich interactive
69console for working with ``pw_rpc``. Run the RPC console with the following
70command, replacing ``/dev/ttyACM0`` with the correct serial device for your
71board.
72
73.. code-block:: console
74
75   pw-system-console --no-rpc-logging --proto-globs pw_rpc/echo.proto \
76     --device /dev/ttyACM0
77
78RPCs may be accessed through the predefined ``rpcs`` variable. RPCs are
79organized by their protocol buffer package and RPC service, as defined in a
80.proto file. The ``Echo`` method is part of the ``EchoService``, which
81is in the ``pw.rpc`` package. To invoke it synchronously, call
82``rpcs.pw.rpc.EchoService.Echo()``:
83
84.. code-block:: pycon
85
86   >>> device.rpcs.pw.rpc.EchoService.Echo(msg='Hello, world!')
87   (Status.OK, pw.rpc.EchoMessage(msg='Hello, world!'))
88
895. Invoke RPCs with a script
90============================
91RPCs may also be invoked from Python scripts. Close the RPC console if it is
92running, and execute the example script. Set the ``--device`` argument to the
93serial port for your device.
94
95.. code-block:: console
96
97   python pw_hdlc/rpc_example/example_script.py --device /dev/ttyACM0
98
99You should see this output:
100
101.. code-block:: text
102
103   The status was Status.OK
104   The payload was msg: "Hello"
105
106   The device says: Goodbye!
107
108-------------------------
109Local RPC example project
110-------------------------
111This example is similar to the above example, except it uses a socket to
112connect a server to a client, both running on the host.
113
1141. Build Pigweed
115================
116Activate the Pigweed environment and build the code.
117
118.. code-block:: console
119
120   . ./activate.sh
121   pw package install nanopb
122   gn gen out --args='dir_pw_third_party_nanopb="//environment/packages/nanopb"'
123   ninja -C out
124
1252. Start the server
126===================
127Run a ``pw_rpc`` server in one terminal window.
128
129.. code-block:: console
130
131   ./out/pw_strict_host_clang_debug/obj/pw_hdlc/rpc_example/bin/rpc_example
132
1333. Start the client
134===================
135In a separate Pigweed-activated terminal, run the ``pw-system-console`` RPC
136client with ``--proto-globs`` set to ``pw_rpc/echo.proto``. Additional protos
137can be added if needed.
138
139.. code-block:: console
140
141   pw-system-console --no-rpc-logging --proto-globs pw_rpc/echo.proto \
142     --socket-addr default
143
144.. tip::
145
146   The ``--socket-addr`` value may be replaced with an IP and port separated by
147   a colon, e.g. ``127.0.0.1:33000``. If using a Unix socket, the path to the
148   file follows ``file:``, e.g. ``file:/path/to/unix/socket``. Unix socket
149   Python support is pending, see `python/cpython#77589
150   <https://github.com/python/cpython/issues/77589>`_.
151
152.. tip::
153
154   The default RPC channel ID (``1``) can be overriden with ``--channel-id``.
155
1564. Invoke RPCs from the client
157==============================
158Invoke RPCs from the interactive console on the client side.
159
160.. code-block:: pycon
161
162   >>> device.rpcs.pw.rpc.EchoService.Echo(msg='Hello, world!')
163   (Status.OK, pw.rpc.EchoMessage(msg='Hello, world!'))
164
165.. seealso::
166
167   - The :ref:`module-pw_console`
168     :bdg-ref-primary-line:`module-pw_console-user_guide` for more info on using
169     the the pw_console UI.
170
171   - The target docs for other RPC-enabled application examples:
172
173     - :bdg-ref-primary-line:`target-host-device-simulator`
174     - :bdg-ref-primary-line:`target-rp2040`
175     - :bdg-ref-primary-line:`target-stm32f429i-disc1-stm32cube`
176
177-----------------
178More pw_hdlc docs
179-----------------
180.. include:: ../docs.rst
181   :start-after: .. pw_hdlc-nav-start
182   :end-before: .. pw_hdlc-nav-end
183