Skip to content

Commit 57b4e9e

Browse files
author
Tobias Aschenbrenner
committed
Merge branch 'feat-nanopb' into 'dev'
feat: nanopb See merge request blik/embedded/zephyr!23
2 parents 83987a0 + e12a139 commit 57b4e9e

File tree

9 files changed

+188
-0
lines changed

9 files changed

+188
-0
lines changed

samples/nanopb/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
2+
project(NONE)
3+
4+
# Extend zephyrs minimal stdint for missing types
5+
include_directories("ext/nanopb_syshdr")
6+
add_definitions(-DPB_SYSTEM_HEADER=\"pb_syshdr.h\")
7+
8+
# Protobuf definitions
9+
add_subdirectory (ext/blik)
10+
11+
# Generated protobufs
12+
include_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/blik")
13+
14+
# Make nanopb headers available
15+
include_directories("ext/nanopb")
16+
17+
# Mark them as to be generated and not necessarily available right away
18+
set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS}
19+
PROPERTIES GENERATED TRUE)
20+
21+
# Build sample with protobuf sources
22+
target_sources(app PRIVATE src/main.c ${PROTO_SRCS} ${PROTO_HDRS})
23+
24+
# Ensure to generate the protobuf files before building the sample
25+
add_dependencies(app blik)

samples/nanopb/README.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.. _nanopb:
2+
3+
nanopb
4+
###########
5+
6+
Overview
7+
********
8+
A simple example how to use nanopb in a zephyr application.
9+
The code is from the nanopb sample 'cmake_relpath'.
10+
11+
Building and Running
12+
********************
13+
14+
In order to build this sample, both protobuf-compiler and python-protobuf are required on the system.
15+
Nanopb has to be present in ext/nanopb and can be cloned from https://github.com/nanopb/nanopb.
16+
17+
18+
Sample Output
19+
=============
20+
21+
.. code-block:: console
22+
23+
***** BOOTING ZEPHYR OS v1.11.0 - BUILD: May 22 2018 19:21:56 *****
24+
Your lucky number was 13!
25+
Your unlucky number was 42!
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
project(NONE)
3+
4+
# NANOPB LIBRARY
5+
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../nanopb/extra)
6+
find_package(Nanopb REQUIRED)
7+
include_directories(${NANOPB_INCLUDE_DIRS})
8+
9+
# Generate proto
10+
nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS RELPATH . blik.proto sub/unlucky.proto)
11+
12+
# Mark them as to be generated and not necessarily available right away
13+
set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS}
14+
PROPERTIES GENERATED TRUE)
15+
16+
# Make the source- and header files globally available
17+
SET(PROTO_SRCS "${PROTO_SRCS}" CACHE INTERNAL "PROTO_SRCS")
18+
SET(PROTO_HDRS "${PROTO_HDRS}" CACHE INTERNAL "PROTO_HDRS")
19+
20+
# Create target and let it depend on generating the sources first
21+
add_custom_target(blik SOURCES ${PROTO_SRCS} ${PROTO_HDRS})

samples/nanopb/ext/blik/blik.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// A very simple protocol definition, consisting of only
2+
// one message.
3+
syntax = "proto2";
4+
5+
import "sub/unlucky.proto";
6+
7+
message SimpleMessage {
8+
required int32 lucky_number = 1;
9+
required UnluckyNumber unlucky = 2;
10+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
syntax = "proto2";
2+
3+
message UnluckyNumber {
4+
required uint32 number = 1;
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef _PB_SYSHDR_H_
2+
#define _PB_SYSHDR_H_
3+
4+
#include <stdint.h>
5+
#include <stdbool.h>
6+
#include <string.h>
7+
#ifdef PB_ENABLE_MALLOC
8+
#include <stdlib.h>
9+
#endif
10+
11+
/* The minimal stdint that ships with zephyr doesn't define any least types */
12+
typedef int8_t int_least8_t;
13+
typedef uint8_t uint_least8_t;
14+
typedef int16_t int_least16_t;
15+
typedef uint16_t uint_least16_t;
16+
17+
#endif

samples/nanopb/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# nothing here

samples/nanopb/sample.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
sample:
2+
description: nanopb for zephyr
3+
application
4+
name: nanopb
5+
platforms: all
6+
common:
7+
tags: samples
8+
harness: console
9+
harness_config:
10+
type: one_line
11+
regex:
12+
- "nanopb (.*)"

samples/nanopb/src/main.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include <zephyr.h>
2+
#include <stdio.h>
3+
#include <pb_encode.h>
4+
#include <pb_decode.h>
5+
#include "blik.pb.h"
6+
7+
/* This is the buffer where we will store our message. */
8+
static u8_t buffer[128];
9+
10+
void main(void)
11+
{
12+
size_t message_length;
13+
bool status;
14+
15+
/* Encode our message */
16+
{
17+
/* Allocate space on the stack to store the message data.
18+
*
19+
* Nanopb generates simple struct definitions for all messages.
20+
* - check out the contents of simple.pb.h!
21+
* It is a good idea to always initialize your structures
22+
* so that you do not have garbage data from RAM in there.
23+
*/
24+
SimpleMessage message = SimpleMessage_init_zero;
25+
26+
/* Create a stream that will write to our buffer. */
27+
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
28+
29+
/* Fill in the lucky number */
30+
message.lucky_number = 13;
31+
message.unlucky.number = 42;
32+
33+
/* Now we are ready to encode the message! */
34+
status = pb_encode(&stream, SimpleMessage_fields, &message);
35+
message_length = stream.bytes_written;
36+
37+
/* Then just check for any errors.. */
38+
if (!status) {
39+
printk("Encoding failed: %s\n", PB_GET_ERROR(&stream));
40+
return;
41+
}
42+
}
43+
44+
/* Now we could transmit the message over network, store it in a file or
45+
* wrap it to a pigeon's leg.
46+
*/
47+
48+
/* But because we are lazy, we will just decode it immediately. */
49+
50+
{
51+
/* Allocate space for the decoded message. */
52+
SimpleMessage message = SimpleMessage_init_zero;
53+
54+
/* Create a stream that reads from the buffer. */
55+
pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
56+
57+
/* Now we are ready to decode the message. */
58+
status = pb_decode(&stream, SimpleMessage_fields, &message);
59+
60+
/* Check for errors... */
61+
if (!status) {
62+
printk("Decoding failed: %s\n", PB_GET_ERROR(&stream));
63+
return;
64+
}
65+
66+
/* Print the data contained in the message. */
67+
printk("Your lucky number was %d!\n", message.lucky_number);
68+
printk("Your unlucky number was %u!\n", message.unlucky.number);
69+
}
70+
71+
}
72+

0 commit comments

Comments
 (0)