ardupilot/libraries/APM_BinComm/protocol/protogen.awk
DrZiplok@gmail.com c0c28f8eae Recover 256 bytes of RAM by making the packet transmission code smarter. Now we emit the packet directly from the procedure parameters, rather than wasting time and space packing it into a temporary buffer.
Revert the buffer overflow test until I can work out what James was doing with it.

Don't try to send a text message in response to a message we don't like; we should probably implement a NAK message instead.

Improve the text string sender a bit.  We need to fix the protocol generator for this to be less sucky on the send side.


git-svn-id: https://arducopter.googlecode.com/svn/trunk@827 f9c3cf11-9bcb-44bc-f272-b75c42450872
2010-11-11 07:16:32 +00:00

184 lines
4.4 KiB
Awk

#
# Process the protocol specification and emit functions to pack and unpack buffers.
#
# See protocol.def for a description of the definition format.
#
BEGIN {
printf("//\n// THIS FILE WAS AUTOMATICALLY GENERATED - DO NOT EDIT\n//\n")
printf("/// @file protocol.h\n")
printf("#pragma pack(push)\n");
printf("#pragma pack(1)\n");
currentMessage = ""
structureCount = 0
}
END {
# finalise the last message definition
EMIT_MESSAGE()
#
# emit the MessageID enum
#
# XXX it would be elegant to sort the array here, but not
# everyone has GNU awk.
#
printf("\n//////////////////////////////////////////////////////////////////////\n")
printf("/// Message ID values\n")
printf("enum MessageID {\n")
for (opcode in opcodes) {
printf("\t%s = 0x%x,\n", opcodes[opcode], opcode)
}
printf("\tMSG_ANY = 0xfe,\n")
printf("\tMSG_NULL = 0xff\n")
printf("};\n")
printf("\n//////////////////////////////////////////////////////////////////////\n")
printf("/// Message buffer sizing\n")
printf("union _binCommBufferSizer {\n");
for (i = 0; i < structureCount; i++) {
printf("\tstruct %s %s;\n", structs[i], structs[i]);
}
printf("};\n");
printf("#define BINCOMM_MAX_MESSAGE_SIZE sizeof(union _binCommBufferSizer)\n\n");
printf("#pragma pack(pop)\n")
}
#
# Emit definitions for one message
#
function EMIT_MESSAGE(payloadSize)
{
if (currentMessage != "") {
printf("\n//////////////////////////////////////////////////////////////////////\n")
printf("/// @name %s \n//@{\n\n", currentMessage)
#
# emit a structure defining the message payload
#
printf("/// Structure describing the payload section of the %s message\n", currentMessage)
printf("struct %s {\n", tolower(currentMessage))
for (i = 0; i < fieldCount; i++) {
printf("\t%s %s", types[i], names[i])
if (counts[i])
printf("[%s]", counts[i])
printf(";\n")
}
printf("};\n\n")
#
# Record the structure name for later use sizing the receive buffer.
#
structs[structureCount] = tolower(currentMessage);
structureCount++;
#
# emit a routine to emit the message payload from a set of variables
#
printf("/// Send a %s message\n", currentMessage)
printf("inline void\nsend_%s(\n", tolower(currentMessage))
for (i = 0; i < fieldCount; i++) {
if (counts[i]) {
printf("\tconst %s (&%s)[%d]", types[i], names[i], counts[i])
} else {
printf("\tconst %s %s", types[i], names[i])
}
if (i < (fieldCount -1))
printf(",\n");
}
printf(")\n{\n")
printf("\t_startMessage(%s,", currentMessage);
for (i = 0; i < fieldCount; i++) {
if (counts[i]) {
printf("\n\t\t(sizeof(%s[0]) * %d) +", names[i], counts[i]);
} else {
printf("\n\t\tsizeof(%s) +", names[i]);
}
}
printf(" 0);\n");
for (i = 0; i < fieldCount; i++) {
if (counts[i]) {
printf("\t_emit(%s, %s);\n", names[i], counts[i])
} else {
printf("\t_emit(%s);\n", names[i])
}
}
printf("\t_endMessage();\n")
printf("};\n\n")
#
# emit a routine to unpack the current message into a set of variables
#
printf("/// Unpack a %s message\n", currentMessage)
printf("inline void\nunpack_%s(\n", tolower(currentMessage))
for (i = 0; i < fieldCount; i++) {
if (counts[i]) {
printf("\t%s (&%s)[%d]", types[i], names[i], counts[i])
} else {
printf("\t%s &%s", types[i], names[i])
}
if (i < (fieldCount -1))
printf(",\n");
}
printf(")\n{\n")
printf("\tuint8_t *__p = &_decodeBuf.payload[0];\n")
for (i = 0; i < fieldCount; i++) {
if (counts[i]) {
printf("\t_unpack(__p, %s, %s);\n", names[i], counts[i])
} else {
printf("\t_unpack(__p, %s);\n", names[i])
}
}
printf("};\n")
# close the Doxygen group
printf("//@}\n")
}
}
# skip lines containing comments
$1=="#" {
next
}
#
# process a new message declaration
#
$1=="message" {
# emit any previous message
EMIT_MESSAGE()
# save the current opcode and message name
currentOpcode = $2
currentMessage = $3
opcodes[$2] = $3
# set up for the coming fields
fieldCount = 0
delete types
delete names
delete counts
next
}
#
# process a field inside a message definition
#
NF >= 2 {
# save the field definition
types[fieldCount] = $1
names[fieldCount] = $2
# if an array size was supplied, save it
if (NF >= 3) {
counts[fieldCount] = $3
}
fieldCount++
}