pw_rpc#

Efficient, low-code-size RPC system for embedded devices

Stable C++ Java JavaScript Python TypeScript

pw_rpc provides an embedded-friendly system for defining and using remote procedure calls (RPCs) over arbitrary serial or packet-oriented transports. Services and their request/response messages are defined in shared protobuf files.

pw_rpc supports several languages, and both Nanopb and pw_protobuf code generation in C++.

syntax = "proto3";

package blinky;

import "pw_protobuf_protos/common.proto";

service Blinky {
  // Toggles the LED on or off.
  rpc ToggleLed(pw.protobuf.Empty) returns (pw.protobuf.Empty);
  // Continuously blinks the board LED a specified number of times.
  rpc Blink(BlinkRequest) returns (pw.protobuf.Empty);
}

message BlinkRequest {
  // The interval at which to blink the LED, in milliseconds.
  uint32 interval_ms = 1;
  // The number of times to blink the LED.
  optional uint32 blink_count = 2;
}
#include "pw_rpc/examples/blinky.rpc.pb.h"
#include "pw_system/rpc_server.h"

namespace blinky {

class BlinkyService final
    : public blinky::pw_rpc::nanopb::Blinky::Service<BlinkyService> {
 public:
  pw::Status ToggleLed(const pw_protobuf_Empty&, pw_protobuf_Empty&) {
    // Turn the LED off if it's currently on and vice versa
    return pw::OkStatus();
  }

  pw::Status Blink(const blinky_BlinkRequest& request, pw_protobuf_Empty&) {
    if (request.blink_count == 0) {
      // Stop blinking
    }
    if (request.interval_ms > 0) {
      // Change the blink interval
    }
    if (request.has_blink_count) {
      // Blink request.blink_count times
    }
    return pw::OkStatus();
  }
};

BlinkyService blinky_service;

}  // namespace blinky

namespace pw::system {

void UserAppInit() {
  pw::system::GetRpcServer().RegisterService(blinky::blinky_service);
}

}  // namespace pw::system
proto_library(
    name = "blinky_proto",
    srcs = ["blinky.proto"],
    deps = [
        "//pw_protobuf:common_proto",
    ],
)

nanopb_proto_library(
    name = "blinky_nanopb",
    deps = [":blinky_proto"],
)

nanopb_rpc_proto_library(
    name = "blinky_nanopb_rpc",
    nanopb_proto_library_deps = [":blinky_nanopb"],
    deps = [":blinky_proto"],
)

cc_library(
    name = "blinky_service",
    srcs = ["blinky_service.cc"],
    deps = [
        ":blinky_nanopb_rpc",
        "//pw_system:rpc_server",
    ],
)
Quickstart & guides

Check out the pw_rpc quickstart for more explanation of the code above. The guides answer common questions such as whether to use proto2 or proto3 syntax.

C++ server and client

C++ server and client library API guides.

Packet protocol

A detailed description of the pw_rpc packet protocol.

Design

An overview of the RPC call lifecycle, naming conventions, and the pw_rpc roadmap.

Python client

Python client library API reference.

TypeScript client

TypeScript client library API guide.

Nanopb codegen

Nanopb codegen library API guide.

pw_protobuf codegen

pw_protobuf codegen library API guide.