PS, @Ceos, Holomino:
wegen eurer Anmerkungen von oben:
Grundsätzlich sind "klassische" C cstring Funktionen eher fehleranfällig als C++ std::string bzw. String-Methoden (0-Terminierung, Längenüberschreitung etc.), und noch nicht einmal originale <string.h> u/o <stdio.h> Funktionen verhalten sich hier immer identisch, logisch und/oder vorhersagbar.

Arduino String entspricht aber einem abgespeckten std::string samt vieler seiner Methoden, und für beide sind

String msg, s;
char cstr[30];
msg+= s;
msg+= (String)cstr;

völlig normale und legitime C++ Operationen, und Arduino arbeitet ja mit C++ und nicht mit C.

Da die endgültige Länge von msg bei mir zur Laufzeit aber ständig wechselt und daher nicht bekannt ist, sondern nur: wie das terminierende byte aussieht ('\n'), wird gelesen bis '\n' erreicht ist.
Genau wie std::string verwaltet Arduino String den notwendigen Speicher bei String-Methoden selbstständig, gerade auch bei der "Addition" (Concatenierung).
Zur weiteren Verabeitung von enthaltenen "tokens" über ANSI C - <string.h> Funktionen wird dann der Inhalt von msg in einen Array definierter Maximallänge kopiert und dort weiterverarbeitet.
(Außerdem ist das später in threads auch einfacher über mutexe zu schützen.)

Übrigens kompiliere ich auch den Raspi code mit gpp/C++, nicht mit gcc/C.

Betr. UART:
Im Gegensatz zur Arduino Serial() class (vererbt von der Stream class) inkl. vieler eingebauter Puffer- und Timeout-Methoden arbeitet wiringPi per wiringSerial aber mit "klassischem" C, ohne eingebaute Korrekturmethoden, und daher vermute ich momentan die "Aufhänger" eher ursächlich Raspi-seitig (CMIIW)...