modules: nanopb: introduce new module
Add the nanopb library and generator tools as a module. Nanopb is a small code-size Protocol Buffers implementation in ansi C. It is especially suitable for use in microcontrollers, but fits any memory restricted system. Nanopb home: https://jpa.kapsi.fi/nanopb/ Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
This commit is contained in:
parent
be0a19757c
commit
b6979736ca
13 changed files with 318 additions and 0 deletions
|
@ -54,6 +54,9 @@ comment "hal_nordic module not available."
|
||||||
comment "Trusted-firmware-m module not available."
|
comment "Trusted-firmware-m module not available."
|
||||||
depends on !ZEPHYR_TRUSTED_FIRMWARE_M_MODULE
|
depends on !ZEPHYR_TRUSTED_FIRMWARE_M_MODULE
|
||||||
|
|
||||||
|
comment "Nanopb module not available."
|
||||||
|
depends on !ZEPHYR_NANOPB_MODULE
|
||||||
|
|
||||||
# This ensures that symbols are available in Kconfig for dependency checking
|
# This ensures that symbols are available in Kconfig for dependency checking
|
||||||
# and referencing, while keeping the settings themselves unavailable when the
|
# and referencing, while keeping the settings themselves unavailable when the
|
||||||
# modules are not present in the workspace
|
# modules are not present in the workspace
|
||||||
|
|
61
modules/nanopb/CMakeLists.txt
Normal file
61
modules/nanopb/CMakeLists.txt
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Copyright (c) 2021, Basalte bv
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
if(CONFIG_NANOPB)
|
||||||
|
|
||||||
|
set(NANOPB_DIR ${ZEPHYR_CURRENT_MODULE_DIR})
|
||||||
|
|
||||||
|
find_program(PROTOC protoc)
|
||||||
|
if(NOT PROTOC)
|
||||||
|
message(FATAL_ERROR "'protoc' not found, please ensure protoc is installed\
|
||||||
|
and in path. See https://docs.zephyrproject.org/latest/samples/modules/nanopb/README.html")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_DIR}/extra)
|
||||||
|
find_package(Nanopb REQUIRED)
|
||||||
|
|
||||||
|
zephyr_library()
|
||||||
|
|
||||||
|
zephyr_include_directories(${NANOPB_DIR})
|
||||||
|
|
||||||
|
zephyr_library_sources(
|
||||||
|
${NANOPB_DIR}/pb_common.c
|
||||||
|
${NANOPB_DIR}/pb_encode.c
|
||||||
|
${NANOPB_DIR}/pb_decode.c
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_compile_definitions(
|
||||||
|
PB_MAX_REQUIRED_FIELDS=${CONFIG_NANOPB_MAX_REQUIRED_FIELDS})
|
||||||
|
|
||||||
|
zephyr_compile_definitions_ifdef(
|
||||||
|
CONFIG_NANOPB_ENABLE_MALLOC
|
||||||
|
PB_ENABLE_MALLOC
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_compile_definitions_ifdef(
|
||||||
|
CONFIG_NANOPB_NO_ERRMSG
|
||||||
|
PB_NO_ERRMSG
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_compile_definitions_ifdef(
|
||||||
|
CONFIG_NANOPB_BUFFER_ONLY
|
||||||
|
PB_BUFFER_ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_compile_definitions_ifdef(
|
||||||
|
CONFIG_NANOPB_WITHOUT_64BIT
|
||||||
|
PB_WITHOUT_64BIT
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_compile_definitions_ifdef(
|
||||||
|
CONFIG_NANOPB_ENCODE_ARRAYS_UNPACKED
|
||||||
|
PB_ENCODE_ARRAYS_UNPACKED
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_compile_definitions_ifdef(
|
||||||
|
CONFIG_NANOPB_VALIDATE_UTF8
|
||||||
|
PB_VALIDATE_UTF8
|
||||||
|
)
|
||||||
|
|
||||||
|
endif()
|
59
modules/nanopb/Kconfig
Normal file
59
modules/nanopb/Kconfig
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# Copyright (c) 2021 Basalte bv
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config ZEPHYR_NANOPB_MODULE
|
||||||
|
bool
|
||||||
|
|
||||||
|
menuconfig NANOPB
|
||||||
|
bool "Nanopb Support"
|
||||||
|
help
|
||||||
|
This option enables the Nanopb library and generator.
|
||||||
|
|
||||||
|
if NANOPB
|
||||||
|
|
||||||
|
config NANOPB_ENABLE_MALLOC
|
||||||
|
bool "Enable malloc usage"
|
||||||
|
help
|
||||||
|
This option enables dynamic allocation support in the decoder.
|
||||||
|
|
||||||
|
config NANOPB_MAX_REQUIRED_FIELDS
|
||||||
|
int "Max number of required fields"
|
||||||
|
default 64
|
||||||
|
help
|
||||||
|
Maximum number of proto2 required fields to check for presence.
|
||||||
|
Default and minimum value is 64.
|
||||||
|
|
||||||
|
config NANOPB_NO_ERRMSG
|
||||||
|
bool "Disable error messages"
|
||||||
|
help
|
||||||
|
Disable error message support to save code size. Only error
|
||||||
|
information is the true/false return value.
|
||||||
|
|
||||||
|
config NANOPB_BUFFER_ONLY
|
||||||
|
bool "Buffers only"
|
||||||
|
help
|
||||||
|
Disable support for custom streams. Only supports encoding and
|
||||||
|
decoding with memory buffers. Speeds up execution and slightly
|
||||||
|
decreases code size.
|
||||||
|
|
||||||
|
config NANOPB_WITHOUT_64BIT
|
||||||
|
bool "Disable 64-bit integer fields"
|
||||||
|
help
|
||||||
|
Disable support of 64-bit integer fields, for old compilers or
|
||||||
|
for a slight speedup on 8-bit platforms.
|
||||||
|
|
||||||
|
config NANOPB_ENCODE_ARRAYS_UNPACKED
|
||||||
|
bool "Encode arrays unpacked"
|
||||||
|
help
|
||||||
|
Encode scalar arrays in the unpacked format, which takes up more
|
||||||
|
space.
|
||||||
|
Only to be used when the decoder on the receiving side cannot
|
||||||
|
process packed arrays, such as protobuf.js versions before 2020.
|
||||||
|
|
||||||
|
config NANOPB_VALIDATE_UTF8
|
||||||
|
bool "Validate UTF-8"
|
||||||
|
help
|
||||||
|
Check whether incoming strings are valid UTF-8 sequences.
|
||||||
|
Adds a small performance and code size penalty.
|
||||||
|
|
||||||
|
endif # NANOPB
|
|
@ -24,6 +24,7 @@ Samples and Demos
|
||||||
posix/*
|
posix/*
|
||||||
kernel/*
|
kernel/*
|
||||||
tfm_integration/tfm_integration.rst
|
tfm_integration/tfm_integration.rst
|
||||||
|
modules/*
|
||||||
|
|
||||||
.. comment
|
.. comment
|
||||||
To add a new sample document, please use the template available under
|
To add a new sample document, please use the template available under
|
||||||
|
|
10
samples/modules/index.rst
Normal file
10
samples/modules/index.rst
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.. _module-samples:
|
||||||
|
|
||||||
|
External Module Samples
|
||||||
|
#######################
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
:glob:
|
||||||
|
|
||||||
|
**/*
|
15
samples/modules/nanopb/CMakeLists.txt
Normal file
15
samples/modules/nanopb/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13.1)
|
||||||
|
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(nanopb_sample)
|
||||||
|
|
||||||
|
nanopb_generate_cpp(proto_sources proto_headers RELPATH .
|
||||||
|
src/simple.proto
|
||||||
|
)
|
||||||
|
# we need to be able to include generated header files
|
||||||
|
zephyr_library_include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c)
|
||||||
|
target_sources(app PRIVATE ${proto_sources} ${app_sources})
|
55
samples/modules/nanopb/README.rst
Normal file
55
samples/modules/nanopb/README.rst
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
.. _nanopb_sample:
|
||||||
|
|
||||||
|
Nanopb sample
|
||||||
|
#############
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
A simple protocol buffer sample using Nanopb for serializing structured data
|
||||||
|
to platform independent raw buffers or streams.
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
************
|
||||||
|
|
||||||
|
Nanopb uses the protocol buffer compiler to generate source and header files,
|
||||||
|
make sure the ``protoc`` executable is intalled and available.
|
||||||
|
|
||||||
|
.. tabs::
|
||||||
|
|
||||||
|
.. group-tab:: Ubuntu
|
||||||
|
|
||||||
|
Use ``apt`` to install dependency:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
sudo apt install protobuf-compiler
|
||||||
|
|
||||||
|
.. group-tab:: macOS
|
||||||
|
|
||||||
|
Use ``brew`` to install dependency:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
brew install protobuf
|
||||||
|
|
||||||
|
.. group-tab:: Windows
|
||||||
|
|
||||||
|
Use ``choco`` to install dependency:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
choco install protoc
|
||||||
|
|
||||||
|
Building and Running
|
||||||
|
********************
|
||||||
|
|
||||||
|
This application can be built as follows:
|
||||||
|
|
||||||
|
.. zephyr-app-commands::
|
||||||
|
:zephyr-app: samples/modules/nanopb
|
||||||
|
:host-os: unix
|
||||||
|
:board: qemu_x86
|
||||||
|
:goals: run
|
||||||
|
:compact:
|
1
samples/modules/nanopb/prj.conf
Normal file
1
samples/modules/nanopb/prj.conf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CONFIG_NANOPB=y
|
13
samples/modules/nanopb/sample.yaml
Normal file
13
samples/modules/nanopb/sample.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
sample:
|
||||||
|
description: Nanopb sample, with a simple proto
|
||||||
|
buffer
|
||||||
|
name: Simple nanopb
|
||||||
|
common:
|
||||||
|
harness: console
|
||||||
|
harness_config:
|
||||||
|
type: one_line
|
||||||
|
regex:
|
||||||
|
- "Your lucky number was 13!"
|
||||||
|
tests:
|
||||||
|
sample.modules.nanopb:
|
||||||
|
tags: samples nanopb
|
86
samples/modules/nanopb/src/main.c
Normal file
86
samples/modules/nanopb/src/main.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Petteri Aimonen
|
||||||
|
* Copyright (c) 2021 Basalte bv
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <sys/printk.h>
|
||||||
|
|
||||||
|
#include <pb_encode.h>
|
||||||
|
#include <pb_decode.h>
|
||||||
|
#include "src/simple.pb.h"
|
||||||
|
|
||||||
|
bool encode_message(uint8_t *buffer, size_t *message_length)
|
||||||
|
{
|
||||||
|
bool status;
|
||||||
|
|
||||||
|
/* Allocate space on the stack to store the message data.
|
||||||
|
*
|
||||||
|
* Nanopb generates simple struct definitions for all the messages.
|
||||||
|
* - check out the contents of simple.pb.h!
|
||||||
|
* It is a good idea to always initialize your structures
|
||||||
|
* so that you do not have garbage data from RAM in there.
|
||||||
|
*/
|
||||||
|
SimpleMessage message = SimpleMessage_init_zero;
|
||||||
|
|
||||||
|
/* Create a stream that will write to our buffer. */
|
||||||
|
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
/* Fill in the lucky number */
|
||||||
|
message.lucky_number = 13;
|
||||||
|
|
||||||
|
/* Now we are ready to encode the message! */
|
||||||
|
status = pb_encode(&stream, SimpleMessage_fields, &message);
|
||||||
|
*message_length = stream.bytes_written;
|
||||||
|
|
||||||
|
if (!status) {
|
||||||
|
printk("Encoding failed: %s\n", PB_GET_ERROR(&stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decode_message(uint8_t *buffer, size_t message_length)
|
||||||
|
{
|
||||||
|
bool status;
|
||||||
|
|
||||||
|
/* Allocate space for the decoded message. */
|
||||||
|
SimpleMessage message = SimpleMessage_init_zero;
|
||||||
|
|
||||||
|
/* Create a stream that reads from the buffer. */
|
||||||
|
pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
|
||||||
|
|
||||||
|
/* Now we are ready to decode the message. */
|
||||||
|
status = pb_decode(&stream, SimpleMessage_fields, &message);
|
||||||
|
|
||||||
|
/* Check for errors... */
|
||||||
|
if (status) {
|
||||||
|
/* Print the data contained in the message. */
|
||||||
|
printk("Your lucky number was %d!\n", (int)message.lucky_number);
|
||||||
|
} else {
|
||||||
|
printk("Decoding failed: %s\n", PB_GET_ERROR(&stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
/* This is the buffer where we will store our message. */
|
||||||
|
uint8_t buffer[SimpleMessage_size];
|
||||||
|
size_t message_length;
|
||||||
|
|
||||||
|
/* Encode our message */
|
||||||
|
if (!encode_message(buffer, &message_length)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we could transmit the message over network, store it in a file or
|
||||||
|
* wrap it to a pigeon's leg.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* But because we are lazy, we will just decode it immediately. */
|
||||||
|
decode_message(buffer, message_length);
|
||||||
|
}
|
8
samples/modules/nanopb/src/simple.proto
Normal file
8
samples/modules/nanopb/src/simple.proto
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// A very simple protocol definition, consisting of only
|
||||||
|
// one message.
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message SimpleMessage {
|
||||||
|
required int32 lucky_number = 1;
|
||||||
|
}
|
|
@ -17,3 +17,6 @@ Pillow
|
||||||
|
|
||||||
# can be used to sign a Zephyr application binary for consumption by a bootloader
|
# can be used to sign a Zephyr application binary for consumption by a bootloader
|
||||||
imgtool>=1.7.1
|
imgtool>=1.7.1
|
||||||
|
|
||||||
|
# used by nanopb module to generate sources from .proto files
|
||||||
|
protobuf
|
||||||
|
|
3
west.yml
3
west.yml
|
@ -145,6 +145,9 @@ manifest:
|
||||||
repo-path: mcuboot
|
repo-path: mcuboot
|
||||||
path: modules/tee/tfm-mcuboot
|
path: modules/tee/tfm-mcuboot
|
||||||
revision: v1.7.2
|
revision: v1.7.2
|
||||||
|
- name: nanopb
|
||||||
|
path: modules/lib/nanopb
|
||||||
|
revision: d148bd26718e4c10414f07a7eb1bd24c62e56c5d
|
||||||
|
|
||||||
self:
|
self:
|
||||||
path: zephyr
|
path: zephyr
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue