Start RPC example

Change-Id: Ie39a707573c615ceeb3650c036331683757cbc50
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/quickstart/cmake/+/422273
9 files changed
tree: 851b69658ec25bf7789c6d4d17692a756c7db342
  1. .gitignore
  2. AUTHORS
  3. CMakeLists.txt
  4. CONTRIBUTING.md
  5. LICENSE
  6. main.cc
  7. math_service.h
  8. math_service.proto
  9. OWNERS
  10. README.md
  11. run_console.py
README.md

Pigweed: minimal CMake example

A minimal, complete example of integrating Pigweed into a CMake project.

Overview

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.

Limitations

  • 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.

Quickstart

1. Install dependencies

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.

2. Build

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.

3. Run

  1. Open a console tab and run ./build/rpc_demo.

    The simulated firmware device boots up and starts listening on localhost:33000.

  2. Open another console tab and cd into the root of the Pigweed repo.

    cd third_party/pigweed
    
  3. 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.

  4. Start a pw_console session.

    python3 ../../../run_console.py --socket-addr localhost:33000
    
  5. 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"))
    
  6. 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))
    
  7. 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
    

Next steps

Appendix: Files

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.