mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-04 15:08:28 -04:00
71efe28851
Based on work done for the ArduStationM firmware and influenced by Randall Mackay's ArduCopter BinComm code. This is a work in progress; discussion is welcome. git-svn-id: https://arducopter.googlecode.com/svn/trunk@318 f9c3cf11-9bcb-44bc-f272-b75c42450872
174 lines
4.1 KiB
Awk
174 lines
4.1 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("#pragma pack(1)\n");
|
|
|
|
currentMessage = ""
|
|
}
|
|
|
|
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("#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")
|
|
|
|
#
|
|
# emit a routine to pack the message payload from a set of variables and send it
|
|
#
|
|
printf("/// Send a %s message\n", currentMessage)
|
|
printf("inline void\nBinComm::send_%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("\tuint8_t *p = &_encodeBuf.payload;\n")
|
|
payloadSize = 0;
|
|
for (i = 0; i < fieldCount; i++) {
|
|
if (counts[i]) {
|
|
printf("\t_pack(p, %s, %s);\n", names[i], counts[i])
|
|
payloadSize += sizes[i] * counts[i]
|
|
} else {
|
|
printf("\t_pack(p, %s);\n", names[i])
|
|
payloadSize += sizes[i]
|
|
}
|
|
}
|
|
printf("\t_encodeBuf.header.length = %s;\n", payloadSize)
|
|
printf("\t_encodeBuf.header.messageID = %s;\n", currentMessage)
|
|
printf("\t_encodeBuf.header.messageVersion = MSG_VERSION_1;\n")
|
|
printf("\t_sendMessage();\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\nBinComm::unpack_%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;\n")
|
|
for (i = 0; i < fieldCount; i++) {
|
|
if (counts[i]) {
|
|
printf("\t_unpack(p, %s, %s);\n", names[i], counts[i])
|
|
payloadSize += sizes[i] * counts[i]
|
|
} else {
|
|
printf("\t_unpack(p, %s);\n", names[i])
|
|
payloadSize += sizes[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 sizes
|
|
delete counts
|
|
|
|
next
|
|
}
|
|
|
|
#
|
|
# process a field inside a message definition
|
|
#
|
|
NF >= 2 {
|
|
|
|
# save the field definition
|
|
types[fieldCount] = $1
|
|
names[fieldCount] = $2
|
|
|
|
# guess the field size, note that we only support <inttypes.h> and "char"
|
|
sizes[fieldCount] = 1
|
|
if ($1 ~ ".*16.*")
|
|
sizes[fieldCount] = 2
|
|
if ($1 ~ ".*32.*")
|
|
sizes[fieldCount] = 4
|
|
|
|
# if an array size was supplied, save it
|
|
if (NF >= 3) {
|
|
counts[fieldCount] = $3
|
|
}
|
|
|
|
fieldCount++
|
|
}
|