Raspberry Pi 3 UART baud rate workaround

If you've tried to use the UART on the GPIO header of the new Raspberry Pi 3, you may have been frustrated to discover that it doesn't work properly.

There are a few reasons this is the case, and I'll get into those further down the post, but the current workaround is this:

In /boot/config.txt, add the line core_freq=250. Save and reboot! The GPIO UART now operates at the correct baud rate, and is available at /dev/ttyS0, and NOT /dev/ttyAMA0 like before.

First things first, why is the GPIO header UART now on /dev/ttyS0, and not /dev/ttyAMA0 like before? The answer is that previously, the UART broken out at the GPIO header was uart0 on the BCM2835/6. However, uart0 is now used for Bluetooth instead, so on the Pi 3, it is uart1 that is broken out at the GPIO header instead.

But why change it at all?

The reason, and the crux of the problem, is that unlike uart1, uart0 is immune from changes in the core clock frequency (and has larger FIFOs). Unlike uart0, the baud rate for uart1 is dependent on the core clock. So if the core clock changes, the baud rate will change!

Interestingly, during my investigation, I had found that it was possible to temporarily 'fix' the serial console by initiating a SSH session with the Pi. By starting an SSH connection, the core clock was bumped up to hand the extra load, which brought the baud rate back into line with what my USB UART cable was expecting!

So, until we get a 'proper' fix (possibly setting PLLs correctly or dynamically with any changes to the core frequency), the best option seems to be setting the core clock to 250MHz, with core_freq=250 in /boot/config.txt.

Further information, from people who are cleverer than I am, can be found in this GitHub issue.

EDIT: It is possible to swap the UARTs back, so that uart0 is now broken out at the GPIO header instead. More details can be found in this forum thread.