Document the .options file usage.
Also add note about the 'packed' message option being incompatible with CPUs that do not support unaligned access. Update issue 12 Status: FixedInGit Update issue 77 Status: FixedInGit
This commit is contained in:
@@ -10,47 +10,40 @@ The things outlined here are the underlying concepts of the nanopb design.
|
||||
|
||||
Proto files
|
||||
===========
|
||||
All Protocol Buffers implementations use .proto files to describe the message format.
|
||||
The point of these files is to be a portable interface description language.
|
||||
All Protocol Buffers implementations use .proto files to describe the message
|
||||
format. The point of these files is to be a portable interface description
|
||||
language.
|
||||
|
||||
Compiling .proto files for nanopb
|
||||
---------------------------------
|
||||
Nanopb uses the Google's protoc compiler to parse the .proto file, and then a python script to generate the C header and source code from it::
|
||||
Nanopb uses the Google's protoc compiler to parse the .proto file, and then a
|
||||
python script to generate the C header and source code from it::
|
||||
|
||||
user@host:~$ protoc -omessage.pb message.proto
|
||||
user@host:~$ python ../generator/nanopb_generator.py message.pb
|
||||
Writing to message.h and message.c
|
||||
user@host:~$
|
||||
|
||||
Compiling .proto files with nanopb options
|
||||
------------------------------------------
|
||||
Nanopb defines two extensions for message fields described in .proto files: *max_size* and *max_count*.
|
||||
These are the maximum size of a string and maximum count of items in an array::
|
||||
Modifying generator behaviour
|
||||
-----------------------------
|
||||
Using generator options, you can set maximum sizes for fields in order to
|
||||
allocate them statically. The preferred way to do this is to create an .options
|
||||
file with the same name as your .proto file::
|
||||
|
||||
required string name = 1 [(nanopb).max_size = 40];
|
||||
repeated PhoneNumber phone = 4 [(nanopb).max_count = 5];
|
||||
# Foo.proto
|
||||
message Foo {
|
||||
required string name = 1;
|
||||
}
|
||||
|
||||
To use these extensions, you need to place an import statement in the beginning of the file::
|
||||
::
|
||||
|
||||
import "nanopb.proto";
|
||||
# Foo.options
|
||||
Foo.name max_size:16
|
||||
|
||||
This file, in turn, requires the file *google/protobuf/descriptor.proto*. This is usually installed under */usr/include*. Therefore, to compile a .proto file which uses options, use a protoc command similar to::
|
||||
|
||||
protoc -I/usr/include -Inanopb/generator -I. -omessage.pb message.proto
|
||||
|
||||
The options can be defined in file, message and field scopes::
|
||||
|
||||
option (nanopb_fileopt).max_size = 20; // File scope
|
||||
message Message
|
||||
{
|
||||
option (nanopb_msgopt).max_size = 30; // Message scope
|
||||
required string fieldsize = 1 [(nanopb).max_size = 40]; // Field scope
|
||||
}
|
||||
|
||||
It is also possible to give the options on command line, but then they will affect the whole file. For example::
|
||||
|
||||
user@host:~$ python ../generator/nanopb_generator.py -s 'max_size: 20' message.pb
|
||||
For more information on this, see the `Proto file options`_ section in the
|
||||
reference manual.
|
||||
|
||||
.. _`Proto file options`: reference.html#proto-file-options
|
||||
|
||||
Streams
|
||||
=======
|
||||
|
||||
@@ -6,31 +6,160 @@ Nanopb: API reference
|
||||
|
||||
.. contents ::
|
||||
|
||||
|
||||
|
||||
|
||||
Compilation options
|
||||
===================
|
||||
The following options can be specified using -D switch given to the C compiler:
|
||||
The following options can be specified using -D switch given to the C compiler
|
||||
when compiling the nanopb library and applications using it. You must have the
|
||||
same settings for the nanopb library and all code that includes pb.h.
|
||||
|
||||
============================ ================================================================================================
|
||||
__BIG_ENDIAN__ Set this if your platform stores integers and floats in big-endian format.
|
||||
Mixed-endian systems (different layout for ints and floats) are currently not supported.
|
||||
NANOPB_INTERNALS Set this to expose the field encoder functions that are hidden since nanopb-0.1.3.
|
||||
PB_MAX_REQUIRED_FIELDS Maximum number of required fields to check for presence. Default value is 64. Increases stack
|
||||
usage 1 byte per every 8 fields. Compiler warning will tell if you need this.
|
||||
PB_FIELD_16BIT Add support for tag numbers > 255 and fields larger than 255 bytes or 255 array entries.
|
||||
Increases code size 3 bytes per each field. Compiler error will tell if you need this.
|
||||
PB_FIELD_32BIT Add support for tag numbers > 65535 and fields larger than 65535 bytes or 65535 array entries.
|
||||
Increases code size 9 bytes per each field. Compiler error will tell if you need this.
|
||||
PB_NO_ERRMSG Disables the support for error messages; only error information is the true/false return value.
|
||||
Decreases the code size by a few hundred bytes.
|
||||
PB_BUFFER_ONLY Disables the support for custom streams. Only supports encoding to memory buffers.
|
||||
Speeds up execution and decreases code size slightly.
|
||||
PB_OLD_CALLBACK_STYLE Use the old function signature (void\* instead of void\*\*) for callback fields. This was the
|
||||
============================ ================================================
|
||||
__BIG_ENDIAN__ Set this if your platform stores integers and
|
||||
floats in big-endian format. Mixed-endian
|
||||
systems (different layout for ints and floats)
|
||||
are currently not supported.
|
||||
NANOPB_INTERNALS Set this to expose the field encoder functions
|
||||
that are hidden since nanopb-0.1.3.
|
||||
PB_MAX_REQUIRED_FIELDS Maximum number of required fields to check for
|
||||
presence. Default value is 64. Increases stack
|
||||
usage 1 byte per every 8 fields. Compiler
|
||||
warning will tell if you need this.
|
||||
PB_FIELD_16BIT Add support for tag numbers > 255 and fields
|
||||
larger than 255 bytes or 255 array entries.
|
||||
Increases code size 3 bytes per each field.
|
||||
Compiler error will tell if you need this.
|
||||
PB_FIELD_32BIT Add support for tag numbers > 65535 and fields
|
||||
larger than 65535 bytes or 65535 array entries.
|
||||
Increases code size 9 bytes per each field.
|
||||
Compiler error will tell if you need this.
|
||||
PB_NO_ERRMSG Disables the support for error messages; only
|
||||
error information is the true/false return
|
||||
value. Decreases the code size by a few hundred
|
||||
bytes.
|
||||
PB_BUFFER_ONLY Disables the support for custom streams. Only
|
||||
supports encoding and decoding with memory
|
||||
buffers. Speeds up execution and decreases code
|
||||
size slightly.
|
||||
PB_OLD_CALLBACK_STYLE Use the old function signature (void\* instead
|
||||
of void\*\*) for callback fields. This was the
|
||||
default until nanopb-0.2.1.
|
||||
============================ ================================================================================================
|
||||
============================ ================================================
|
||||
|
||||
The PB_MAX_REQUIRED_FIELDS, PB_FIELD_16BIT and PB_FIELD_32BIT settings allow
|
||||
raising some datatype limits to suit larger messages. Their need is recognized
|
||||
automatically by C-preprocessor #if-directives in the generated .pb.h files.
|
||||
The default setting is to use the smallest datatypes (least resources used).
|
||||
|
||||
|
||||
|
||||
|
||||
Proto file options
|
||||
==================
|
||||
The generator behaviour can be adjusted using these options, defined in the
|
||||
'nanopb.proto' file in the generator folder:
|
||||
|
||||
============================ ================================================
|
||||
max_size Allocated size for 'bytes' and 'string' fields.
|
||||
max_count Allocated number of entries in arrays
|
||||
('repeated' fields).
|
||||
type Type of the generated field. Default value
|
||||
is FT_DEFAULT, which selects automatically.
|
||||
You can use FT_CALLBACK, FT_STATIC or FT_IGNORE
|
||||
to force a callback field, a static field or
|
||||
to completely ignore the field.
|
||||
long_names Prefix the enum name to the enum value in
|
||||
definitions, i.e. 'EnumName_EnumValue'. Enabled
|
||||
by default.
|
||||
packed_struct Make the generated structures packed.
|
||||
NOTE: This cannot be used on CPUs that break
|
||||
on unaligned accesses to variables.
|
||||
============================ ================================================
|
||||
|
||||
These options can be defined for the .proto files before they are converted
|
||||
using the nanopb-generatory.py. There are three ways to define the options:
|
||||
|
||||
1. Using a separate .options file.
|
||||
This is the preferred way as of nanopb-0.2.1, because it has the best
|
||||
compatibility with other protobuf libraries.
|
||||
2. Defining the options on the command line of nanopb_generator.py.
|
||||
This only makes sense for settings that apply to a whole file.
|
||||
3. Defining the options in the .proto file using the nanopb extensions.
|
||||
This is the way used in nanopb-0.1, and will remain supported in the
|
||||
future. It however sometimes causes trouble when using the .proto file
|
||||
with other protobuf libraries.
|
||||
|
||||
The effect of the options is the same no matter how they are given. The most
|
||||
common purpose is to define maximum size for string fields in order to
|
||||
statically allocate them.
|
||||
|
||||
Defining the options in a .options file
|
||||
---------------------------------------
|
||||
The preferred way to define options is to have a separate file
|
||||
'myproto.options' in the same directory as the 'myproto.proto'. The
|
||||
generator will automatically search for this file and read the options from
|
||||
it. The file format is as follows:
|
||||
|
||||
* Lines starting with '#' or '//' are regarded as comments.
|
||||
* Blank lines are ignored.
|
||||
* All other lines should start with a field name pattern, followed by one or
|
||||
more options. For example: *"MyMessage.myfield max_size:5 max_count:10"*.
|
||||
* The field name pattern is matched against a string of form 'Message.field'.
|
||||
For nested messages, the string is 'Message.SubMessage.field'.
|
||||
* The field name pattern may use the notation recognized by Python fnmatch():
|
||||
- \* matches any part of string, like 'Message.\*' for all fields
|
||||
- \? matches any single character
|
||||
- [seq] matches any of characters 's', 'e' and 'q'
|
||||
- [!seq] matches any other character
|
||||
* The options are written as 'option_name:option_value' and several options
|
||||
can be defined on same line, separated by whitespace.
|
||||
* Options defined later in the file override the ones specified earlier, so
|
||||
it makes sense to define wildcard options first in the file and more specific
|
||||
ones later.
|
||||
|
||||
If preferred, the name of the options file can be set using the command line
|
||||
switch '-f' to nanopb_generator.py.
|
||||
|
||||
Defining the options on command line
|
||||
------------------------------------
|
||||
The nanopb_generator.py has a simple command line option '-s OPTION:VALUE'.
|
||||
The setting applies to the whole file that is being processed.
|
||||
|
||||
Defining the options in the .proto file
|
||||
---------------------------------------
|
||||
The .proto file format allows defining custom options for the fields.
|
||||
The nanopb library comes with 'nanopb.proto' which does exactly that, allowing
|
||||
you do define the options directly in the .proto file:
|
||||
|
||||
import "nanopb.proto";
|
||||
required string name = 1 [(nanopb).max_size = 40];
|
||||
repeated PhoneNumber phone = 4 [(nanopb).max_count = 5];
|
||||
|
||||
A small complication is that you have to set the include path of protoc so that
|
||||
nanopb.proto can be found. This file, in turn, requires the file
|
||||
*google/protobuf/descriptor.proto*. This is usually installed under
|
||||
*/usr/include*. Therefore, to compile a .proto file which uses options, use a
|
||||
protoc command similar to::
|
||||
|
||||
protoc -I/usr/include -Inanopb/generator -I. -omessage.pb message.proto
|
||||
|
||||
The options can be defined in file, message and field scopes::
|
||||
|
||||
option (nanopb_fileopt).max_size = 20; // File scope
|
||||
message Message
|
||||
{
|
||||
option (nanopb_msgopt).max_size = 30; // Message scope
|
||||
required string fieldsize = 1 [(nanopb).max_size = 40]; // Field scope
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The PB_MAX_REQUIRED_FIELDS, PB_FIELD_16BIT and PB_FIELD_32BIT settings allow raising some datatype limits to suit larger messages.
|
||||
Their need is recognized automatically by C-preprocessor #if-directives in the generated .pb.h files. The default setting is to use
|
||||
the smallest datatypes (least resources used).
|
||||
|
||||
pb.h
|
||||
====
|
||||
@@ -148,6 +277,16 @@ Protocol Buffers wire types. These are used with `pb_encode_tag`_. ::
|
||||
PB_WT_32BIT = 5
|
||||
} pb_wire_type_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pb_encode.h
|
||||
===========
|
||||
|
||||
@@ -297,6 +436,17 @@ In Protocol Buffers format, the submessage size must be written before the subme
|
||||
|
||||
If the submessage contains callback fields, the callback function might misbehave and write out a different amount of data on the second call. This situation is recognized and *false* is returned, but garbage will be written to the output before the problem is detected.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pb_decode.h
|
||||
===========
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ message NanoPBOptions {
|
||||
optional bool long_names = 4 [default = true];
|
||||
|
||||
// Add 'packed' attribute to generated structs.
|
||||
// Note: this cannot be used on CPUs that break on unaligned
|
||||
// accesses to variables.
|
||||
optional bool packed_struct = 5 [default = false];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user