Kernel Linux UART

Em sistemas embarcados, a porta serial pode ser usada para gerar logs para depuração do sistema e também para comunicação de curta distância e baixa velocidade. É uma porta de comunicação muito prática.

Este artigo apresenta funções baseadas no kernel de placa única .RockPI 4ALinux 4.4RK3399 UART

1. Introdução ao UART

UART(Universal Asynchronous Receiver/Transmitter): Receptor-transmissor assíncrono universal, adequado para transmissão de dados de curta distância, baixa velocidade, serial e full-duplex.

Na China, a porta serial geralmente se refere à porta de comunicação serial. Existem 9 pinos, usando níveis.PCCOMRS-232

Em sistemas embarcados, porta serial geralmente se refere à porta. Geralmente, 3 pinos são usados ​​e níveis são usados.UARTTTL

TTL/RS-232/RS-485Refere-se ao padrão de nível, a diferença é a seguinte:

padrão de nível lógica 0 Lógica 1 método de transferência
TTLnível 0 ~ 0.4V 2.4 ~ 5V duplex completo
RS-232nível 3 ~ 15V -15 ~ -3V duplex completo
RS-485nível -6 ~ -2V 2 ~ 6V Half-duplex (transmissão diferencial, maior distância)

Ao depurar a placa única incorporada, você pode selecionar o módulo para implementar a comunicação serial com a placa única, conforme mostrado na figura abaixo:USB转TTLPC

RK3399 UARTRecursos do controlador:

1. Suporta porta serial de 5 vias.

2. Apoie ou interrompa o modo de transmissão.DMA

3. Suporta dois envios e recebimentos de 64 bytes .FIFO

4. Suporta envio ou recebimento de dados seriais 5/6/7/8.bit

5. Suporta bits de comunicação assíncrona padrão, como início, parada e verificação de paridade.

6. A taxa de transmissão máxima do clock pode ser suportada até 4.Mbps

7. Suporta modo de controle de fluxo automático.UART0/3

RK3399 UARTA descrição do pino é mostrada na figura abaixo:

2. Conexão UART

ROCKPi 4AA placa possui uma porta de expansão de 40 pinos, conforme mostrado na imagem abaixo:radxa

RockPI 4AA placa única é usada como porta serial de depuração e o método de conexão de pinos para conversão em porta serial é o seguinte:UART2USBTTL

Placa única RockPI4A Porta serial USB para TTL
PIN8(UART2_TXD) RXD
PIN9 (GND) GND
PIN10(UART2_RXD) TXD

RockPI 4AA configuração da porta serial de depuração da placa única é mostrada na figura abaixo:

Ao conectar a porta serial, você deve primeiro garantir que a conexão esteja correta e, em seguida, verificar se os níveis dos pinos da porta serial são compatíveis e se a configuração dos parâmetros da porta serial está correta. Caso contrário, a porta serial pode estar indisponível ou distorcida.GND

3. Configuração UART

Tome uma única placa como exemplo para definir a configuração na introdução .ROCKPI 4ARK3399 DTSUART

3.1. Alias ​​da porta serial

Os dispositivos de porta serial comuns serão numerados de acordo com o número da porta serial e serão registrados como o dispositivo correspondente.dtsaliasesserialxttySx

Arquivo de configuração: .arch/arm64/boot/dts/rockchip/rk3399.dtsi

RK3399 DTSé definido da seguinte forma :aliases

    aliases { 
... serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; serial3 = &uart3; serial4 = &uart4; };        
        
        
        
        
        
    

Se você registrar a modificação como , poderá fazer as seguintes modificações:UART4ttyS1

    aliases { 
... serial0 = &uart0; serial1 = &uart4; ## Use uart4 para substituir uart1 ... serial4 = &uart1 };        
        
        
        
        
    

3.2. Configuração da porta serial

Arquivo de configuração: .arch/arm64/boot/dts/rockchip/rk3399.dtsi

UART0 dtsA configuração é a seguinte:

    uart0: serial@ff180000 { 
compatível = "rockchip,rk3399-uart", "snps,dw-apb- uart " ; >, <&cru PCLK_UART0>; ## O relógio usado por uart0 clock-names = "baudclk", "apb_pclk"; interrupções = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>; , O modo DMA não é usado reg-shift = <2> ## O endereço do registrador é deslocado em 2 bits, ou seja, offset+4 reg-io-width = <4> ## A largura de bits do registrador é de 32 bits; . pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ## uart0 usa o pino de controle de fluxo status = "disabled" ;        
                       
          
        
        
                    
                 
        
        
        
    

UART0 pinmuxconfiguração, incluindo pinos de controle de fluxo .cts/rts

    uart0 { 
        uart0_xfer: uart0-xfer { 
            rockchip, pinos = 
                <2 16 RK_FUNC_1 &pcfg_pull_up>, 
                <2 17 RK_FUNC_1 &pcfg_pull_none>; 
        }; 
​uart0_cts
        : uart0-cts { 
            rockchip,pins = 
                <2 18 RK_FUNC_1 &pcfg_pull_none>; 
        }; 
​uart0_rts
        : uart0-rts { 
            rockchip,pins = 
                <2 19 RK_FUNC_1 &pcfg_pull_none>; 
        }; 
    };

Observação:

RK3399 UART0O número de interrupção é 131. O número de interrupção começa em 32, e o número de interrupção começa em 0 por padrão, então o número de interrupção configurado é: 131-32, que é 99.SPIdtsSPIUART0

Após a inicialização do sistema, você poderá visualizar as interrupções da porta serial (131 e 132):

root@xiaotianbsp:/# cat proc/interrompe 
           CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 
14: 0 0 0 0 0 0 GICv3 29 Edge arch_timer 
... 
35: 16 0 0 0 0 0 GICv3 131 Nível serial 
... 
222: 301 0 0 0 0 0 GICv3 132 Nível de depuração 
... 
Err: 0

3.3. Habilitação de porta serial

Arquivo de configuração: .arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi

UART0 dtsA configuração de habilitação é a seguinte:

&uart0 { 
    pinctrl-names = "default"; 
    pinctrl-0 = <&uart0_xfer &uart0_cts>; 
    status = "ok"; 
} 
&
 uart2 { 
    status = "ok" ## Habilitar porta serial 2 
};

Observação:

status = "okay"ou , mas não pode ser usado ."ok"enable

O código de análise do kernel é o seguinte:

static bool __of_device_is_available(const struct device_node *device) 
{ 
    ... 
    status = __of_get_property(device, "status", &statlen); 
    ... 
​if
     (statlen > 0) { 
if (!strcmp(status, "ok") || !strcmp(status, "ok")) retorna verdadeiro; } ​retorna falso; }        
            
    

    

3.4、ttyFIQ0

O sistema é usado como um dispositivo./dev/ttyFIQ0console

Arquivo de configuração: , o conteúdo é o seguinte:arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi

    fiq_debugger: fiq-debugger { 
status = "disabled"; compatível = " rockchip ,fiq-debugger" ; e alterne a porta serial. Alterne o pinmux da porta serial ao mesmo tempo rockchip ,signal-irq = <182> ; * Se enable uart usa irq em vez de fiq */ rockchip ,baudrate = < & uart2c_xfer> ; -eu ia };                    
        
               
        
        
        
        
        
             
    

RockPI 4APara o sistema utilizado pela placa , defina os parâmetros no arquivo de configuração.Debianextlinux.confconsole

root@xiaotianbsp:/boot/extlinux# cat extlinux.conf 
timeout 10 
menu title select kernel 
​label
 kernel-4.4.154-90-rockchip-ga14f6502e045 
    kernel /vmlinuz-4.4.154-90-rockchip-ga14f6502e045 
    devicetreedir /dtbs/4.4 .154-90-rockchip-ga14f6502e045 
    ## Habilite o early printk, ttyFIQ0 é usado como dispositivo de console, a taxa de transmissão da porta serial é 1,5M, 8 bits de dados, 1 bit de parada 
    acrescenta earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/ init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4

Depois que o sistema for iniciado, você poderá visualizá-lo.cmdline

root@xiaotianbsp:~# cat /proc/cmdline 
earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4

4. Driver UART

RK3399 Linux4.4O driver do kernel usa o driver universal 8250, o tipo é . Principais arquivos de implementação:UART16550A

drivers/tty/serial/8250/8250_dma.c ## 
Drivers de implementação UART dma/tty/serial/8250/8250_dw.c ## Drivers de driver de porta serial Synopsys DesignWare 8250 
/tty/serial/8250/8250_early.c ## console inicial drivers de implementação 
/tty/serial/8250/8250_port.c ## Interfaces relacionadas para configuração de porta UART

UARTDrivers e depuração serão introduzidos posteriormente.

5. Depuração de log do kernel

Em sistemas embarcados, o mais comum é usar a porta serial para gerar logs do kernel para depuração funcional.Linux

5.1、imprimir

No kernel, funções estão disponíveis para enviar informações do kernel para o buffer de informações do kernel.Linuxprintk()

A saída do log do kernel é dividida em diferentes níveis, arquivo de definição: , incluindo:include/linux/kern_levels.h

#define LOGLEVEL_EMERG 0 /* o sistema está inutilizável */ 
#define LOGLEVEL_ALERT 1 /* ação deve ser tomada imediatamente */ 
#define LOGLEVEL_CRIT 2 /* condições críticas */ 
#define LOGLEVEL_ERR 3 /* condições de erro */ 
#define LOGLEVEL_WARNING 4 /* condições de aviso */ 
#define LOGLEVEL_NOTICE 5 /* condição normal, mas significativa */ 
#define LOGLEVEL_INFO 6 /* informativa */ 
#define LOGLEVEL_DEBUG 7 /* mensagens em nível de depuração */

Além das funções, você também pode usar e .printk()pr_**()dev_**()

pr_**Arquivo de definição: , a macro é definida da seguinte forma:include/linux/printk.h

#define pr_emerg(fmt, ...) \ 
    printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) 
#define pr_alert(fmt, ...) \ 
    printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) 
#define pr_crit( fmt, ...) \ 
    printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) 
#define pr_err(fmt, ...) \ 
    printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) 
#define pr_warning(fmt, .. .) \ 
    printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) 
#define pr_warn pr_warning 
#define pr_notice(fmt, ...) \ 
    printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) 
#define pr_info(fmt, .. .) \ 
    printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)

dev_**Arquivo de definição: , a função é definida da seguinte forma:drivers/base/core.c

#define define_dev_printk_level(func, kern_level) \        
void func(const struct dispositivo *dev, const char *fmt, ...)    \ 
{ \                                
    struct va_format vaf; \                    
    va_list argumentos; \\                        
va_start(args,fmt) ; \\ vaf.fmt =fmt; \ vaf.va=&args; \ \ __dev_printk(kern_level, dev, &vaf); \\ va_end (args); \ } \ EXPORT_SYMBOL(func); ​define_dev_printk_level (dev_emerg, KERN_EMERG); define_dev_printk_level(dev_alert, KERN_ALERT); define_dev_printk_level(dev_crit, KERN_CRIT); define_dev_printk_level(dev_err,KERN_ERR); define_dev_printk_level(dev_warn, KERN_WARNING); define_dev_printk_level(dev_notice, KERN_NOTICE); define_dev_printk_level(_dev_info,KERN_INFO);                                
                        
                                
                          
                         
                                
                
                                
                           
                               








5.1.1 Nível de saída do registro.

O nível de saída do log do kernel pode ser ajustado modificando o valor de ou .loglevel/proc/sys/kernel/printk

Antes de o sistema iniciar, você pode ajustar a saída do log da porta serial por meio da configuração.loglevel

root@xiaotianbsp:~# cat /boot/extlinux/extlinux.conf 
... 
label kernel-debug 
    kernel /debug/Image 
    fdt /debug/rk3399-rock-pi-4a.dtb 
    ## Modifique o nível de log para ajustar a saída da porta serial nível de log 
    anexar earlyprintk console=ttyFIQ0,1500000n8 loglevel=4 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4 no_console_suspend initcall_debug

Outros sistemas (como: ou ) são geralmente modificados em .Ubuntun、BuildrootAndroidbootargsloglevel

Observação:

no_console_suspendUsado para depuração de gerenciamento de energia do sistema Linux, o que significa que depois que o sistema entra em suspensão (suspende), a porta serial não dorme e ainda pode produzir.

Após o sistema ser iniciado, o nível de saída do log da porta serial também pode ser ajustado dinamicamente.

root@xiaotianbsp:/proc/sys/kernel# cat printk 
7 4 1 7 
root@xiaotianbsp:/proc/sys/kernel# echo 4 > printk 
root@xiaotianbsp:/proc/sys/kernel# cat printk 
4 4 1 7

printkOs números correspondem a diferentes níveis de log. Basta modificar o nível de log da porta.console

int console_printk[4] = { 
        CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */   ## Nível de log do console         
        MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */   ## Nível de log de mensagens padrão 
        CONSOLE_LOGLEVEL_MIN, /* mínimo_console_loglevel */ ## Nível mínimo de log do console 
        CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */ ##Nível de log do console padrão 
};

5.1.2 Registro de data e hora.

Após a inicialização do sistema, a exibição dos carimbos de data e hora do log do kernel pode ser ajustada dinamicamente.

## 1. O valor do tempo é Y, o que significa o carimbo de data e hora 
root@xiaotianbsp:/# cat /sys/module/printk/parameters/time 
Y 
## 2. Neste momento, o log mostra um carimbo de data e hora 
root@xiaotianbsp:/ # find . -name time 
[1719.836194] FAT-fs (sda4): erro, acesso inválido ao FAT (entrada 0x07b03538) 
[1719.836874] FAT-fs (sda4): erro, acesso inválido ao FAT (entrada 0x07b03538) 
## 3. Defina o valor do tempo como N 
root@xiaotianbsp:/# echo N > /sys/module/printk/parameters/time 
## 4. Neste momento, o log mostra um carimbo de data/hora root@xiaotianbsp:/# find -name time 
FAT . 
-fs (sda4): erro, acesso inválido ao FAT (entrada 0x07b03538) 
FAT-fs (sda4): erro, acesso inválido ao FAT (entrada 0x07b03538)

5.2、dmesg

Após a inicialização do sistema, se você perdeu a fase de inicialização do kernel ou usou uma porta não serial (por exemplo: login) para conectar a placa de depuração, você pode usar para visualizar o log do kernel.adb/sshdmesg

dmesgO uso é o seguinte:

root@xiaotianbsp:/# dmesg -h 
​Uso
 : 
dmesg [opções] 
​Exibe
 ou controla o buffer circular do kernel. 
​Opções
 : 
-C, --clear limpa o buffer circular do kernel 
-c, --read-clear lê e limpa todas as mensagens 
-D, --console-off desabilita a impressão de mensagens no console 
-E, --console-on habilita a impressão de mensagens no console 
-F, --file <arquivo> usa o arquivo em vez do buffer de log do kernel 
-f, - -facility <lista> restringir a saída para recursos definidos 
-H, --human saída legível por humanos 
-k, --kernel exibir mensagens do kernel 
-L, --color[=<quando>] colorir mensagens (automático, sempre ou nunca) 
                               cores são habilitados por padrão 
-l, --level <lista> restringe a saída a níveis definidos 
-n, --console-level <nível> define o nível das mensagens impressas no console 
-P, --nopager não canaliza a saída para um pager 
- r, --raw imprime o buffer de mensagem bruta 
-S, --syslog força a usar syslog(2) em vez de /dev/kmsg 
-s, --buffer-size <tamanho> tamanho do buffer para consultar o buffer de anel do kernel 
-u , --userspace exibe mensagens do espaço do usuário 
-w, --follow espera por novas mensagens 
-x, --decode facilidade de decodificação e nível para string legível 
-d, --show-delta mostra o delta do tempo entre mensagens impressas 
-e, --reltime mostra a hora local e o delta da hora em formato legível 
-T, --ctime mostra o carimbo de data e hora legível por humanos (pode ser impreciso!) 
-t, --notime não mostra nenhum carimbo de data e hora com mensagens 
     --time-format <formato> mostra o carimbo de data e hora usando o formato fornecido: 
                               [delta|reltime|ctime|notime|iso] 
A suspensão/retomada tornará os carimbos de data e hora ctime e iso imprecisos. 
​-h
 , --help exibe esta ajuda e sai 
-V, --version gera informações de versão e sai 
Recursos de log suportados
     kern - mensagens do kernel     usuário - mensagens aleatórias em nível de usuário     mail -   daemon do sistema de correio - daemons do sistema     auth - mensagens de segurança/autorização   syslog - mensagens geradas internamente pelo syslogd      lpr - notícias do subsistema de impressora de linha     - subsistema de notícias da rede Log suportado    emergente - alerta de sistema inutilizável    - ação deve ser tomada imediatamente     crítico - condições críticas













     err - 
    aviso de condições de erro - condições de aviso 
  aviso - informações de condições normais, mas significativas 
    - 
   depuração informativa - mensagens em nível de depuração 
Para mais detalhes, consulte dmesg(1).

5.2.1 Exibir logs do kernel.

raiz@xiaotianbsp:/# dmesg 
[0,000000] inicializando o Linux na CPU física 0x0 
[0,000000] inicializando o CPUSET CGROUP 
[0.000000] Inicializando o CHURUP CHUROUP CPU [0.000000 
] Inicializando o cgrop Cpuacct 
[0.000000] Linux [0,0000]. ga14f6502e045 (root@2705a206000b) (gcc versão 7.3.1 20180425 [linaro-7.3-2018.05 revisão d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) #2) 2 SMP Ter, 30 de julho 10:32:28 UTC 2019

5.2.2 Limitar o nível de saída do log

## 仅输出error信息
root@xiaotianbsp:/# dmesg -l err 
[2.170152] rockchip-pcie f8000000.pcie: Tempo limite de treinamento do link PCIe gen1! 
[2.175658] rk-vcodec ff650000.vpu_service: não foi possível encontrar o nó power_model 
[2.180010] rk-vcodec ff660000.rkvdec: não foi possível encontrar o nó power_model 
[2.200359] rockchip-vop ff900000.vop: faltando rockchip, propriedade grf 
[2.20191 3] rockchip- vop ff8f0000.vop: faltando rockchip, propriedade grf 
[2.203632] i2c i2c-9: of_i2c: falha de modalias em /hdmi@ff940000/portas 
[2.240381] mali ff9a0000.gpu: Falha ao obter regulador 
[2.240839] mali ff9a0000.gpu : Poder falha na inicialização do controle 
[2.260317] rk_gmac-dwmac fe300000.ethernet: não é possível obter o relógio clk_mac_speed
## 同时输出error和warning信息
root@xiaotianbsp:/# dmesg -l err,warn 
[0.000000] rockchip_clk_register_frac_branch: não foi possível encontrar dclk_vop0_frac como pai de dclk_vop0, as alterações de taxa podem não funcionar 
[0.000000] frac_branch: não foi possível encontrar dclk_vop1_frac como pai de dclk_vop1, alterações de taxa podem não funcionar 
[0,000000] rockchip_cpuclk_pre_rate_change: limitando alt-divider 33 a 31 
[1,589058] Thermal Thermal_zone1: power_allocator: Sustainable_Power será estimado 
[1,637902] phy phy-ff770000.syscon:[email protected]: Falha ao obter o regulador de alimentação VBUS 
[1.639962] phy phy-ff770000.syscon:[email protected]: Falha ao obter o regulador de alimentação VBUS 
[2.170152] rockchip-pcie f8000000.pcie: Tempo limite de treinamento de link PCIe gen1!

5.2.3. Pesquisar uma determinada informação

root@xiaotianbsp:~#dmesg | grep rockchip-vop 
[2.197270] rockchip-vop ff900000.vop: faltando rockchip, propriedade grf 
[2.198853] rockchip-vop ff8f0000.vop: faltando rockchip, propriedade grf 
root@xiaotianbsp:~# dmesg | grep xiaotianbsp 
root@xiaotianbsp:~#

5.2.4 Limpar informações do buffer de anel.

root@xiaotianbsp:/# dmesg -c 
[ 0.000000] Inicializando o Linux na CPU física 0x0 
[ 0.000000] Inicializando cgroup subsys cpuset 
[ 0.000000] Inicializando cgroup subsys cpu 
[ 0.000000] Inicializando cgroup subsys cpuacct 
... 
root@xiaotianbsp:/# dmesg 
root @xiaotianbsp:/#

dmesgVocê pode testar mais usos sozinho.

Nota: Por favor, indique o autor e a fonte ao reimprimir.

RustDesk suspendeu o serviço doméstico Taobao (taobao.com) devido a fraude desenfreada, reiniciou o trabalho de otimização da versão web, a Apple lançou o chip M4, estudantes do ensino médio criaram sua própria linguagem de programação de código aberto como uma cerimônia de maioridade - Internautas comentaram: Confiando em a defesa, Yunfeng renunciou ao Alibaba e planeja produzir no futuro o destino para programadores de jogos independentes o Visual Studio Code 1.89, é oficialmente anunciado pela Huawei. O ajuste de trabalho de Yu Chengdong foi pregado no “Pilar da Vergonha FFmpeg. ” 15 anos atrás, mas hoje ele tem que nos agradecer - Tencent QQ Video vinga sua vergonha anterior? A estação espelho de código aberto da Universidade de Ciência e Tecnologia Huazhong está oficialmente aberta ao acesso à rede externa
{{o.nome}}
{{m.nome}}

Acho que você gosta

Origin my.oschina.net/u/4702401/blog/5558194
Recomendado
Clasificación