I have a serial protocol that defines messages like this:
(I know about byte order, and struct padding, and all of it matches between host and Teensy, so don't worry about that
Then I have a class for receiving messages that looks something like:
Can you see the bug?
buf is aligned at a 4 byte boundary (likely,) but the structure in the buffer starts at offset 2 within the buffer. This means that the uint32_t data member in the message structure is being accessed unaligned (2 bytes off its natural 4-byte alignment in memory.)
When this happens on Teensy3.5 and Teensy3.6 the CPU just takes some unaligned access interrupt and locks up. This of course works great on x86 (where alignment is, at worst, just a performance problem) and on smaller, older microcontrollers that have narrow busses and emulate 32-bit words through multiple access. The Teensy3.5 just happens to be in the middle of this gulf, and doesn't like unaligned accesses.
This would have been easier to debug if there was some obvious signal I could catch for the various exceptions.
Is there? Is there a vector I could implement for the unaligned access exception? Are there other exceptions (like null pointer deference, and so forth,) that I could reasonably catch and maybe print something out a serial port, so I could know what's going on rather than poking at a nonresponsive chip, adding LED and pin wiggles in my code until I can zero in on the problem?
Code:
struct SomeMessage {
uint32_t data1;
uint16_t data2;
uint16_t data3;
};
(I know about byte order, and struct padding, and all of it matches between host and Teensy, so don't worry about that
Then I have a class for receiving messages that looks something like:
Code:
class MessageParser {
public:
void receive() {
while (port.available() > 0) {
int ch = port.read();
buf[ptr] = ch;
if (ptr == 0 && ch == HEADER_CHAR) {
ptr = 1;
crc = 0;
} else if (ptr > 0) {
crc.update(ch);
++ptr;
if (ptr >= 2 && ptr == buf[1]+2) {
decode_message(buf[1], &buf[2], crc);
ptr = 0;
}
}
}
}
void decode_message(size_t size, void const *data) {
SomeMessage const &sm = *(SomeMessage const *)data;
... do stuff with sm ...
}
uint16_t crc_;
uint16_t ptr;
uint8_t buf[258];
};
Can you see the bug?
buf is aligned at a 4 byte boundary (likely,) but the structure in the buffer starts at offset 2 within the buffer. This means that the uint32_t data member in the message structure is being accessed unaligned (2 bytes off its natural 4-byte alignment in memory.)
When this happens on Teensy3.5 and Teensy3.6 the CPU just takes some unaligned access interrupt and locks up. This of course works great on x86 (where alignment is, at worst, just a performance problem) and on smaller, older microcontrollers that have narrow busses and emulate 32-bit words through multiple access. The Teensy3.5 just happens to be in the middle of this gulf, and doesn't like unaligned accesses.
This would have been easier to debug if there was some obvious signal I could catch for the various exceptions.
Is there? Is there a vector I could implement for the unaligned access exception? Are there other exceptions (like null pointer deference, and so forth,) that I could reasonably catch and maybe print something out a serial port, so I could know what's going on rather than poking at a nonresponsive chip, adding LED and pin wiggles in my code until I can zero in on the problem?