Code:
struct firmware_signature {
const tyb_board_model *model;
uint8_t magic[8];
};
static const struct firmware_signature signatures[] = {
{&_tyb_teensy_pp10_model, {0x0C, 0x94, 0x00, 0x7E, 0xFF, 0xCF, 0xF8, 0x94}},
{&_tyb_teensy_20_model, {0x0C, 0x94, 0x00, 0x3F, 0xFF, 0xCF, 0xF8, 0x94}},
{&_tyb_teensy_pp20_model, {0x0C, 0x94, 0x00, 0xFE, 0xFF, 0xCF, 0xF8, 0x94}},
{&_tyb_teensy_30_model, {0x38, 0x80, 0x04, 0x40, 0x82, 0x3F, 0x04, 0x00}},
{&_tyb_teensy_31_model, {0x30, 0x80, 0x04, 0x40, 0x82, 0x3F, 0x04, 0x00}},
{&_tyb_teensy_lc_model, {0x34, 0x80, 0x04, 0x40, 0x82, 0x3F, 0x00, 0x00}},
{0}
};
// Give it a firmware, get the model it was compiled for (or NULL)
const tyb_board_model *tyb_board_test_firmware(const tyb_firmware *f)
{
assert(f);
if (f->size < sizeof(signatures[0].magic))
return NULL;
/* Naive search with each board's signature, not pretty but unless
thousands of models appear this is good enough. */
for (size_t i = 0; i < f->size - sizeof(signatures[0].magic); i++) {
for (const struct firmware_signature *sig = signatures; sig->model; sig++) {
if (memcmp(f->image + i, sig->magic, sizeof(signatures[0].magic)) == 0)
return sig->model;
}
}
return NULL;
}
Of course, I can't guarantee that it's future-proof.