terça-feira, 22 de setembro de 2015

Como aumentar a velocidade da conexão serial (UART) do Raspberry Pi

velocidade uart serial raspberry pi

A porta serial (PL011: GPIO14 e GPIO15 em /dev/AMA0) do Raspberry Pi por padrão tem sua velocidade (baudrate) máxima limitada à 187500bps.

Caso tente alterar para algo além disso não será possível:

$ stty -F /dev/ttyAMA0 921600
stty: /dev/ttyAMA0: unable to perform all requested operations

Em alguns projetos pode ser necessário utilizar velocidades muito acima do máximo permitido. Um dos testes que precisei fazer no Raspberry Pi meses atrás necessitava transferências à 1000000bps.

Calculando e alterando a velocidade da porta serial


A base da velocidade máxima disponível na porta serial é sua frequência (UARTCLK). Por padrão esse clock é definido em 3Mhz, essa frequência que será definida de acordo com o máximo necessário.

É possível consultar a frequência atual do UART por meio do programa vcgencmd.

$ vcgencmd measure_clock uart
frequency(22)=3000000


Para calcular a frequência correspondente à velocidade máxima que será usada, basta multiplicar o baudrate máximo por 16. Caso queira por exemplo utilizar 1000000bps você precisará alterar a frequência para (1000000*16)=16000000 ou 16Mhz.

Quando o Raspberry Pi foi lançado só era possível realizar essa alteração modificando o código fonte do kernel ou realizando outras formas nada triviais.

Hoje é possível alterar essa frequência colocando um parâmetro no arquivo "/boot/config.txt".

Basta abrir o arquivo com sudo ou root e adicionar ao final do arquivo a frequência desejada:

init_uart_clock=16000000

Após a alteração basta reiniciar o sistema e verificar se funcionou corretamente:

$ vcgencmd measure_clock uart
frequency(22)=16000000
$ stty -F /dev/ttyAMA0 1000000
$ stty -F /dev/ttyAMA0
speed 1000000 baud; line = 0;
-brkint -imaxbel



Conclusão


Internamente o baudrate é definido por meio de um divisor que utiliza 2 registradores, sendo IBRD de 16 bits a parte inteira e FBRD de 6 bits a parte fracionária.

O cálculo para se chegar no valor do divisor utiliza a seguinte fórmula:

UARTCLK / (16 * BAUDRATE) = DIVISOR

Portanto se temos um UARTCLK=16000000 e queremos selecionar BAUDRATE=1000000 temos:

16000000 / (16 * 1000000) = 1

Um divisor inteiro 1. Entretanto se tivermos o mesmo UARTCLK acima mas queremos selecionar BAUDRATE=115200 temos:

16000000 / (16 * 115200) = 8,68

Segundo um dos engenheiros do Raspberry Pi o clock do UART é gerado com base no core clock (250Mhz padrão) e portanto a frequência máxima no UART seria 250Mhz.

Levando essa frequência em conta, o máximo teórico seria 250Mhz/16 = 15625000bps (15,625mbps). Entretanto ele informa que como haverá muitas interrupções, acha razoável o uso até 6mbps.

Referências:
http://elinux.org/RPiconfig
https://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf

Nenhum comentário:

Postar um comentário