mirror of https://github.com/ArduPilot/ardupilot
184 lines
4.4 KiB
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++
|
|
}
|