You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.4 KiB
183 lines
4.4 KiB
# |
|
# 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++ |
|
}
|
|
|