ardupilot/libraries/APM_BinComm/protocol/protogen.awk

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++
}