Лучше всего использовать ту же библиотеку журналов, о которой вы упомянули, но с кодами, специфичными для ОС (например, номер строки, имя файла, последовательная связь), отдельно от логического кода. Специфичный для ОС код должен содержаться в функциях или макросах, а затем вызываться из логического кода.
Пример:
#OS_LINE _LINE_
#OS_FILE _FILE_
#OS_SEND(a) Send(a)
int log(void)
{
char msg[50];
sprintf(msg, "line %i, %s", OS_LINE, OS_FILE);
OS_SEND(msg);
return 0;
}
При этом вы можете повторно использовать библиотеку, просто изменяя макросы, специфичные для ОС, для каждого устройства.