1.. _module-pw_hdlc-rpc-example:
2
3=============================
4RPC over HDLC example project
5=============================
6The :ref:`module-pw_hdlc` module includes an example of bringing up a
7:ref:`module-pw_rpc` server that can be used to invoke RPCs. The example code
8is located at ``pw_hdlc/rpc_example``. This section walks through invoking RPCs
9interactively and with a script using the RPC over HDLC example.
10
11These instructions assume the STM32F429i Discovery board, but they work with
12any target with :ref:`pw::sys_io <module-pw_sys_io>` implemented.
13
14---------------------
15Getting started guide
16---------------------
17
181. Set up your board
19====================
20Connect the board you'll be communicating with. For the Discovery board, connect
21the mini USB port, and note which serial device it appears as (e.g.
22``/dev/ttyACM0``).
23
242. Build Pigweed
25================
26Activate the Pigweed environment and run the default build.
27
28.. code-block:: sh
29
30  source activate.sh
31  gn gen out
32  ninja -C out
33
343. Flash the firmware image
35===========================
36After a successful build, the binary for the example will be located at
37``out/<toolchain>/obj/pw_hdlc/rpc_example/bin/rpc_example.elf``.
38
39Flash this image to your board. If you are using the STM32F429i Discovery Board,
40you can flash the image with `OpenOCD <http://openocd.org>`_.
41
42.. code-block:: sh
43
44 openocd -f targets/stm32f429i-disc1/py/stm32f429i_disc1_utils/openocd_stm32f4xx.cfg \
45     -c "program out/stm32f429i_disc1_debug/obj/pw_hdlc/rpc_example/bin/rpc_example.elf"
46
474. Invoke RPCs from in an interactive console
48=============================================
49The RPC console uses `IPython <https://ipython.org>`_ to make a rich interactive
50console for working with pw_rpc. Run the RPC console with the following command,
51replacing ``/dev/ttyACM0`` with the correct serial device for your board.
52
53.. code-block:: text
54
55  $ python -m pw_hdlc.rpc_console --device /dev/ttyACM0
56
57  Console for interacting with pw_rpc over HDLC.
58
59  To start the console, provide a serial port as the --device argument and paths
60  or globs for .proto files that define the RPC services to support:
61
62    python -m pw_hdlc.rpc_console --device /dev/ttyUSB0 sample.proto
63
64  This starts an IPython console for communicating with the connected device. A
65  few variables are predefined in the interactive console. These include:
66
67      rpcs   - used to invoke RPCs
68      device - the serial device used for communication
69      client - the pw_rpc.Client
70
71  An example echo RPC command:
72
73    rpcs.pw.rpc.EchoService.Echo(msg="hello!")
74
75  In [1]:
76
77RPCs may be accessed through the predefined ``rpcs`` variable. RPCs are
78organized by their protocol buffer package and RPC service, as defined in a
79.proto file. To call the ``Echo`` method is part of the ``EchoService``, which
80is in the ``pw.rpc`` package. To invoke it synchronously, call
81``rpcs.pw.rpc.EchoService.Echo``:
82
83.. code-block:: python
84
85    In [1]: rpcs.pw.rpc.EchoService.Echo(msg="Your message here!")
86    Out[1]: (<Status.OK: 0>, msg: "Your message here!")
87
885. Invoke RPCs with a script
89============================
90RPCs may also be invoked from Python scripts. Close the RPC console if it is
91running, and execute the example script. Set the --device argument to the
92serial port for your device.
93
94.. code-block:: text
95
96  $ pw_hdlc/rpc_example/example_script.py --device /dev/ttyACM0
97  The status was Status.OK
98  The payload was msg: "Hello"
99
100  The device says: Goodbye!
101
102-------------------------
103Local RPC example project
104-------------------------
105
106This example is similar to the above example, except it use socket to
107connect server and client running on the host.
108
1091. Build Pigweed
110================
111Activate the Pigweed environment and build the code.
112
113.. code-block:: sh
114
115  source activate.sh
116  gn gen out
117  pw watch
118
1192. Start client side and server side
120====================================
121
122Run pw_rpc client (i.e. use echo.proto)
123
124.. code-block:: sh
125
126  python -m pw_hdlc.rpc_console path/to/echo.proto -s localhost:33000
127
128Run pw_rpc server
129
130.. code-block:: sh
131
132  out/host_clang_debug/obj/pw_hdlc/rpc_example/bin/rpc_example
133
134Then you can invoke RPCs from the interactive console on the client side.
135