3 ms·
Was converting an avionics subsystem from Ada to C. It was a client application that had to talk to an Ada server, sending and receiving rather huge chunks of d
by tjr 17y ago
Was converting an avionics subsystem from Ada to C. It was a client application that had to talk to an Ada server, sending and receiving rather huge chunks of data, large, deeply nested, intricate structure types. The C structure type had to match the Ada type exactly, or else it wouldn't work.
I got it working fine on our desktop simulation, but running on the actual hardware it was consistently off. After extensive testing, I realized that it was a bug in the compiler for the target hardware, such that a very particular type of structure (something like, {int, char, float}) was being packed incorrectly, resulting in a 2-byte pad that shouldn't be there. If I reordered the structure elements, it was fine, but that particular grouping and order refused to work correctly.
It was GCC, so we could fix the compiler ourselves, right? Not really, as, for avionics systems the compiler has to be thoroughly qualified for avionics use, and changes equal requalification. I "fixed" it by storing the float as an array of characters, converting it to and from a real float type as we needed to use the data value.
Trivial, perhaps, but I was very excited to resolve the problem, after spending days barking up wrong trees. One usually expects that the problem is not in the compiler... :-)
- vicaya 17y agoWere you using GCC's __attribute__((__packed__))? Anyway, the standard way (to handle protocols) is to parse the thing not making any assumption of the struct layout.
- tjr 17y agoYes. The other structures all packed correctly. If I am understanding what you are saying, we really couldn't do that, as the server sent and expected to receive binary blobs of data; the only way to know what was what was to have a map of where the data elements were.
- joe_bleau 17y agoI like to use macros (in C) to spit out the structure size and offsets of each structure member over a serial port, in a format I can then cut-n-paste back into the source. This output consists of a bunch of (compile-time, when possible) assertions so that any changes to a structure break the build. These assertions go on both the embedded side and the PC server side, so any weird packing issues show up at compile time.