Start RPC example Change-Id: Ie39a707573c615ceeb3650c036331683757cbc50 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/quickstart/cmake/+/422273
A minimal, complete example of integrating Pigweed into a CMake project.
main.cc creates an RPC server that listens on a local TCP socket for RPC requests. Using pw_console as an RPC client you will send an RPC request to this server. Communication over the socket uses HDLC framing. All RPC requests and responses are structured as protobufs. All protobuf generation is configured inside of CMakeLists.txt.
This example has only been verified to work on Debian.
The example is only set up to build a host-side simulation of the firmware. It does not set up a cross-compilation toolchain or provide flashing tools.
The firmware build intentionally avoids a bootstrap to demonstrate manual setup of Pigweed modules in a CMake project. Most of the toolchain must be installed globally and available on the system path. We use a bootstrap to speed up the manual testing (i.e. bootstrapping in order to spin up the pw_console RPC client quickly) but it's not required on the client-side, either.
Linux:
sudo apt-get install -y build-essential cmake ninja-build \ protobuf-compiler python3 python3-protobuf python3-serial
Note: Pigweed and Nanopb (on-device protobuf codegen library) are managed in CMakeLists.txt via FetchContent.
Configure the build:
cmake -B build -S . -G Ninja
Run the build:
cmake --build build --target rpc_demo
Note: The Python protobuf codegen also runs as part of this build. The pw_console client will use this generated Python to communicate with the simulated firmware device.
Open a console tab and run ./build/rpc_demo.
The simulated firmware device boots up and starts listening on localhost:33000.
Open another console tab and cd into the root of the Pigweed repo.
cd third_party/pigweed
Bootstrap an environment for pw_console.
. bootstrap.sh
Note: Bootstrap is only used here to simplify and speed up the manual testing part of the example. It's possible to use pw_console without a bootstrap.
Start a pw_console session.
python3 ../../../run_console.py --socket-addr localhost:33000
In the Python REPL of pw_console invoke the Echo RPC. You should see the server respond with a tuple containing Status.OK followed by a response containing the same message that you sent.
>>> device.rpcs.pw.rpc.EchoService.Echo(msg="hello") (Status.OK, pw.rpc.EchoMessage(msg="hello"))
Now try invoking the Add RPC. You should see the server respond with a tuple containing Status.OK again followed by the correct sum.
>>> device.rpcs.rpc.math.MathService.Add(a=3, b=5) (Status.OK, rpc.math.AddResponse(result=8))
Go back to the tab running the simulated firmware device. You should see the server logging messages.
Awaiting connection on port 33000 Client connected INF pw_system initialized, main thread sleeping... INF System init INF Registering RPC services INF Starting threads INF Running RPC server INF Registering custom MathService INF Server received Add: 5 + 3 INF Simulated device is still alive
Talk to us in the #cmake-build channel of our Discord.
Learn more about Pigweed's CMake support.
Source files:
//CMakeLists.txt: Defines the CMake build system. It fetches dependencies (Nanopb, Pigweed), configures Pigweed backends, sets up C++ and Python protobuf codegen, and defines the rpc_demo executable target.
//main.cc: The entry point for the C++ application. It initializes pw_system and implements UserAppInit to register the custom MathService.
//math_service.proto: Defines the protobuf service MathService with an Add method.
//math_service.h: Implements the MathService defined in math_service.proto.
//run_console.py: Python script to launch pw_console configured to talk to the running application. It sets up the Python path to include generated protos.
Generated files:
//build/math_service/nanopb/math_service.pb.h and //build/math_service/nanopb/math_service.pb.c: Nanopb generated C code for the math_service.proto messages.
//build/math_service/nanopb_rpc/math_service.rpc.pb.h: Pigweed RPC generated C++ header for the math_service.proto service.
//build/generated_python/python/math_service_pb2.py: Python protobuf module generated from math_service.proto, used by run_console.py.
//build/python_packages/: Contains Python protobuf modules generated from Pigweed internal protos, required by Pigweed RPC plugins.