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:
Petteri Aimonen
2013-07-06 13:49:47 +03:00
parent 68dd0171bc
commit 6e9e532927
3 changed files with 192 additions and 47 deletions

View File

@@ -10,47 +10,40 @@ The things outlined here are the underlying concepts of the nanopb design.
Proto files Proto files
=========== ===========
All Protocol Buffers implementations use .proto files to describe the message format. All Protocol Buffers implementations use .proto files to describe the message
The point of these files is to be a portable interface description language. format. The point of these files is to be a portable interface description
language.
Compiling .proto files for nanopb 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:~$ protoc -omessage.pb message.proto
user@host:~$ python ../generator/nanopb_generator.py message.pb user@host:~$ python ../generator/nanopb_generator.py message.pb
Writing to message.h and message.c Writing to message.h and message.c
user@host:~$ user@host:~$
Compiling .proto files with nanopb options Modifying generator behaviour
------------------------------------------ -----------------------------
Nanopb defines two extensions for message fields described in .proto files: *max_size* and *max_count*. Using generator options, you can set maximum sizes for fields in order to
These are the maximum size of a string and maximum count of items in an array:: 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]; # Foo.proto
repeated PhoneNumber phone = 4 [(nanopb).max_count = 5]; 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";
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 # Foo.options
Foo.name max_size:16
For more information on this, see the `Proto file options`_ section in the
reference manual.
.. _`Proto file options`: reference.html#proto-file-options
Streams Streams
======= =======

View File

@@ -6,31 +6,160 @@ Nanopb: API reference
.. contents :: .. contents ::
Compilation options 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. __BIG_ENDIAN__ Set this if your platform stores integers and
Mixed-endian systems (different layout for ints and floats) are currently not supported. floats in big-endian format. Mixed-endian
NANOPB_INTERNALS Set this to expose the field encoder functions that are hidden since nanopb-0.1.3. systems (different layout for ints and floats)
PB_MAX_REQUIRED_FIELDS Maximum number of required fields to check for presence. Default value is 64. Increases stack are currently not supported.
usage 1 byte per every 8 fields. Compiler warning will tell if you need this. NANOPB_INTERNALS Set this to expose the field encoder functions
PB_FIELD_16BIT Add support for tag numbers > 255 and fields larger than 255 bytes or 255 array entries. that are hidden since nanopb-0.1.3.
Increases code size 3 bytes per each field. Compiler error will tell if you need this. PB_MAX_REQUIRED_FIELDS Maximum number of required fields to check for
PB_FIELD_32BIT Add support for tag numbers > 65535 and fields larger than 65535 bytes or 65535 array entries. presence. Default value is 64. Increases stack
Increases code size 9 bytes per each field. Compiler error will tell if you need this. usage 1 byte per every 8 fields. Compiler
PB_NO_ERRMSG Disables the support for error messages; only error information is the true/false return value. warning will tell if you need this.
Decreases the code size by a few hundred bytes. PB_FIELD_16BIT Add support for tag numbers > 255 and fields
PB_BUFFER_ONLY Disables the support for custom streams. Only supports encoding to memory buffers. larger than 255 bytes or 255 array entries.
Speeds up execution and decreases code size slightly. Increases code size 3 bytes per each field.
PB_OLD_CALLBACK_STYLE Use the old function signature (void\* instead of void\*\*) for callback fields. This was the 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. 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 pb.h
==== ====
@@ -148,6 +277,16 @@ Protocol Buffers wire types. These are used with `pb_encode_tag`_. ::
PB_WT_32BIT = 5 PB_WT_32BIT = 5
} pb_wire_type_t; } pb_wire_type_t;
pb_encode.h 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. 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 pb_decode.h
=========== ===========

View File

@@ -33,6 +33,8 @@ message NanoPBOptions {
optional bool long_names = 4 [default = true]; optional bool long_names = 4 [default = true];
// Add 'packed' attribute to generated structs. // 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]; optional bool packed_struct = 5 [default = false];
} }