mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-03-27 01:10:20 +08:00
Nanopb is a plain-C implementation of Google's Protocol Buffers data
format. It is targeted at 32 bit microcontrollers, but is also fit for other embedded systems with tight (2-10 kB ROM, <1 kB RAM) memory constraints.(http://koti.kapsi.fi/jpa/nanopb/) How to use the example: 1. move examples/nanopb to bsp/xxxx/ 2. enable macro RT_USING_NANOPB in rtconfig.h 3. regenerate the project file (scons --target=xxxx) 4. rebuild the project
This commit is contained in:
@@ -184,4 +184,7 @@
|
||||
// <bool name="RT_USING_BSP_CMSIS" description="Using CMSIS in BSP" default="true" />
|
||||
// #define RT_USING_BSP_CMSIS
|
||||
|
||||
/* nanopb support */
|
||||
/* #define RT_USING_NANOPB */
|
||||
|
||||
#endif
|
||||
|
||||
183
components/external/nanopb/CHANGELOG.txt
vendored
Normal file
183
components/external/nanopb/CHANGELOG.txt
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
nanopb-0.3.1 (2014-09-11)
|
||||
Fix security issue due to size_t overflows. (issue 132)
|
||||
Fix memory leak with duplicated fields and PB_ENABLE_MALLOC
|
||||
Fix crash if pb_release() is called twice.
|
||||
Fix cyclic message support (issue 130)
|
||||
Fix error in generated initializers for repeated pointer fields.
|
||||
Improve tests (issues 113, 126)
|
||||
|
||||
nanopb-0.3.0 (2014-08-26)
|
||||
NOTE: See docs/migration.html or online at
|
||||
http://koti.kapsi.fi/~jpa/nanopb/docs/migration.html
|
||||
for changes in this version. Most importantly, you need to add
|
||||
pb_common.c to the list of files to compile.
|
||||
|
||||
Separated field iterator logic to pb_common.c (issue 128)
|
||||
Change the _count fields to use pb_size_t datatype (issue 82)
|
||||
Added PB_ prefix to macro names (issue 106)
|
||||
Added #if version guard to generated files (issue 129)
|
||||
Added migration document
|
||||
|
||||
nanopb-0.2.9 (2014-08-09)
|
||||
NOTE: If you are using the -e option with the generator, you have
|
||||
to prepend . to the argument to get the same behaviour as before.
|
||||
|
||||
Do not automatically add a dot with generator -e option. (issue 122)
|
||||
Fix problem with .options file and extension fields. (issue 125)
|
||||
Don't use SIZE_MAX macro, as it is not in C89. (issue 120)
|
||||
Generate #defines for initializing message structures. (issue 79)
|
||||
Add skip_message option to generator. (issue 121)
|
||||
Add PB_PACKED_STRUCT support for Keil MDK-ARM toolchain (issue 119)
|
||||
Give better messages about the .options file path. (issue 124)
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.8 (2014-05-20)
|
||||
Fix security issue with PB_ENABLE_MALLOC. (issue 117)
|
||||
Add option to not add timestamps to .pb.h and .pb.c preambles. (issue 115)
|
||||
Documentation updates
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.7 (2014-04-07)
|
||||
Fix bug with default values for extension fields (issue 111)
|
||||
Fix some MISRA-C warnings (issue 91)
|
||||
Implemented optional malloc() support (issue 80)
|
||||
Changed pointer-type bytes field datatype
|
||||
Add a "found" field to pb_extension_t (issue 112)
|
||||
Add convenience function pb_get_encoded_size() (issue 16)
|
||||
|
||||
nanopb-0.2.6 (2014-02-15)
|
||||
Fix generator error with bytes callback fields (issue 99)
|
||||
Fix warnings about large integer constants (issue 102)
|
||||
Add comments to where STATIC_ASSERT is used (issue 96)
|
||||
Add warning about unknown field names on .options (issue 105)
|
||||
Move descriptor.proto to google/protobuf subdirectory (issue 104)
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.5 (2014-01-01)
|
||||
Fix a bug with encoding negative values in int32 fields (issue 97)
|
||||
Create binary packages of the generator + dependencies (issue 47)
|
||||
Add support for pointer-type fields to the encoder (part of issue 80)
|
||||
Fixed path in FindNanopb.cmake (issue 94)
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.4 (2013-11-07)
|
||||
Remove the deprecated NANOPB_INTERNALS functions from public API.
|
||||
Document the security model.
|
||||
Check array and bytes max sizes when encoding (issue 90)
|
||||
Add #defines for maximum encoded message size (issue 89)
|
||||
Add #define tags for extension fields (issue 93)
|
||||
Fix MISRA C violations (issue 91)
|
||||
Clean up pb_field_t definition with typedefs.
|
||||
|
||||
nanopb-0.2.3 (2013-09-18)
|
||||
Improve compatibility by removing ternary operator from initializations (issue 88)
|
||||
Fix build error on Visual C++ (issue 84, patch by Markus Schwarzenberg)
|
||||
Don't stop on unsupported extension fields (issue 83)
|
||||
Add an example pb_syshdr.h file for non-C99 compilers
|
||||
Reorganize tests and examples into subfolders (issue 63)
|
||||
Switch from Makefiles to scons for building the tests
|
||||
Make the tests buildable on Windows
|
||||
|
||||
nanopb-0.2.2 (2013-08-18)
|
||||
Add support for extension fields (issue 17)
|
||||
Fix unknown fields in empty message (issue 78)
|
||||
Include the field tags in the generated .pb.h file.
|
||||
Add pb_decode_delimited and pb_encode_delimited wrapper functions (issue 74)
|
||||
Add a section in top of pb.h for changing compilation settings (issue 76)
|
||||
Documentation improvements (issues 12, 77 and others)
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.1 (2013-04-14)
|
||||
NOTE: The default callback function signature has changed.
|
||||
If you don't want to update your code, define PB_OLD_CALLBACK_STYLE.
|
||||
|
||||
Change the callback function to use void** (issue 69)
|
||||
Add support for defining the nanopb options in a separate file (issue 12)
|
||||
Add support for packed structs in IAR and MSVC (in addition to GCC) (issue 66)
|
||||
Implement error message support for the encoder side (issue 7)
|
||||
Handle unterminated strings when encoding (issue 68)
|
||||
Fix bug with empty strings in repeated string callbacks (issue 73)
|
||||
Fix regression in 0.2.0 with optional callback fields (issue 70)
|
||||
Fix bugs with empty message types (issues 64, 65)
|
||||
Fix some compiler warnings on clang (issue 67)
|
||||
Some portability improvements (issues 60, 62)
|
||||
Various new generator options
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.0 (2013-03-02)
|
||||
NOTE: This release requires you to regenerate all .pb.c
|
||||
files. Files generated by older versions will not
|
||||
compile anymore.
|
||||
|
||||
Reformat generated .pb.c files using macros (issue 58)
|
||||
Rename PB_HTYPE_ARRAY -> PB_HTYPE_REPEATED
|
||||
Separate PB_HTYPE to PB_ATYPE and PB_HTYPE
|
||||
Move STATIC_ASSERTs to .pb.c file
|
||||
Added CMake file (by Pavel Ilin)
|
||||
Add option to give file extension to generator (by Michael Haberler)
|
||||
Documentation updates
|
||||
|
||||
nanopb-0.1.9 (2013-02-13)
|
||||
Fixed error message bugs (issues 52, 56)
|
||||
Sanitize #ifndef filename (issue 50)
|
||||
Performance improvements
|
||||
Add compile-time option PB_BUFFER_ONLY
|
||||
Add Java package name to nanopb.proto
|
||||
Check for sizeof(double) == 8 (issue 54)
|
||||
Added generator option to ignore some fields. (issue 51)
|
||||
Added generator option to make message structs packed. (issue 49)
|
||||
Add more test cases.
|
||||
|
||||
nanopb-0.1.8 (2012-12-13)
|
||||
Fix bugs in the enum short names introduced in 0.1.7 (issues 42, 43)
|
||||
Fix STATIC_ASSERT macro when using multiple .proto files. (issue 41)
|
||||
Fix missing initialization of istream.errmsg
|
||||
Make tests/Makefile work for non-gcc compilers (issue 40)
|
||||
|
||||
nanopb-0.1.7 (2012-11-11)
|
||||
Remove "skip" mode from pb_istream_t callbacks. Example implementation had a bug. (issue 37)
|
||||
Add option to use shorter names for enum values (issue 38)
|
||||
Improve options support in generator (issues 12, 30)
|
||||
Add nanopb version number to generated files (issue 36)
|
||||
Add extern "C" to generated headers (issue 35)
|
||||
Add names for structs to allow forward declaration (issue 39)
|
||||
Add buffer size check in example (issue 34)
|
||||
Fix build warnings on MS compilers (issue 33)
|
||||
|
||||
nanopb-0.1.6 (2012-09-02)
|
||||
Reorganize the field decoder interface (issue 2)
|
||||
Improve performance in submessage decoding (issue 28)
|
||||
Implement error messages in the decoder side (issue 7)
|
||||
Extended testcases (alltypes test is now complete).
|
||||
Fix some compiler warnings (issues 25, 26, 27, 32).
|
||||
|
||||
nanopb-0.1.5 (2012-08-04)
|
||||
Fix bug in decoder with packed arrays (issue 23).
|
||||
Extended testcases.
|
||||
Fix some compiler warnings.
|
||||
|
||||
nanopb-0.1.4 (2012-07-05)
|
||||
Add compile-time options for easy-to-use >255 field support.
|
||||
Improve the detection of missing required fields.
|
||||
Added example on how to handle union messages.
|
||||
Fix generator error with .proto without messages.
|
||||
Fix problems that stopped the code from compiling with some compilers.
|
||||
Fix some compiler warnings.
|
||||
|
||||
nanopb-0.1.3 (2012-06-12)
|
||||
Refactor the field encoder interface.
|
||||
Improve generator error messages (issue 5)
|
||||
Add descriptor.proto into the #include exclusion list
|
||||
Fix some compiler warnings.
|
||||
|
||||
nanopb-0.1.2 (2012-02-15)
|
||||
Make the generator to generate include for other .proto files (issue 4).
|
||||
Fixed generator not working on Windows (issue 3)
|
||||
|
||||
nanopb-0.1.1 (2012-01-14)
|
||||
Fixed bug in encoder with 'bytes' fields (issue 1).
|
||||
Fixed a bug in the generator that caused a compiler error on sfixed32 and sfixed64 fields.
|
||||
Extended testcases.
|
||||
|
||||
nanopb-0.1.0 (2012-01-06)
|
||||
First stable release.
|
||||
61
components/external/nanopb/README.txt
vendored
Normal file
61
components/external/nanopb/README.txt
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
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.
|
||||
|
||||
Homepage: http://kapsi.fi/~jpa/nanopb/
|
||||
|
||||
|
||||
|
||||
|
||||
Using the nanopb library
|
||||
========================
|
||||
To use the nanopb library, you need to do two things:
|
||||
|
||||
1) Compile your .proto files for nanopb, using protoc.
|
||||
2) Include pb_encode.c and pb_decode.c in your project.
|
||||
|
||||
The easiest way to get started is to study the project in "examples/simple".
|
||||
It contains a Makefile, which should work directly under most Linux systems.
|
||||
However, for any other kind of build system, see the manual steps in
|
||||
README.txt in that folder.
|
||||
|
||||
|
||||
|
||||
Using the Protocol Buffers compiler (protoc)
|
||||
============================================
|
||||
The nanopb generator is implemented as a plugin for the Google's own protoc
|
||||
compiler. This has the advantage that there is no need to reimplement the
|
||||
basic parsing of .proto files. However, it does mean that you need the
|
||||
Google's protobuf library in order to run the generator.
|
||||
|
||||
If you have downloaded a binary package for nanopb (either Windows, Linux or
|
||||
Mac OS X version), the 'protoc' binary is included in the 'generator-bin'
|
||||
folder. In this case, you are ready to go. Simply run this command:
|
||||
|
||||
generator-bin/protoc --nanopb_out=. myprotocol.proto
|
||||
|
||||
However, if you are using a git checkout or a plain source distribution, you
|
||||
need to provide your own version of protoc and the Google's protobuf library.
|
||||
On Linux, the necessary packages are protobuf-compiler and python-protobuf.
|
||||
On Windows, you can either build Google's protobuf library from source or use
|
||||
one of the binary distributions of it. In either case, if you use a separate
|
||||
protoc, you need to manually give the path to nanopb generator:
|
||||
|
||||
protoc --plugin=protoc-gen-nanopb=nanopb/generator/protoc-gen-nanopb ...
|
||||
|
||||
|
||||
|
||||
Running the tests
|
||||
=================
|
||||
If you want to perform further development of the nanopb core, or to verify
|
||||
its functionality using your compiler and platform, you'll want to run the
|
||||
test suite. The build rules for the test suite are implemented using Scons,
|
||||
so you need to have that installed. To run the tests:
|
||||
|
||||
cd tests
|
||||
scons
|
||||
|
||||
This will show the progress of various test cases. If the output does not
|
||||
end in an error, the test cases were successful.
|
||||
|
||||
|
||||
14
components/external/nanopb/SConscript
vendored
Normal file
14
components/external/nanopb/SConscript
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
from building import *
|
||||
|
||||
src = Split('''
|
||||
pb_common.c
|
||||
pb_decode.c
|
||||
pb_encode.c
|
||||
''')
|
||||
CPPPATH = [RTT_ROOT + '/components/external/nanopb']
|
||||
|
||||
group = DefineGroup('Nanopb', src, depend = ['RT_USING_NANOPB'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
518
components/external/nanopb/pb.h
vendored
Normal file
518
components/external/nanopb/pb.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
90
components/external/nanopb/pb_common.c
vendored
Normal file
90
components/external/nanopb/pb_common.c
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c.
|
||||
*
|
||||
* 2014 Petteri Aimonen <jpa@kapsi.fi>
|
||||
*/
|
||||
|
||||
#include "pb_common.h"
|
||||
|
||||
bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct)
|
||||
{
|
||||
iter->start = fields;
|
||||
iter->pos = fields;
|
||||
iter->required_field_index = 0;
|
||||
iter->dest_struct = dest_struct;
|
||||
iter->pData = (char*)dest_struct + iter->pos->data_offset;
|
||||
iter->pSize = (char*)iter->pData + iter->pos->size_offset;
|
||||
|
||||
return (iter->pos->tag != 0);
|
||||
}
|
||||
|
||||
bool pb_field_iter_next(pb_field_iter_t *iter)
|
||||
{
|
||||
const pb_field_t *prev_field = iter->pos;
|
||||
|
||||
if (prev_field->tag == 0)
|
||||
{
|
||||
/* Handle empty message types, where the first field is already the terminator.
|
||||
* In other cases, the iter->pos never points to the terminator. */
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->pos++;
|
||||
|
||||
if (iter->pos->tag == 0)
|
||||
{
|
||||
/* Wrapped back to beginning, reinitialize */
|
||||
(void)pb_field_iter_begin(iter, iter->start, iter->dest_struct);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increment the pointers based on previous field size */
|
||||
size_t prev_size = prev_field->data_size;
|
||||
|
||||
if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC &&
|
||||
PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED)
|
||||
{
|
||||
/* In static arrays, the data_size tells the size of a single entry and
|
||||
* array_size is the number of entries */
|
||||
prev_size *= prev_field->array_size;
|
||||
}
|
||||
else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER)
|
||||
{
|
||||
/* Pointer fields always have a constant size in the main structure.
|
||||
* The data_size only applies to the dynamically allocated area. */
|
||||
prev_size = sizeof(void*);
|
||||
}
|
||||
|
||||
if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED)
|
||||
{
|
||||
/* Count the required fields, in order to check their presence in the
|
||||
* decoder. */
|
||||
iter->required_field_index++;
|
||||
}
|
||||
|
||||
iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
|
||||
iter->pSize = (char*)iter->pData + iter->pos->size_offset;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)
|
||||
{
|
||||
const pb_field_t *start = iter->pos;
|
||||
|
||||
do {
|
||||
if (iter->pos->tag == tag &&
|
||||
PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
|
||||
{
|
||||
/* Found the wanted field */
|
||||
return true;
|
||||
}
|
||||
|
||||
(void)pb_field_iter_next(iter);
|
||||
} while (iter->pos != start);
|
||||
|
||||
/* Searched all the way back to start, and found nothing. */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
42
components/external/nanopb/pb_common.h
vendored
Normal file
42
components/external/nanopb/pb_common.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c.
|
||||
* These functions are rarely needed by applications directly.
|
||||
*/
|
||||
|
||||
#ifndef PB_COMMON_H_INCLUDED
|
||||
#define PB_COMMON_H_INCLUDED
|
||||
|
||||
#include "pb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Iterator for pb_field_t list */
|
||||
struct pb_field_iter_s {
|
||||
const pb_field_t *start; /* Start of the pb_field_t array */
|
||||
const pb_field_t *pos; /* Current position of the iterator */
|
||||
unsigned required_field_index; /* Zero-based index that counts only the required fields */
|
||||
void *dest_struct; /* Pointer to start of the structure */
|
||||
void *pData; /* Pointer to current field value */
|
||||
void *pSize; /* Pointer to count/has field */
|
||||
};
|
||||
typedef struct pb_field_iter_s pb_field_iter_t;
|
||||
|
||||
/* Initialize the field iterator structure to beginning.
|
||||
* Returns false if the message type is empty. */
|
||||
bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct);
|
||||
|
||||
/* Advance the iterator to the next field.
|
||||
* Returns false when the iterator wraps back to the first field. */
|
||||
bool pb_field_iter_next(pb_field_iter_t *iter);
|
||||
|
||||
/* Advance the iterator until it points at a field with the given tag.
|
||||
* Returns false if no such field exists. */
|
||||
bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1165
components/external/nanopb/pb_decode.c
vendored
Normal file
1165
components/external/nanopb/pb_decode.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
149
components/external/nanopb/pb_decode.h
vendored
Normal file
149
components/external/nanopb/pb_decode.h
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c.
|
||||
* The main function is pb_decode. You also need an input stream, and the
|
||||
* field descriptions created by nanopb_generator.py.
|
||||
*/
|
||||
|
||||
#ifndef PB_DECODE_H_INCLUDED
|
||||
#define PB_DECODE_H_INCLUDED
|
||||
|
||||
#include "pb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Structure for defining custom input streams. You will need to provide
|
||||
* a callback function to read the bytes from your storage, which can be
|
||||
* for example a file or a network socket.
|
||||
*
|
||||
* The callback must conform to these rules:
|
||||
*
|
||||
* 1) Return false on IO errors. This will cause decoding to abort.
|
||||
* 2) You can use state to store your own data (e.g. buffer pointer),
|
||||
* and rely on pb_read to verify that no-body reads past bytes_left.
|
||||
* 3) Your callback may be used with substreams, in which case bytes_left
|
||||
* is different than from the main stream. Don't use bytes_left to compute
|
||||
* any pointers.
|
||||
*/
|
||||
struct pb_istream_s
|
||||
{
|
||||
#ifdef PB_BUFFER_ONLY
|
||||
/* Callback pointer is not used in buffer-only configuration.
|
||||
* Having an int pointer here allows binary compatibility but
|
||||
* gives an error if someone tries to assign callback function.
|
||||
*/
|
||||
int *callback;
|
||||
#else
|
||||
bool (*callback)(pb_istream_t *stream, uint8_t *buf, size_t count);
|
||||
#endif
|
||||
|
||||
void *state; /* Free field for use by callback implementation */
|
||||
size_t bytes_left;
|
||||
|
||||
#ifndef PB_NO_ERRMSG
|
||||
const char *errmsg;
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************
|
||||
* Main decoding functions *
|
||||
***************************/
|
||||
|
||||
/* Decode a single protocol buffers message from input stream into a C structure.
|
||||
* Returns true on success, false on any failure.
|
||||
* The actual struct pointed to by dest must match the description in fields.
|
||||
* Callback fields of the destination structure must be initialized by caller.
|
||||
* All other fields will be initialized by this function.
|
||||
*
|
||||
* Example usage:
|
||||
* MyMessage msg = {};
|
||||
* uint8_t buffer[64];
|
||||
* pb_istream_t stream;
|
||||
*
|
||||
* // ... read some data into buffer ...
|
||||
*
|
||||
* stream = pb_istream_from_buffer(buffer, count);
|
||||
* pb_decode(&stream, MyMessage_fields, &msg);
|
||||
*/
|
||||
bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
/* Same as pb_decode, except does not initialize the destination structure
|
||||
* to default values. This is slightly faster if you need no default values
|
||||
* and just do memset(struct, 0, sizeof(struct)) yourself.
|
||||
*
|
||||
* This can also be used for 'merging' two messages, i.e. update only the
|
||||
* fields that exist in the new message.
|
||||
*
|
||||
* Note: If this function returns with an error, it will not release any
|
||||
* dynamically allocated fields. You will need to call pb_release() yourself.
|
||||
*/
|
||||
bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
/* Same as pb_decode, except expects the stream to start with the message size
|
||||
* encoded as varint. Corresponds to parseDelimitedFrom() in Google's
|
||||
* protobuf API.
|
||||
*/
|
||||
bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
|
||||
|
||||
#ifdef PB_ENABLE_MALLOC
|
||||
/* Release any allocated pointer fields. If you use dynamic allocation, you should
|
||||
* call this for any successfully decoded message when you are done with it. If
|
||||
* pb_decode() returns with an error, the message is already released.
|
||||
*/
|
||||
void pb_release(const pb_field_t fields[], void *dest_struct);
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************
|
||||
* Functions for manipulating streams *
|
||||
**************************************/
|
||||
|
||||
/* Create an input stream for reading from a memory buffer.
|
||||
*
|
||||
* Alternatively, you can use a custom stream that reads directly from e.g.
|
||||
* a file or a network socket.
|
||||
*/
|
||||
pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize);
|
||||
|
||||
/* Function to read from a pb_istream_t. You can use this if you need to
|
||||
* read some custom header data, or to read data in field callbacks.
|
||||
*/
|
||||
bool pb_read(pb_istream_t *stream, uint8_t *buf, size_t count);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Helper functions for writing field callbacks *
|
||||
************************************************/
|
||||
|
||||
/* Decode the tag for the next field in the stream. Gives the wire type and
|
||||
* field tag. At end of the message, returns false and sets eof to true. */
|
||||
bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof);
|
||||
|
||||
/* Skip the field payload data, given the wire type. */
|
||||
bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type);
|
||||
|
||||
/* Decode an integer in the varint format. This works for bool, enum, int32,
|
||||
* int64, uint32 and uint64 field types. */
|
||||
bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest);
|
||||
|
||||
/* Decode an integer in the zig-zagged svarint format. This works for sint32
|
||||
* and sint64. */
|
||||
bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest);
|
||||
|
||||
/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to
|
||||
* a 4-byte wide C variable. */
|
||||
bool pb_decode_fixed32(pb_istream_t *stream, void *dest);
|
||||
|
||||
/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to
|
||||
* a 8-byte wide C variable. */
|
||||
bool pb_decode_fixed64(pb_istream_t *stream, void *dest);
|
||||
|
||||
/* Make a limited-length substream for reading a PB_WT_STRING field. */
|
||||
bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream);
|
||||
void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
664
components/external/nanopb/pb_encode.c
vendored
Normal file
664
components/external/nanopb/pb_encode.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
154
components/external/nanopb/pb_encode.h
vendored
Normal file
154
components/external/nanopb/pb_encode.h
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c.
|
||||
* The main function is pb_encode. You also need an output stream, and the
|
||||
* field descriptions created by nanopb_generator.py.
|
||||
*/
|
||||
|
||||
#ifndef PB_ENCODE_H_INCLUDED
|
||||
#define PB_ENCODE_H_INCLUDED
|
||||
|
||||
#include "pb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Structure for defining custom output streams. You will need to provide
|
||||
* a callback function to write the bytes to your storage, which can be
|
||||
* for example a file or a network socket.
|
||||
*
|
||||
* The callback must conform to these rules:
|
||||
*
|
||||
* 1) Return false on IO errors. This will cause encoding to abort.
|
||||
* 2) You can use state to store your own data (e.g. buffer pointer).
|
||||
* 3) pb_write will update bytes_written after your callback runs.
|
||||
* 4) Substreams will modify max_size and bytes_written. Don't use them
|
||||
* to calculate any pointers.
|
||||
*/
|
||||
struct pb_ostream_s
|
||||
{
|
||||
#ifdef PB_BUFFER_ONLY
|
||||
/* Callback pointer is not used in buffer-only configuration.
|
||||
* Having an int pointer here allows binary compatibility but
|
||||
* gives an error if someone tries to assign callback function.
|
||||
* Also, NULL pointer marks a 'sizing stream' that does not
|
||||
* write anything.
|
||||
*/
|
||||
int *callback;
|
||||
#else
|
||||
bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count);
|
||||
#endif
|
||||
void *state; /* Free field for use by callback implementation. */
|
||||
size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */
|
||||
size_t bytes_written; /* Number of bytes written so far. */
|
||||
|
||||
#ifndef PB_NO_ERRMSG
|
||||
const char *errmsg;
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************
|
||||
* Main encoding functions *
|
||||
***************************/
|
||||
|
||||
/* Encode a single protocol buffers message from C structure into a stream.
|
||||
* Returns true on success, false on any failure.
|
||||
* The actual struct pointed to by src_struct must match the description in fields.
|
||||
* All required fields in the struct are assumed to have been filled in.
|
||||
*
|
||||
* Example usage:
|
||||
* MyMessage msg = {};
|
||||
* uint8_t buffer[64];
|
||||
* pb_ostream_t stream;
|
||||
*
|
||||
* msg.field1 = 42;
|
||||
* stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
||||
* pb_encode(&stream, MyMessage_fields, &msg);
|
||||
*/
|
||||
bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/* Same as pb_encode, but prepends the length of the message as a varint.
|
||||
* Corresponds to writeDelimitedTo() in Google's protobuf API.
|
||||
*/
|
||||
bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/* Encode the message to get the size of the encoded data, but do not store
|
||||
* the data. */
|
||||
bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
/**************************************
|
||||
* Functions for manipulating streams *
|
||||
**************************************/
|
||||
|
||||
/* Create an output stream for writing into a memory buffer.
|
||||
* The number of bytes written can be found in stream.bytes_written after
|
||||
* encoding the message.
|
||||
*
|
||||
* Alternatively, you can use a custom stream that writes directly to e.g.
|
||||
* a file or a network socket.
|
||||
*/
|
||||
pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize);
|
||||
|
||||
/* Pseudo-stream for measuring the size of a message without actually storing
|
||||
* the encoded data.
|
||||
*
|
||||
* Example usage:
|
||||
* MyMessage msg = {};
|
||||
* pb_ostream_t stream = PB_OSTREAM_SIZING;
|
||||
* pb_encode(&stream, MyMessage_fields, &msg);
|
||||
* printf("Message size is %d\n", stream.bytes_written);
|
||||
*/
|
||||
#ifndef PB_NO_ERRMSG
|
||||
#define PB_OSTREAM_SIZING {0,0,0,0,0}
|
||||
#else
|
||||
#define PB_OSTREAM_SIZING {0,0,0,0}
|
||||
#endif
|
||||
|
||||
/* Function to write into a pb_ostream_t stream. You can use this if you need
|
||||
* to append or prepend some custom headers to the message.
|
||||
*/
|
||||
bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Helper functions for writing field callbacks *
|
||||
************************************************/
|
||||
|
||||
/* Encode field header based on type and field number defined in the field
|
||||
* structure. Call this from the callback before writing out field contents. */
|
||||
bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field);
|
||||
|
||||
/* Encode field header by manually specifing wire type. You need to use this
|
||||
* if you want to write out packed arrays from a callback field. */
|
||||
bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number);
|
||||
|
||||
/* Encode an integer in the varint format.
|
||||
* This works for bool, enum, int32, int64, uint32 and uint64 field types. */
|
||||
bool pb_encode_varint(pb_ostream_t *stream, uint64_t value);
|
||||
|
||||
/* Encode an integer in the zig-zagged svarint format.
|
||||
* This works for sint32 and sint64. */
|
||||
bool pb_encode_svarint(pb_ostream_t *stream, int64_t value);
|
||||
|
||||
/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */
|
||||
bool pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size);
|
||||
|
||||
/* Encode a fixed32, sfixed32 or float value.
|
||||
* You need to pass a pointer to a 4-byte wide C variable. */
|
||||
bool pb_encode_fixed32(pb_ostream_t *stream, const void *value);
|
||||
|
||||
/* Encode a fixed64, sfixed64 or double value.
|
||||
* You need to pass a pointer to a 8-byte wide C variable. */
|
||||
bool pb_encode_fixed64(pb_ostream_t *stream, const void *value);
|
||||
|
||||
/* Encode a submessage field.
|
||||
* You need to pass the pb_field_t array and pointer to struct, just like
|
||||
* with pb_encode(). This internally encodes the submessage twice, first to
|
||||
* calculate message size and then to actually write it out.
|
||||
*/
|
||||
bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
13
examples/nanopb/SConscript
Normal file
13
examples/nanopb/SConscript
Normal file
@@ -0,0 +1,13 @@
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
from building import *
|
||||
|
||||
src = Split('''
|
||||
simple.c
|
||||
simple.pb.c
|
||||
''')
|
||||
CPPPATH = [RTT_ROOT + '/examples/nanopb']
|
||||
|
||||
group = DefineGroup('Nanopb_test', src, depend = ['RT_USING_NANOPB'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
73
examples/nanopb/simple.c
Normal file
73
examples/nanopb/simple.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <rthw.h>
|
||||
#include <stm32f10x.h>
|
||||
#include <pb_encode.h>
|
||||
#include <pb_decode.h>
|
||||
#include "simple.pb.h"
|
||||
|
||||
int nanopb_test()
|
||||
{
|
||||
/* This is the buffer where we will store our message. */
|
||||
uint8_t buffer[128];
|
||||
size_t message_length;
|
||||
bool status;
|
||||
|
||||
/* Encode our message */
|
||||
{
|
||||
/* 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! */
|
||||
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;
|
||||
|
||||
/* Then just check for any errors.. */
|
||||
if (!status)
|
||||
{
|
||||
rt_kprintf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
{
|
||||
/* Allocate space for the decoded message. */
|
||||
SimpleMessage message;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
rt_kprintf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print the data contained in the message. */
|
||||
rt_kprintf("Your lucky number was %d!\n", message.lucky_number);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <finsh.h>
|
||||
FINSH_FUNCTION_EXPORT(nanopb_test, nanopb encode/decode test.)
|
||||
#endif
|
||||
1
examples/nanopb/simple.options
Normal file
1
examples/nanopb/simple.options
Normal file
@@ -0,0 +1 @@
|
||||
SimpleMessage.name max_size:16
|
||||
18
examples/nanopb/simple.pb.c
Normal file
18
examples/nanopb/simple.pb.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.3.1 at Tue Mar 10 01:16:15 2015. */
|
||||
|
||||
#include "simple.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
const pb_field_t SimpleMessage_fields[3] = {
|
||||
PB_FIELD( 1, INT32 , REQUIRED, STATIC , FIRST, SimpleMessage, lucky_number, lucky_number, 0),
|
||||
PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, SimpleMessage, name, lucky_number, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
||||
45
examples/nanopb/simple.pb.h
Normal file
45
examples/nanopb/simple.pb.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.3.1 at Tue Mar 10 01:16:15 2015. */
|
||||
|
||||
#ifndef PB_SIMPLE_PB_H_INCLUDED
|
||||
#define PB_SIMPLE_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 30
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
/* Struct definitions */
|
||||
typedef PB_BYTES_ARRAY_T(16) SimpleMessage_name_t;
|
||||
|
||||
typedef struct _SimpleMessage {
|
||||
int32_t lucky_number;
|
||||
SimpleMessage_name_t name;
|
||||
} SimpleMessage;
|
||||
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define SimpleMessage_init_default {0, {0, {0}}}
|
||||
#define SimpleMessage_init_zero {0, {0, {0}}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define SimpleMessage_lucky_number_tag 1
|
||||
#define SimpleMessage_name_tag 2
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t SimpleMessage_fields[3];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define SimpleMessage_size 29
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
10
examples/nanopb/simple.proto
Normal file
10
examples/nanopb/simple.proto
Normal file
@@ -0,0 +1,10 @@
|
||||
// A very simple protocol definition, consisting of only
|
||||
// one message.
|
||||
|
||||
message SimpleMessage {
|
||||
required int32 lucky_number = 1;
|
||||
required bytes name = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user