Есть два подхода, которые обычно используются:
1) много #ifdefs
2) написать "драйверы" и убедиться, что другой код абстрагирован
Если вы работаете на похожих платформах, 1), вероятно, будет работать лучше для вас. Если платформы очень разные, то 2), вероятно, лучшая идея. Большинство реальных решений, которые я видел, используют подход #ifdef, но это быстро приводит к запутанному лабиринту кода, который может быть трудно изменить. Я бы порекомендовал что-то промежуточное, так как трудно проектировать драйверы в 2).
Типы должны быть указаны в файле types.h или использовать явные типы, такие как uint16_t. Мы определяем все наши собственные типы на основе абсолютов (U8, U16, U32, S8 ...), поскольку встроенные типы в C зависят от реализации. Этот файл затем изменяется при изменении архитектуры.