fdevopen() verknüpft eine von dir gelieferte, primitive Zeichen-Ein-
oder Ausgabe-Funktion mit den Ein- oder Ausgabestreams der C-Library.
Mit einer solchen Verknüpfung gehen dann z.B. Schreiboperationen mit
printf, die von der C-Library aus ja auf den Ausgabestream STDOUT gehen,
durch deine Funktion durch, im obigen Fall also durch die serielle
Schnittstelle UART.
Du brauchst das nicht. Es kann aber nützlich sein, das zu benutzen, wenn
du z.B. die komfortablen Formatiermöglichkeiten eines printf magst und
dein (ein fremdes) Programm mit gängigen C-Funktionen schreiben willst,
statt überall eigene Funktionen zu benutzen.
Wenn du z.B. printf benutzen willst, um auf ein LCD was auszugeben,
kannst du mit fdevopen an einer Stelle eine entsprechende
LCD-Ausgabefunktion einbinden und brauchst nicht überall wo eine Ausgabe
gemacht wird UART auf LCD umzuschreiben.
Mehr Infos hier:
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#gb599ddf60819df4cc993c724a83cb1a4