Skip to content

Commit

Permalink
Add example for interacting with the Kuksa Databroker with ESP32-base…
Browse files Browse the repository at this point in the history
…d microcontrollers
  • Loading branch information
max-grzanna authored and SebastianSchildt committed Jul 10, 2024
1 parent ed56ee1 commit 8947e8b
Show file tree
Hide file tree
Showing 24 changed files with 2,223 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ Component | Content | Comment/Status
[eCAL Provider](ecal2val) | Python provider for [eCAL](https://projects.eclipse.org/projects/automotive.ecal)
[PS4/PS5 - 2021 Formula Provider](./fone2val) | F1 Telemetrydata source for [KUKSA Databroker](https://github.com/eclipse/kuksa.val/tree/master/kuksa_databroker)
[KUKSA GO Client](kuksa_go_client) | Example client written in the [GO](https://go.dev/) programming language for easy interaction with KUKSA Databroker and Server
[ESP32 gRPC provider](gRPC-on-ESP32) | Example for interacting with the [KUKSA Databroker](https://github.com/eclipse/kuksa.val/tree/master/kuksa_databroker) with ESP32-based microcontrollers

## Contribution

For contribution guidelines see [CONTRIBUTING.md](CONTRIBUTING.md)

## Pre-commit set up

This repository is set up to use [pre-commit](https://pre-commit.com/) hooks.
Use `pip install pre-commit` to install pre-commit.
After you clone the project, run `pre-commit install` to install pre-commit into your git hooks.
Expand Down
51 changes: 51 additions & 0 deletions gRPC-on-ESP32/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
FROM espressif/idf

ARG DEBIAN_FRONTEND=nointeractive
ARG CONTAINER_USER=esp
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN apt-get update \
&& apt install -y -q \
cmake \
git \
hwdata \
libglib2.0-0 \
libnuma1 \
libpixman-1-0 \
linux-tools-virtual \
&& rm -rf /var/lib/apt/lists/*

RUN update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20

# QEMU
ENV QEMU_REL=esp-develop-20220919
ENV QEMU_SHA256=f6565d3f0d1e463a63a7f81aec94cce62df662bd42fc7606de4b4418ed55f870
ENV QEMU_DIST=qemu-${QEMU_REL}.tar.bz2
ENV QEMU_URL=https://github.com/espressif/qemu/releases/download/${QEMU_REL}/${QEMU_DIST}

ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8

RUN wget --no-verbose ${QEMU_URL} \
&& echo "${QEMU_SHA256} *${QEMU_DIST}" | sha256sum --check --strict - \
&& tar -xf $QEMU_DIST -C /opt \
&& rm ${QEMU_DIST}

ENV PATH=/opt/qemu/bin:${PATH}

RUN groupadd --gid $USER_GID $CONTAINER_USER \
&& adduser --uid $USER_UID --gid $USER_GID --disabled-password --gecos "" ${CONTAINER_USER} \
&& usermod -a -G root $CONTAINER_USER && usermod -a -G dialout $CONTAINER_USER

RUN chmod -R 775 /opt/esp/python_env/

USER ${CONTAINER_USER}
ENV USER=${CONTAINER_USER}
WORKDIR /home/${CONTAINER_USER}

RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc

ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]

CMD ["/bin/bash", "-c"]
47 changes: 47 additions & 0 deletions gRPC-on-ESP32/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/ubuntu
{
"name": "ESP-IDF QEMU",
"build": {
"dockerfile": "Dockerfile"
},
// Add the IDs of extensions you want installed when the container is created
"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind",
/* the path of workspace folder to be opened after container is running
*/
"workspaceFolder": "${localWorkspaceFolder}",
"mounts": [
"source=extensionCache,target=/root/.vscode-server/extensions,type=volume"
],
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.3_py3.10_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"extensions": [
"espressif.esp-idf-extension"
],
},
"codespaces": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.3_py3.10_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"extensions": [
"espressif.esp-idf-extension"
],
}
},
"runArgs": [
"--privileged"
]
}
7 changes: 7 additions & 0 deletions gRPC-on-ESP32/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.idea
.vscode
build/
managed_components/
cmake-build-debug/
sdkconfig
components
13 changes: 13 additions & 0 deletions gRPC-on-ESP32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

# Add the directory containing Nanopb to the list of extra component directories
# This assumes that `nanopb` is a directory within `components`
set(EXTRA_COMPONENT_DIRS
$ENV{IDF_PATH}/examples/common_components/protocol_examples_common
${CMAKE_CURRENT_LIST_DIR}/components/nanopb
)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(gRPC-on-esp32)
33 changes: 33 additions & 0 deletions gRPC-on-ESP32/NOTICE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# esp-grpc

The file src/grpc.c and src/grpc.h are derived from [grpc.c](https://github.com/chrisomatic/esp-grpc/blob/main/main/grpc.c)
and [grpc.h](https://github.com/chrisomatic/esp-grpc/blob/main/main/grpc.h).

Reference: <https://github.com/chrisomatic/esp-grpc/tree/5395918b5aa38314289b07a386601b7709c6c8e8>

The [esp-grpc](https://github.com/chrisomatic/esp-grpc/tree/5395918b5aa38314289b07a386601b7709c6c8e8) project is licensed under the following terms:

```
MIT License
Copyright (c) 2022 Christopher Rose
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
74 changes: 74 additions & 0 deletions gRPC-on-ESP32/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# gRPC on ESP32

This project offers a example on developing a gRPC client application designed to dispatch unary gRPC calls to a gRPC server, utilizing HTTP/2 as the underlying protocol.

The project incorporates the following building blocks:

+ [ESP-IDF](https://github.com/espressif/esp-idf) - ESP-32 Development Framework

+ [nghttp2](https://nghttp2.org/) - integrated with [esp-idf extra components](https://components.espressif.com/components/espressif/nghttp)

+ [nanopb](https://github.com/nanopb/nanopb) - compilation of protobufs, encoding/decoding of messages and responses into binary wire format

+ [kuksa.val Databroker](https://github.com/eclipse/kuksa.val) - protobuf definitions for communicating via gRPC

Note that this is a simplistic illustration of interacting with the Kuksa Databroker. For more detailed message exchanges, consider starting with `encoder.c` or `decoder.c`. These files contain the protobuf-specific implementations necessary for the exchange. See `grpc.c` for the HTTP/2 gRPC implementation.

An application scenario would be conceivable in which the ESP32 represents a microcontroller that sends sensor values such as the current speed of the vehicle to the Kuksa Databroker via GRPC.

## Hardware Required

+ A development board with ESP32/ESP32-S2/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
+ A USB cable for power supply and programming

## Configure the project

1. **Install the esp-idf toolchain** as shown in the esp-idf [docs](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/index.html#installation).

```bash
idf.py menuconfig
```

2. **Incorporate nanopb specific header files**

```bash
chmod +x install_nanopb.sh
./install_nanopb.sh
```

3. **Compile Protobufs**

+ Activate the esp-idf development toolchain and environment with `. ./export.sh` inside your toolchain installation
directory (typically under `~/esp/...`)
+ execute shell script `compile_proto.sh`

> 📝 Sometimes nanopb will give you a warning, that some dependencies are not installed. Install them with `pip install protobuf grpcio-tools`
4. **Install expra components**
In the project root, execute the command below to add the nghttp2 lib to the project.

```bash
idf.py add-dependency "espressif/nghttp^1.58.0"
```

5. **Open the project configuration menu** (`idf.py menuconfig`) to configure Wi-Fi or Ethernet.

## Create Get/Set requests

Refer to the `main.c` file to modify the message type and set the target URL with a kuksa Databroker running. To send a request for retrieving information, such as the vehicle's current speed, utilize the get section of the code, which is already uncommented. If you wish to set a value in the broker, uncomment the set section and employ the defined constants for _set_.

## Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

```bash
idf.py flash monitor
```

(To exit the serial monitor, type ``Ctrl-]`` or ``Ctrl-TX`` on Mac.)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

## Example Output

![Serial Output](assets/serial-output.png)
Binary file added gRPC-on-ESP32/assets/serial-output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions gRPC-on-ESP32/compile_proto.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#################################################################################
# Copyright (c) 2024 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License 2.0 which is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
#################################################################################

#!/bin/sh
./components/nanopb/generator-bin/protoc --proto_path=proto/ --nanopb_out=main/generated val.proto types.proto

./components/nanopb/generator-bin/protoc --proto_path=proto/ --nanopb_out=components/nanopb/google/protobuf/ wrappers.proto empty.proto timestamp.proto

echo "Done!"
58 changes: 58 additions & 0 deletions gRPC-on-ESP32/install_nanopb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#################################################################################
# Copyright (c) 2024 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License 2.0 which is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
#################################################################################

#!/bin/bash

URL="https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz"
TARGET_DIR="components"
FINAL_NAME="nanopb"
CMAKELISTS="$TARGET_DIR/nanopb/CMakeLists.txt"

# Download and extract the main package
curl -o "nanopb-0.4.8-linux-x86.tar.gz" $URL
mkdir -p "$TARGET_DIR"
tar -xzf "nanopb-0.4.8-linux-x86.tar.gz" -C "$TARGET_DIR"
mv "$TARGET_DIR/nanopb-0.4.8-linux-x86" "$TARGET_DIR/$FINAL_NAME"
rm "nanopb-0.4.8-linux-x86.tar.gz"


echo "Downloading timestamp protobuf definitions."
mkdir -p "$TARGET_DIR/nanopb/google/protobuf/"
PROTO_FILES=(
"https://raw.githubusercontent.com/protocolbuffers/protobuf/main/src/google/protobuf/wrappers.proto"
"https://raw.githubusercontent.com/protocolbuffers/protobuf/main/src/google/protobuf/empty.proto"
"https://raw.githubusercontent.com/protocolbuffers/protobuf/main/src/google/protobuf/timestamp.proto"
)

for URL in "${PROTO_FILES[@]}"; do
FILE_NAME=$(basename $URL)
curl -o "proto/$FILE_NAME" $URL
done

# Define CMake configuration and overwrite
CMAKE_CONFIG='idf_component_register(SRCS
"pb_common.c"
"pb_encode.c"
"pb_decode.c"
"google/protobuf/empty.pb.c"
"google/protobuf/timestamp.pb.c"
"google/protobuf/wrappers.pb.c"
INCLUDE_DIRS .
)'

# Write the configuration to CMakeLists.txt
echo "$CMAKE_CONFIG" > "$CMAKELISTS"

echo "CMakeLists.txt has been updated."

echo "Installation of nanopb is complete."
22 changes: 22 additions & 0 deletions gRPC-on-ESP32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
set (
srcs
"main.c"
"grpc.c"
"encoder.c"
"decoder.c"
"generated/val.pb.c"
"generated/types.pb.c"
)

set(
include_dirs
"."
"generated/"
)

idf_component_register(
SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}"#EMBED_TXTFILES ../certs/server_cert.pem
)

target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
Loading

0 comments on commit 8947e8b

Please sign in to comment.