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."
|
||||
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
|
||||
# and referencing, while keeping the settings themselves unavailable when the
|
||||
# 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/*
|
||||
kernel/*
|
||||
tfm_integration/tfm_integration.rst
|
||||
modules/*
|
||||
|
||||
.. comment
|
||||
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
|
||||
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
|
||||
path: modules/tee/tfm-mcuboot
|
||||
revision: v1.7.2
|
||||
- name: nanopb
|
||||
path: modules/lib/nanopb
|
||||
revision: d148bd26718e4c10414f07a7eb1bd24c62e56c5d
|
||||
|
||||
self:
|
||||
path: zephyr
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue