gRPC framework for TizenRT
November 15, 2019 ยท View on GitHub
TizenRT features the gRPC framework from the opensource project gRPC, and is versioned at 1.9.
The following covers the pre-requisites to building grpc on TizenRT.
PreRequisites
TizenRT's version of gRPC supports only C++ binding, so it is expected that the developer should write C++ applications in order to
use gRPC. In that context, gRPC needs specific cpp plugins in order to convert certain high-level RPC specifications (covered in detail under Using Protobuf to generate Service and message classes) to C++ header and source files.
At present, TizenRT's gRPC build borrows the plugins from a native build of gRPC on the host environment (usually Linux or Mac OS). This requires building gRPC 1.9.0. The following steps describe how to do so on a linux machine:
-
Install Pre-requisites
$ [sudo] apt-get install build-essential autoconf libtool pkg-config $ [sudo] apt-get install libgflags-dev libgtest-dev $ [sudo] apt-get install clang libc++-dev -
Clone gRPC from Github, and checkout branch
v1.9.x$ git clone https://github.com/grpc/grpc $ cd grpc $ git checkout v1.9.x -
Fetch the gRPC submodules, including
Protocol Bufferwhich gRPC uses for RPC specifications$ git submodule update --init -
Build and install from the grpc repository root
$ make $ [sudo] make install -
Build
Protocol Buffersfrom within grpc folder. Assuming that you are on grpc folder, do the following:$ cd third_party/protobuf $ git submodule update --init --recursive $ ./autogen.sh $ ./configure $ make $ make check $ [sudo] make install $ [sudo] ldconfig
As a reference, please consult C++ Installation Instructions for details on how to install Protobuf from source.
After executing the steps above, you will have successfully installed the grpc and Protocol Buffer libraries, including cpp plugin and the protoc compiler on your host environment. The above steps are described in detail in Installing gRPC from source In the following, we cover two main aspects of porting gRPC to TizenRT, mainly details on how to build gRPC library, and how to develop, build and run applications that use gRPC.
Build gRPC in TizenRT
The source files for gRPC are located at external/grpc, and the associated header files are located at
external/include/grpc folders. To build gRPC in TizenRT, you need to enable CONFIG_GRPC via menuconfig. In this case, the parameter is located
under Networking Support -> Protocols -> gRPC.
As gRPC uses C++ binding, make sure that you have enabled C++ library in TizenRT as well.
Especially, you need to include the relevant config parameters using menuconfig as shown below:
- HAVE_CXX parameter, located at
Built-in Libraries -> Have C++ compiler - HAVE_CXXINITIALIZE, located at
Application Configuration -> Platform-specific Support -> Have C++ initialization - LIBC_LOCALE, located at
Built-in Libraries -> Enable I18N (LOCALE) support.
After you have enabled the configuration parameters and typed make at the os folder, the object files for gRPC will be
linked together under static library os/build/libraries/libexternal.a.
Develop, Build and Run TizenRT applications that use gRPC
This section is divided into three parts, namely,
- Using Protocol Buffer external module located under
external/protobufto convert.protospecifications to C++ service and message classes, - Customizing TizenRT's
Makefileto include theprotoccompiler along with the grpc application, - TizenRT's run-time environment support for grpc application.
Let us look in detail at the points above.
Using Protobuf to generate service and message classes
The C++ binding for gRPC uses Service and message classes to implement RPC stubs. Although the Service and message classes can be written by hand,
the Protocol Buffer compiler provides a convenient specification language, as well as automated C++ code generation for these classes. TizenRT has ported Protocol Buffer under
external/protobuf folder, so it is highly recommended to use this external module to generate the aforestated classes.
Accordingly, please include CONFIG_PROTOBUF in your TizenRT build configuration as well. You can refer to external/protobuf/Kconfig for details of this configuration. In order to generate stub code from protobuf specifications, gRPC features a set of plugins, one for each programming language. TizenRT requires the grpc-cpp-plugin to convert .proto files into C++ implementation of Message and Service classes. For this purpose, additional plugins must be installed on the host build environment (your Linux machine or VM). To do so, follow the installation steps described earlier in Pre-Requisites.
In the following subsection, we describe in detail how
to include the protoc compilation command in TizenRT's application-level Makefile.
Customizing Makefile for gRPC
In order to understand the details below, please refer to apps/examples/greeter_client/Makefile as an example.
In general, the application-level Makefile must include an additional step for auto-generating the Service and message classes using the protoc compiler.
For convenience, developers are expected to create their .proto specification at the same application folder, and provide it to the Makefile as shown below:
CXXPROTO = <proto-filename>.proto
Next, the protoc command will be invoked to generate the C++ Service and message classes. The Service files have extensions .grpc.pb.cc (source) and .grpc.pb.h (header),
while the Message files have extensions .pb.cc and .pb.h correspondingly. These Source and message classes are generated in Makefile as shown:
# Message class
$(CXXSRCS): %$(GENCXXEXT): %$(PROTOEXT)
protoc -I . --cpp_out=. $<
# Service class
$(CXXSRCS2): %$(SERVICECXXEXT): %$(PROTOEXT)
protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` $<
The protoc step above uses the grpc_cpp_plugin that comes with the gRPC installation on your host build machine. After the protoc step shown above, the Message class and Service class sources are compiled to generate object files of type .pb.o and .grpc.pb.o respectively.
These object files are combined together with the main application source file under the static library os/build/libraries/libapps.a.
Additionally, applications using gRPC need to be run through an ASYNC task from TASH, given their memory consumption. Accordingly, you need
to specify this in Makefile as shown below:
THREADEXEC = TASH_EXECMD_ASYNC
Run-time Environment Support for gRPC
In this section, we cover the following details concerning TizenRT run-time support for gRPC.
Deploy gRPC as Thread
TizenRT applications are deployed as tasks from the TASH console. However, gRPC modules need to run in a thread context.
Therefore, our TizenRT application must internally use either pthread_create API or C++'s std::thread module to start gRPC.
Please refer to grpc_greeter_client and grpc_route_client applications under apps/examples folder as examples on how to achieve this.
An important consideration when running gRPC on TizenRT is the stack size allocated for its threads.
From our initial verification, we observe that a minimum thread stack size of 16384 bytes is necessary for the main gRPC thread to run successfully on TizenRT.
This can be achieved by either using the pthread_attr_setstacksize API or configuring the default pthread stacksize via menuconfig, at the location Kernel Features -> Stack size information -> Default pthread stack size.
Additionally, this gRPC main thread engine uses pthread_create internally for its run-time procedures, for which we recommend setting a stack size of 10240 bytes or higher. In order to configure this easily, TizenRT features a menuconfig parameter at the location Networking Support -> Protocols -> gRPC -> Set thread size for grpc modules.
Enable Debug Log
To enable run-time logs, you need to set the environment variable GRPC_VERBOSITY to DEBUG. This can be done on the TASH console
by using the setenv command as shown below:
TASH>> setenv GRPC_VERBOSITY DEBUG
Alternatively, it is a better option to use the setenv function inside the TizenRT application, as shown below:
setenv("GRPC_VERBOSITY", "DEBUG", 1);
gRPC also allows logging tracers by setting the GRPC_TRACE variable to all. However, this functionality is not enabled yet, so interested developers must
manually enable the tracers in the gRPC source.