Move examples into subfolders, add READMEs
This commit is contained in:
@@ -1,14 +0,0 @@
|
||||
CFLAGS=-ansi -Wall -Werror -I .. -g -O0
|
||||
DEPS=../pb_decode.c ../pb_decode.h ../pb_encode.c ../pb_encode.h ../pb.h
|
||||
|
||||
all: server client
|
||||
|
||||
clean:
|
||||
rm -f server client fileproto.pb.c fileproto.pb.h
|
||||
|
||||
%: %.c $(DEPS) fileproto.pb.h fileproto.pb.c
|
||||
$(CC) $(CFLAGS) -o $@ $< ../pb_decode.c ../pb_encode.c fileproto.pb.c common.c
|
||||
|
||||
fileproto.pb.c fileproto.pb.h: fileproto.proto ../generator/nanopb_generator.py
|
||||
protoc -I. -I../generator -I/usr/include -ofileproto.pb $<
|
||||
python ../generator/nanopb_generator.py fileproto.pb
|
||||
@@ -1,22 +0,0 @@
|
||||
CFLAGS=-Wall -Werror -I .. -g -O0
|
||||
DEPS=double_conversion.c ../pb_decode.c ../pb_decode.h ../pb_encode.c ../pb_encode.h ../pb.h
|
||||
|
||||
all: run_tests
|
||||
|
||||
clean:
|
||||
rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h
|
||||
|
||||
test_conversions: test_conversions.c double_conversion.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
%: %.c $(DEPS) doubleproto.pb.h doubleproto.pb.c
|
||||
$(CC) $(CFLAGS) -o $@ $< double_conversion.c ../pb_decode.c ../pb_encode.c doubleproto.pb.c
|
||||
|
||||
doubleproto.pb.c doubleproto.pb.h: doubleproto.proto ../generator/nanopb_generator.py
|
||||
protoc -I. -I../generator -I/usr/include -odoubleproto.pb $<
|
||||
python ../generator/nanopb_generator.py doubleproto.pb
|
||||
|
||||
run_tests: test_conversions encode_double decode_double
|
||||
./test_conversions
|
||||
./encode_double | ./decode_double
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
CFLAGS=-ansi -Wall -Werror -I .. -g -O0
|
||||
DEPS=../pb_decode.c ../pb_decode.h ../pb_encode.c ../pb_encode.h ../pb.h
|
||||
|
||||
all: encode decode
|
||||
./encode 1 | ./decode
|
||||
./encode 2 | ./decode
|
||||
./encode 3 | ./decode
|
||||
|
||||
clean:
|
||||
rm -f encode unionproto.pb.h unionproto.pb.c
|
||||
|
||||
%: %.c $(DEPS) unionproto.pb.h unionproto.pb.c
|
||||
$(CC) $(CFLAGS) -o $@ $< ../pb_decode.c ../pb_encode.c unionproto.pb.c
|
||||
|
||||
unionproto.pb.h unionproto.pb.c: unionproto.proto ../generator/nanopb_generator.py
|
||||
protoc -I. -I../generator -I/usr/include -ounionproto.pb $<
|
||||
python ../generator/nanopb_generator.py unionproto.pb
|
||||
19
examples/network_server/Makefile
Normal file
19
examples/network_server/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
CFLAGS = -ansi -Wall -Werror -g -O0
|
||||
|
||||
# Path to the nanopb root folder
|
||||
NANOPB_DIR = ../..
|
||||
DEPS = $(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_decode.h \
|
||||
$(NANOPB_DIR)/pb_encode.c $(NANOPB_DIR)/pb_encode.h $(NANOPB_DIR)/pb.h
|
||||
CFLAGS += -I$(NANOPB_DIR)
|
||||
|
||||
all: server client
|
||||
|
||||
clean:
|
||||
rm -f server client fileproto.pb.c fileproto.pb.h
|
||||
|
||||
%: %.c $(DEPS) fileproto.pb.h fileproto.pb.c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_encode.c fileproto.pb.c common.c
|
||||
|
||||
fileproto.pb.c fileproto.pb.h: fileproto.proto $(NANOPB_DIR)/generator/nanopb_generator.py
|
||||
protoc -ofileproto.pb $<
|
||||
python $(NANOPB_DIR)/generator/nanopb_generator.py fileproto.pb
|
||||
60
examples/network_server/README
Normal file
60
examples/network_server/README
Normal file
@@ -0,0 +1,60 @@
|
||||
Nanopb example "network_server"
|
||||
===============================
|
||||
|
||||
This example demonstrates the use of nanopb to communicate over network
|
||||
connections. It consists of a server that sends file listings, and of
|
||||
a client that requests the file list from the server.
|
||||
|
||||
Example usage
|
||||
-------------
|
||||
|
||||
user@host:~/nanopb/examples/network_server$ make # Build the example
|
||||
protoc -ofileproto.pb fileproto.proto
|
||||
python ../../generator/nanopb_generator.py fileproto.pb
|
||||
Writing to fileproto.pb.h and fileproto.pb.c
|
||||
cc -ansi -Wall -Werror -I .. -g -O0 -I../.. -o server server.c
|
||||
../../pb_decode.c ../../pb_encode.c fileproto.pb.c common.c
|
||||
cc -ansi -Wall -Werror -I .. -g -O0 -I../.. -o client client.c
|
||||
../../pb_decode.c ../../pb_encode.c fileproto.pb.c common.c
|
||||
|
||||
user@host:~/nanopb/examples/network_server$ ./server & # Start the server on background
|
||||
[1] 24462
|
||||
|
||||
petteri@oddish:~/nanopb/examples/network_server$ ./client /bin # Request the server to list /bin
|
||||
Got connection.
|
||||
Listing directory: /bin
|
||||
1327119 bzdiff
|
||||
1327126 bzless
|
||||
1327147 ps
|
||||
1327178 ntfsmove
|
||||
1327271 mv
|
||||
1327187 mount
|
||||
1327259 false
|
||||
1327266 tempfile
|
||||
1327285 zfgrep
|
||||
1327165 gzexe
|
||||
1327204 nc.openbsd
|
||||
1327260 uname
|
||||
|
||||
|
||||
Details of implementation
|
||||
-------------------------
|
||||
fileproto.proto contains the portable Google Protocol Buffers protocol definition.
|
||||
It could be used as-is to implement a server or a client in any other language, for
|
||||
example Python or Java.
|
||||
|
||||
fileproto.options contains the nanopb-specific options for the protocol file. This
|
||||
sets the amount of space allocated for file names when decoding messages.
|
||||
|
||||
common.c/h contains functions that allow nanopb to read and write directly from
|
||||
network socket. This way there is no need to allocate a separate buffer to store
|
||||
the message.
|
||||
|
||||
server.c contains the code to open a listening socket, to respond to clients and
|
||||
to list directory contents.
|
||||
|
||||
client.c contains the code to connect to a server, to send a request and to print
|
||||
the response message.
|
||||
|
||||
The code is implemented using the POSIX socket api, but it should be easy enough
|
||||
to port into any other socket api, such as lwip.
|
||||
29
examples/using_double_on_avr/Makefile
Normal file
29
examples/using_double_on_avr/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
CFLAGS = -Wall -Werror -g -O0
|
||||
|
||||
# Path to the nanopb root directory
|
||||
NANOPB_DIR = ../..
|
||||
DEPS = double_conversion.c $(NANOPB_DIR)/pb.h \
|
||||
$(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_decode.h \
|
||||
$(NANOPB_DIR)/pb_encode.c $(NANOPB_DIR)/pb_encode.h
|
||||
CFLAGS += -I$(NANOPB_DIR)
|
||||
|
||||
all: run_tests
|
||||
|
||||
clean:
|
||||
rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h
|
||||
|
||||
test_conversions: test_conversions.c double_conversion.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
%: %.c $(DEPS) doubleproto.pb.h doubleproto.pb.c
|
||||
$(CC) $(CFLAGS) -o $@ $< double_conversion.c \
|
||||
$(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_encode.c doubleproto.pb.c
|
||||
|
||||
doubleproto.pb.c doubleproto.pb.h: doubleproto.proto $(NANOPB_DIR)/generator/nanopb_generator.py
|
||||
protoc -odoubleproto.pb $<
|
||||
python $(NANOPB_DIR)/generator/nanopb_generator.py doubleproto.pb
|
||||
|
||||
run_tests: test_conversions encode_double decode_double
|
||||
./test_conversions
|
||||
./encode_double | ./decode_double
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
Nanopb example "using_double_on_avr"
|
||||
====================================
|
||||
|
||||
Some processors/compilers, such as AVR-GCC, do not support the double
|
||||
datatype. Instead, they have sizeof(double) == 4. Because protocol
|
||||
binary format uses the double encoding directly, this causes trouble
|
||||
@@ -9,7 +12,7 @@ platforms. The file double_conversion.c provides functions that
|
||||
convert these values to/from floats, without relying on compiler
|
||||
support.
|
||||
|
||||
To use this method, you need to make two modifications to your code:
|
||||
To use this method, you need to make some modifications to your code:
|
||||
|
||||
1) Change all 'double' fields into 'fixed64' in the .proto.
|
||||
|
||||
@@ -17,6 +20,6 @@ To use this method, you need to make two modifications to your code:
|
||||
|
||||
3) Whenever reading a 'double' field, use double_to_float().
|
||||
|
||||
The conversion routines should be as accurate as the float datatype can
|
||||
The conversion routines are as accurate as the float datatype can
|
||||
be. Furthermore, they should handle all special values (NaN, inf, denormalized
|
||||
numbers) correctly. There are testcases in test_conversions.c.
|
||||
22
examples/using_union_messages/Makefile
Normal file
22
examples/using_union_messages/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
CFLAGS = -ansi -Wall -Werror -g -O0
|
||||
|
||||
# Path to the nanopb root folder
|
||||
NANOPB_DIR = ../..
|
||||
DEPS = $(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_decode.h \
|
||||
$(NANOPB_DIR)/pb_encode.c $(NANOPB_DIR)/pb_encode.h $(NANOPB_DIR)/pb.h
|
||||
CFLAGS += -I$(NANOPB_DIR)
|
||||
|
||||
all: encode decode
|
||||
./encode 1 | ./decode
|
||||
./encode 2 | ./decode
|
||||
./encode 3 | ./decode
|
||||
|
||||
clean:
|
||||
rm -f encode unionproto.pb.h unionproto.pb.c
|
||||
|
||||
%: %.c $(DEPS) unionproto.pb.h unionproto.pb.c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_encode.c unionproto.pb.c
|
||||
|
||||
unionproto.pb.h unionproto.pb.c: unionproto.proto $(NANOPB_DIR)/generator/nanopb_generator.py
|
||||
protoc -ounionproto.pb $<
|
||||
python $(NANOPB_DIR)/generator/nanopb_generator.py unionproto.pb
|
||||
52
examples/using_union_messages/README
Normal file
52
examples/using_union_messages/README
Normal file
@@ -0,0 +1,52 @@
|
||||
Nanopb example "using_union_messages"
|
||||
=====================================
|
||||
|
||||
Union messages is a common technique in Google Protocol Buffers used to
|
||||
represent a group of messages, only one of which is passed at a time.
|
||||
It is described in Google's documentation:
|
||||
https://developers.google.com/protocol-buffers/docs/techniques#union
|
||||
|
||||
This directory contains an example on how to encode and decode union messages
|
||||
with minimal memory usage. Usually, nanopb would allocate space to store
|
||||
all of the possible messages at the same time, even though at most one of
|
||||
them will be used at a time.
|
||||
|
||||
By using some of the lower level nanopb APIs, we can manually generate the
|
||||
top level message, so that we only need to allocate the one submessage that
|
||||
we actually want. Similarly when decoding, we can manually read the tag of
|
||||
the top level message, and only then allocate the memory for the submessage
|
||||
after we already know its type.
|
||||
|
||||
|
||||
Example usage
|
||||
-------------
|
||||
|
||||
Type `make` to run the example. It will build it and run commands like
|
||||
following:
|
||||
|
||||
./encode 1 | ./decode
|
||||
Got MsgType1: 42
|
||||
./encode 2 | ./decode
|
||||
Got MsgType2: true
|
||||
./encode 3 | ./decode
|
||||
Got MsgType3: 3 1415
|
||||
|
||||
This simply demonstrates that the "decode" program has correctly identified
|
||||
the type of the received message, and managed to decode it.
|
||||
|
||||
|
||||
Details of implementation
|
||||
-------------------------
|
||||
|
||||
unionproto.proto contains the protocol used in the example. It consists of
|
||||
three messages: MsgType1, MsgType2 and MsgType3, which are collected together
|
||||
into UnionMessage.
|
||||
|
||||
encode.c takes one command line argument, which should be a number 1-3. It
|
||||
then fills in and encodes the corresponding message, and writes it to stdout.
|
||||
|
||||
decode.c reads a UnionMessage from stdin. Then it calls the function
|
||||
decode_unionmessage_type() to determine the type of the message. After that,
|
||||
the corresponding message is decoded and the contents of it printed to the
|
||||
screen.
|
||||
|
||||
Reference in New Issue
Block a user