En los sistemas integrados, el puerto serie se puede utilizar para generar registros para la depuración del sistema y también se puede utilizar para comunicaciones de corta distancia y baja velocidad. Es un puerto de comunicación muy práctico.
Este artículo presenta funciones basadas en el kernel de placa única .RockPI 4A
Linux 4.4
RK3399 UART
1. Introducción a la UART
UART(Universal Asynchronous Receiver/Transmitter)
: Receptor-transmisor asíncrono universal, adecuado para transmisión de datos de corta distancia, baja velocidad, serie y full-duplex.
En China, el puerto serie generalmente se refiere al puerto de comunicación serie. Hay 9 pines, usando niveles.PC
COM
RS-232
En los sistemas integrados, el puerto serie generalmente se refiere al puerto. Generalmente se utilizan 3 pines y niveles.UART
TTL
TTL/RS-232/RS-485
Se refiere al nivel estándar, la diferencia es la siguiente:
estándar de nivel | lógica 0 | Lógica 1 | método de transferencia |
---|---|---|---|
TTL nivel |
0 ~ 0.4V |
2.4 ~ 5V |
duplex completo |
RS-232 nivel |
3 ~ 15V |
-15 ~ -3V |
duplex completo |
RS-485 nivel |
-6 ~ -2V |
2 ~ 6V |
Half-duplex (transmisión diferencial, mayor distancia) |
Al depurar la placa única integrada, puede seleccionar el módulo para implementar la comunicación en serie con la placa única, como se muestra en la siguiente figura:USB转TTL
PC
RK3399 UART
Características del controlador:
1. Admite puerto serie de 5 vías.
2. Admitir o interrumpir el modo de transmisión.DMA
3. Admite dos envíos y recepciones de 64 bytes .FIFO
4. Admite envío o recepción de datos en serie 5/6/7/8.bit
5. Admite bits de comunicación asíncronos estándar, como inicio, parada y verificación de paridad.
6. La velocidad máxima en baudios del reloj puede admitirse hasta 4.Mbps
7. Admite el modo de control de flujo automático.UART0/3
RK3399 UART
La descripción del pin se muestra en la siguiente figura:
2. Conexión UART
ROCKPi 4A
La placa tiene un puerto de expansión de 40 pines, como se muestra en la siguiente imagen:radxa
RockPI 4A
La placa única se utiliza como puerto serie de depuración y el método de conexión de pines para convertir a un puerto serie es el siguiente:UART2
USB
TTL
Placa única RockPI4A | Puerto serie USB a TTL |
---|---|
PIN8(UART2_TXD) | RXD |
PIN9 (Tierra) | Tierra |
PIN10(UART2_RXD) | TXD |
RockPI 4A
La configuración del puerto serie de depuración de la placa única se muestra en la siguiente figura:
Al conectar el puerto serie, primero debe asegurarse de que la conexión sea correcta y luego verificar si los niveles de pin del puerto serie son compatibles y si la configuración de los parámetros del puerto serie es correcta. De lo contrario, es posible que el puerto serie no esté disponible o esté confuso.GND
3. configuración UART
Tome una sola placa como ejemplo para configurar la configuración en la introducción .ROCKPI 4A
RK3399 DTS
UART
3.1. Alias del puerto serie
Los dispositivos de puerto serie ordinarios se numerarán según el número de puerto serie y se registrarán como el dispositivo correspondiente.dts
aliases
serialx
ttySx
Archivo de configuración: .arch/arm64/boot/dts/rockchip/rk3399.dtsi
RK3399 DTS
se define de la siguiente manera :aliases
alias { ... serial0 = &uart0; serie1 = &uart1; serie2 = &uart2; serie3 = &uart3; serial4 = &uart4; };
Si registra la modificación como , podrá realizar las siguientes modificaciones:UART4
ttyS1
alias { ... serial0 = &uart0; serial1 = &uart4 ## Utilice uart4 para reemplazar uart1 ... serial4 = &uart1 ;
3.2. Configuración del puerto serie
Archivo de configuración: .arch/arm64/boot/dts/rockchip/rk3399.dtsi
UART0 dts
La configuración es la siguiente:
uart0: serial@ff180000 { compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; reg = <0x0 0xff180000 0x0 0x100> ## dirección de registro uart0 0xff180000 y tamaño de mapeo 0x100 relojes = <&cru SCLK_UART0 >, <&cru PCLK_UART0>; ## El reloj utilizado por uart0 clock-names = "baudclk", "apb_pclk"; interrumpe = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0> ## uart0 usa interrupción SPI, número de interrupción 131 (99+32) , El modo DMA no se utiliza reg-shift = <2>; ## La dirección del registro está compensada en 2 bits, es decir, offset+4 reg-io-width = <4> ## El ancho de bits del registro es 32 bits; . pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ## uart0 usa el estado del pin de control de flujo = "disabled" ## Estado desactivado predeterminado };
UART0 pinmux
configuración, incluidos los pines de control de flujo .cts/rts
uart0 { uart0_xfer: uart0-xfer { rockchip,pins = <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>; }; };
Nota:
RK3399 UART0
El número de interrupción es 131. El número de interrupción comienza desde 32 y el número de interrupción comienza desde 0 de forma predeterminada, por lo que el número de interrupción configurado es: 131-32, que es 99.SPI
dts
SPI
UART0
Después de que se inicia el sistema, puede ver las interrupciones del puerto serie (131 y 132):
root@xiaotianbsp:/# cat proc/interrupts 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 Nivel serial ... 222: 301 0 0 0 0 0 GICv3 132 Nivel de depuración ... Err: 0
3.3. Habilitación del puerto serie
Archivo de configuración: .arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi
UART0 dts
La configuración de habilitación es la siguiente:
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts>; status = "ok"; ## ok: activa la función del puerto serie deshabilitada: desactiva la función del puerto serie. }; & uart2 { status = "ok" ## Habilitar puerto serie 2 };
Nota:
status = "okay"
o , pero no se puede utilizar ."ok"
enable
El código de análisis del kernel es el siguiente:
bool estático __of_device_is_available(const struct device_node *dispositivo) { ... estado = __of_get_property(dispositivo, "estado", &statlen); ... if (statlen > 0) { if (!strcmp(estado, "ok") || !strcmp(status, "ok")) devuelve verdadero; } devuelve falso; }
3.4、ttyFIQ0
El sistema se utiliza como dispositivo./dev/ttyFIQ0
console
Archivo de configuración:, el contenido es el siguiente:arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi
fiq_debugger: fiq-debugger { status = "disabled"; compatible = "rockchip,fiq-debugger"; rockchip,serial-id = <2>; use el número de puerto serie (UART2), modifique el valor de este atributo, y cambie el pinmux del puerto serie al mismo tiempo rockchip,signal-irq = <182>; rockchip , wake-irq = <0>; * Si enable uart usa irq en lugar de fiq */ rockchip ,baudrate = <1500000>; /* Sólo 115200 y 1500000 */ pinctrl-names = "default" = < &uart2c_xfer>; -identificación };
RockPI 4A
Para el sistema utilizado por la placa , configure los parámetros en el archivo de configuración.Debian
extlinux.conf
console
root@xiaotianbsp:/boot/extlinux# cat extlinux.conf tiempo de espera 10 menú título seleccionar kernel etiqueta kernel-4.4.154-90-rockchip-ga14f6502e045 kernel /vmlinuz-4.4.154-90-rockchip-ga14f6502e045 devicetreedir /dtbs/4.4 .154-90-rockchip-ga14f6502e045 ## Habilite la impresión temprana, ttyFIQ0 se usa como dispositivo de consola, la velocidad en baudios del puerto serie es 1,5 M, 8 bits de datos, 1 bit de parada agregado earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/ init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4
Una vez que se inicia el sistema, puede verlo.cmdline
root@xiaotianbsp:~# cat /proc/cmdline earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4
4. controlador UART
RK3399 Linux4.4
El controlador del kernel utiliza el controlador universal 8250, el tipo es . Archivos de implementación principales:UART
16550A
drivers/tty/serial/8250/8250_dma.c ## Controladores de implementación UART dma/tty/serial/8250/8250_dw.c ## Controladores del controlador del puerto serie Synopsys DesignWare 8250/ tty/serial/8250/8250_early.c ## consola temprana drivers de implementación /tty/serial/8250/8250_port.c ## Interfaces relacionadas para la configuración del puerto UART
UART
Los controladores y la depuración se presentarán más adelante.
5. Depuración del registro del kernel
En los sistemas integrados, lo más común es utilizar el puerto serie para generar registros del kernel para la depuración funcional.Linux
5.1, imprimir
En el kernel, hay funciones disponibles para enviar información del kernel al búfer de información del kernel.Linux
printk()
La salida del registro del kernel se divide en diferentes niveles, archivo de definición:, que incluye:include/linux/kern_levels.h
#define LOGLEVEL_EMERG 0 /* el sistema no se puede utilizar */ #define LOGLEVEL_ALERT 1 /* se debe tomar acción inmediatamente */ #define LOGLEVEL_CRIT 2 /* condiciones críticas */ #define LOGLEVEL_ERR 3 /* condiciones de error */ #define LOGLEVEL_WARNING 4 /* condiciones de advertencia */ #define LOGLEVEL_NOTICE 5 /* condición normal pero significativa */ #define LOGLEVEL_INFO 6 /* informativo */ #define LOGLEVEL_DEBUG 7 /* mensajes a nivel de depuración */
Además de las funciones, también puedes utilizar y .printk()
pr_**()
dev_**()
pr_**
Archivo de definición:, la macro se define de la siguiente manera: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_**
Archivo de definición:, la función se define de la siguiente manera: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_listargumentos; \ \ va_start(args,fmt); \ \ vaf.fmt = fmt; \ vaf.va=&args; \ \ __dev_printk(kern_level, dev, &vaf); \ \ va_end(argumentos); \ } \ 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. Nivel de salida del registro
El nivel de salida del registro del kernel se puede ajustar modificando el valor de o .loglevel
/proc/sys/kernel/printk
Antes de que se inicie el sistema, puede ajustar la salida del registro del puerto serie mediante la configuración.loglevel
root@xiaotianbsp:~# cat /boot/extlinux/extlinux.conf ... label kernel-debug kernel /debug/Image fdt /debug/rk3399-rock-pi-4a.dtb ## Modifique el nivel de registro para ajustar la salida del puerto serie nivel de registro anexar earlyprintk console=ttyFIQ0,1500000n8 loglevel=4 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4 no_console_suspend initcall_debug
Otros sistemas (como: o ) generalmente se modifican en .Ubuntun、Buildroot
Android
bootargs
loglevel
Nota:
no_console_suspend
Se utiliza para la depuración de la administración de energía del sistema Linux, lo que significa que después de que el sistema duerme (suspende), el puerto serie no duerme y aún puede generar salida.
Una vez iniciado el sistema, el nivel de salida del registro del puerto serie también se puede ajustar dinámicamente.
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
printk
Los números corresponden a diferentes niveles de registro. Simplemente modifique el nivel de registro del puerto.console
int console_printk[4] = { CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */ ## Nivel de registro de consola MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */ ## Nivel de registro de mensajes predeterminado CONSOLE_LOGLEVEL_MIN, /* mínimo_console_loglevel */ ## Nivel mínimo de registro de consola CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */ ##Nivel de registro de consola predeterminado };
5.1.2. Marca de tiempo del registro
Una vez que se inicia el sistema, la visualización de las marcas de tiempo del registro del kernel se puede ajustar dinámicamente.
## 1. El valor de tiempo es Y, lo que significa la marca de tiempo root@xiaotianbsp:/# cat /sys/module/printk/parameters/time Y ## 2. En este momento, el registro muestra una marca de tiempo root@xiaotianbsp:/ # buscar. -nombre hora [1719.836194] FAT-fs (sda4): error, acceso no válido a FAT (entrada 0x07b03538) [1719.836874] FAT-fs (sda4): error, acceso no válido a FAT (entrada 0x07b03538) ## 3. Establezca el valor de tiempo en N root@xiaotianbsp:/# echo N > /sys/module/printk/parameters/time ## 4. En este momento, el registro muestra una marca de tiempo root@xiaotianbsp:/# find -name time FAT . -fs (sda4): error, acceso no válido a FAT (entrada 0x07b03538) FAT-fs (sda4): error, acceso no válido a FAT (entrada 0x07b03538)
5.2、dmesg
Después de que se inicia el sistema, si se perdió la fase de inicio del kernel o usa un puerto no serial (por ejemplo: inicio de sesión) para conectar la placa de depuración, puede usarlo para ver el registro del kernel.adb/ssh
dmesg
dmesg
El uso es el siguiente:
root@xiaotianbsp:/# dmesg -h Uso : dmesg [opciones] Muestra o controla el búfer de anillo del núcleo. Opciones : -C, --clear borra el búfer de anillo del núcleo -c, --read-clear leer y borrar todos los mensajes -D, --console-off deshabilita la impresión de mensajes en la consola -E, --console-on habilita la impresión de mensajes en la consola -F, --file <archivo> usa el archivo en lugar del búfer de registro del kernel -f, - -facility <lista> restringir la salida a instalaciones definidas -H, --human salida legible por humanos -k, --kernel mostrar mensajes del kernel -L, --color[=<cuando>] colorear mensajes (automático, siempre o nunca) colores están habilitados de forma predeterminada -l, --level <lista> restringe la salida a niveles definidos -n, --console-level <nivel> establece el nivel de mensajes impresos en la consola -P, --nopager no canaliza la salida a un buscapersonas - r, --raw imprime el búfer de mensajes sin procesar -S, --syslog fuerza el uso de syslog(2) en lugar de /dev/kmsg -s, --buffer-size <tamaño> tamaño del búfer para consultar el búfer de anillo del núcleo -u , --userspace muestra mensajes en el espacio de usuario -w, --follow espera mensajes nuevos -x, --decode función de decodificación y nivel a cadena legible -d, --show-delta muestra el delta de tiempo entre mensajes impresos -e, --reltime muestra la hora local y el delta de hora en formato legible -T, --ctime muestra la marca de tiempo legible por humanos (¡puede ser inexacta!) -t, --notime no muestra ninguna marca de tiempo con mensajes --time-format <formato> muestra la marca de tiempo usando el formato dado: [delta|reltime|ctime|notime|iso] Suspender/reanudar hará que las marcas de tiempo de ctime e iso sean inexactas. -h , --help muestra esta ayuda y sale -V, --version genera información de la versión y sale Instalaciones de registro admitidas kern - mensajes del kernel usuario - mensajes aleatorios a nivel de usuario correo - demonio del sistema de correo - autenticación de demonios del sistema - mensajes de seguridad/autorización syslog - mensajes generados internamente por syslogd lpr - noticias del subsistema de impresora de línea - subsistema de noticias de red Registro admitido emerg - el sistema está inutilizable alerta - se deben tomar medidas inmediatamente crítico - condiciones críticas err - condiciones de error warn - aviso de condiciones de advertencia - información de condición normal pero significativa - depuración informativa - mensajes a nivel de depuración Para obtener más detalles, consulte dmesg(1).
5.2.1. Mostrar registros del kernel
root@xiaotianbsp:/# dmesg [0.000000] Arrancando Linux en CPU física 0x0 [0.000000] Inicializando cgroup subsys cpuset [0.000000] Inicializando cgroup subsys cpu [0.000000] Inicializando cgroup subsys cpuacct [0.000000] Versión de Linux 4.4.154-9 0-rockchip- ga14f6502e045 (root@2705a206000b) (gcc versión 7.3.1 20180425 [linaro-7.3-2018.05 revisión d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) #2 2 SMP martes 30 de julio 10:32:28 UTC 2019
5.2.2. Limitar el nivel de salida del registro
## 仅输出error信息 root@xiaotianbsp:/# dmesg -l err [2.170152] rockchip-pcie f8000000.pcie: ¡Tiempo de espera de gen1 de entrenamiento de enlace PCIe! [2.175658] rk-vcodec ff650000.vpu_service: no se pudo encontrar el nodo power_model [ 2.180010] rk-vcodec ff660000.rkvdec: no se pudo encontrar el nodo power_model [ 2.200359] rockchip-vop ff900000.vop: falta rockchip, propiedad grf [ 2.2019 13] chip de roca- vop ff8f0000.vop: falta rockchip, propiedad grf [2.203632] i2c i2c-9: of_i2c: falla de modalias en /hdmi@ff940000/ports [2.240381] mali ff9a0000.gpu: no se pudo obtener el regulador [2.240839] mali ff9a0000.gpu : Poder Error en la inicialización del control [2.260317] rk_gmac-dwmac fe300000.ethernet: no se puede obtener el reloj clk_mac_speed
## 同时输出error和warning信息 root@xiaotianbsp:/# dmesg -l err,warn [0.000000] rockchip_clk_register_frac_branch: no se pudo encontrar dclk_vop0_frac como padre de dclk_vop0, los cambios de velocidad pueden no funcionar [0.000000] rama: no se pudo encontrar dclk_vop1_frac como padre de dclk_vop1, los cambios de velocidad pueden no funcionar [0.000000] rockchip_cpuclk_pre_rate_change: limitar alt-divider 33 a 31 [1.589058] Thermal Thermal_zone1: power_allocator: Sustainable_power se estimará [1.637902] phy phy-ff770000.syscon:usb2-phy@e450. 1: No se pudo obtener el regulador de suministro VBUS [1.639962] phy phy-ff770000.syscon:[email protected]: No se pudo obtener el regulador de suministro VBUS [2.170152] rockchip-pcie f8000000.pcie: ¡Tiempo de espera de entrenamiento de enlace PCIe gen1!
5.2.3 Buscar una determinada información.
raíz@xiaotianbsp:~# dmesg | grep rockchip-vop [2.197270] rockchip-vop ff900000.vop: falta rockchip, propiedad grf [2.198853] rockchip-vop ff8f0000.vop: falta rockchip, propiedad grf root@xiaotianbsp:~# dmesg | grep xiaotianbsp raíz@xiaotianbsp:~#
5.2.4. Borrar información del búfer circular
root@xiaotianbsp:/# dmesg -c [0.000000] Arrancando Linux en 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:/#
dmesg
Puede probar más usos usted mismo.
Nota: indique el autor y la fuente al reimprimir.
RustDesk suspendió el servicio doméstico Taobao (taobao.com) debido a un fraude desenfrenado, reinició el trabajo de optimización de la versión web, Apple lanzó el chip M4, los estudiantes de secundaria crearon su propio lenguaje de programación de código abierto como una ceremonia de mayoría de edad - Los internautas comentaron: Confiando en La defensa, Yunfeng renunció a Alibaba y planea producir en el futuro el destino para programadores de juegos independientes Visual Studio Code 1.89, según anunció oficialmente Huawei. El ajuste laboral de Yu Chengdong fue clavado en el “FFmpeg Pillar of Shame”. "Hace 15 años, pero hoy tiene que agradecernos: ¿Tencent QQ Video se venga de su vergüenza anterior? La estación espejo de código abierto de la Universidad de Ciencia y Tecnología de Huazhong está oficialmente abierta al acceso a la red externa