Dans les systèmes embarqués, le port série peut être utilisé pour générer des journaux pour le débogage du système, et peut également être utilisé pour la communication à courte distance et à faible vitesse. C'est un port de communication très pratique.
Cet article présente les fonctions basées sur le noyau monocarte .RockPI 4A
Linux 4.4
RK3399 UART
1. Introduction à l'UART
UART(Universal Asynchronous Receiver/Transmitter)
: Récepteur-émetteur asynchrone universel, adapté à la transmission de données à courte distance, à faible vitesse, en série et en duplex intégral.
En Chine, le port série fait généralement référence au port de communication série. Il y a 9 broches, utilisant des niveaux.PC
COM
RS-232
Dans les systèmes embarqués, le port série fait généralement référence au port. Généralement, 3 broches sont utilisées et des niveaux sont utilisés.UART
TTL
TTL/RS-232/RS-485
Fait référence au niveau standard, la différence est la suivante :
niveau standard | logique 0 | Logique 1 | méthode de transfert |
---|---|---|---|
TTL niveau |
0 ~ 0.4V |
2.4 ~ 5V |
Un duplex plein |
RS-232 niveau |
3 ~ 15V |
-15 ~ -3V |
Un duplex plein |
RS-485 niveau |
-6 ~ -2V |
2 ~ 6V |
Half-duplex (transmission différentielle, distance plus longue) |
Lors du débogage de la carte unique intégrée, vous pouvez sélectionner le module pour implémenter la communication série avec la carte unique, comme indiqué dans la figure ci-dessous :USB转TTL
PC
RK3399 UART
Caractéristiques du contrôleur :
1. Prise en charge du port série à 5 voies.
2. Prise en charge ou interruption du mode de transmission.DMA
3. Prend en charge deux envois et réceptions de 64 octets .FIFO
4. Prise en charge de l'envoi ou de la réception de données série 5/6/7/8.bit
5. Prend en charge les bits de communication asynchrones standard tels que le démarrage, l'arrêt et le contrôle de parité.
6. La vitesse de transmission maximale de l'horloge peut être prise en charge jusqu'à 4.Mbps
7. Prend en charge le mode de contrôle automatique du débit.UART0/3
RK3399 UART
La description des broches est présentée dans la figure ci-dessous :
2. Connexion UART
ROCKPi 4A
La carte dispose d'un port d'extension à 40 broches, comme le montre l'image ci-dessous :radxa
RockPI 4A
La carte unique est utilisée comme port série de débogage, et la méthode de connexion des broches pour la conversion en port série est la suivante :UART2
USB
TTL
Carte unique RockPI4A | Port série USB vers TTL |
---|---|
PIN8 (UART2_TXD) | RXD |
PIN9 (GND) | GND |
PIN10 (UART2_RXD) | TXD |
RockPI 4A
La configuration du port série de débogage de la carte unique est illustrée dans la figure ci-dessous :
Lors de la connexion du port série, vous devez d'abord vous assurer que la connexion est correcte, puis vérifier si les niveaux de broches du port série sont compatibles et si la configuration des paramètres du port série est correcte, sinon le port série risque d'être indisponible ou tronqué.GND
3.Configuration UART
Prenons l'exemple d'une seule carte pour configurer la configuration dans l'introduction .ROCKPI 4A
RK3399 DTS
UART
3.1. Alias du port série
Les périphériques de port série ordinaires seront numérotés en fonction du numéro de port série et seront enregistrés comme périphérique correspondant .dts
aliases
serialx
ttySx
Fichier de configuration: .arch/arm64/boot/dts/rockchip/rk3399.dtsi
RK3399 DTS
est défini comme suit :aliases
alias { ... série0 = &uart0; série1 = &uart1; série2 = &uart2; série3 = &uart3; série4 = &uart4; } ;
Si vous enregistrez la modification sous , vous pouvez apporter les modifications suivantes :UART4
ttyS1
alias { ... Serial0 = &uart0; Serial1 = &uart4; ## Utilisez uart4 pour remplacer uart1 ... Serial4 = &uart1 } ;
3.2.Configuration du port série
Fichier de configuration: .arch/arm64/boot/dts/rockchip/rk3399.dtsi
UART0 dts
La configuration est la suivante :
uart0 : série@ff180000 { compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart" ; <0x0 0xff180000 0x0 0x100> ; adresse de registre 0xff180000 et taille de mappage 0x100 horloges = <&cru SCLK_UART0 >, <&cru PCLK_UART0>; ## L'horloge utilisée par uart0 clock-names = "baudclk", "apb_pclk"; interruptions = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>; ## uart0 utilise l'interruption SPI, numéro d'interruption 131 (99+32) , Le mode DMA n'est pas utilisé reg-shift = <2>; ## L'adresse du registre est décalée de 2 bits, c'est-à-dire offset+4 reg-io-width = <4> ## La largeur en bits du registre est de 32 bits. . pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ## uart0 utilise l' état de la broche de contrôle de flux = "disabled" ; ## État désactivé par défaut } ;
UART0 pinmux
configuration, y compris les broches de contrôle de flux .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>; } ; } ;
Note:
RK3399 UART0
Le numéro d'interruption est 131. Le numéro d'interruption commence à 32 et le numéro d'interruption commence à 0 par défaut, donc le numéro d'interruption configuré est : 131-32, soit 99.SPI
dts
SPI
UART0
Après le démarrage du système, vous pouvez visualiser les interruptions du port série (131 et 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 Niveau série ... 222 : 301 0 0 0 0 0 GICv3 132 Débogage de niveau ... Err : 0
3.3. Activation du port série
Fichier de configuration: .arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi
UART0 dts
La configuration d'activation est la suivante :
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts>; status = "ok"; ## ok : activez la fonction du port série ; désactivez la fonction du port série. }; & uart2 { status = "ok"; ## Activer le port série 2 };
Note:
status = "okay"
ou , mais ne peut pas être utilisé ."ok"
enable
Le code d'analyse du noyau est le suivant :
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")) return true; } retourne faux ; }
3.4、ttyFIQ0
Le système est utilisé comme un appareil./dev/ttyFIQ0
console
Fichier de configuration : , le contenu est le suivant :arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi
fiq_debugger: fiq-debugger { status = "disabled"; compatible = "rockchip,fiq-debugger"; rockchip,serial-id = <2>; ## Utiliser le numéro de port série (UART2), modifier la valeur de cet attribut, et changez le port série. Changez le pinmux du port série en même temps rockchip,signal-irq = <182> ; * Si activé, uart utilise irq au lieu de fiq */ rockchip ,baudrate = <1500000> /* Seulement 115200 et 1500000 */ pinctrl -names = " pinctrl-0 = <&uart2c_xfer>; -identifiant };
RockPI 4A
Pour le système utilisé par la carte , définissez les paramètres dans le fichier de configuration.Debian
extlinux.conf
console
root@xiaotianbsp:/boot/extlinux# cat extlinux.conf timeout 10 menu titre sélectionner 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 ## Activer l'impression anticipée, ttyFIQ0 est utilisé comme périphérique de console, le débit en bauds du port série est de 1,5 M, 8 bits de données, 1 bit d'arrêt ajouté earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/ init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4
Une fois le système démarré, vous pouvez le visualiser.cmdline
root@xiaotianbsp:~# cat /proc/cmdline earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4
4. Pilote UART
RK3399 Linux4.4
Le pilote du noyau utilise le pilote universel 8250, le type est . Principaux dossiers de mise en œuvre :UART
16550A
drivers/tty/serial/8250/8250_dma.c ## Pilotes d'implémentation UART dma/tty/serial/8250/8250_dw.c ## Pilote de port série Synopsys DesignWare 8250 drivers/tty/serial/8250/8250_early.c ## première console Implementation drivers/tty/serial/8250/8250_port.c ## Interfaces associées pour la configuration du port UART
UART
Les pilotes et le débogage seront présentés plus tard.
5. Débogage du journal du noyau
Dans les systèmes embarqués, la chose la plus courante consiste à utiliser le port série pour générer les journaux du noyau à des fins de débogage fonctionnel.Linux
5.1、printk
Dans le noyau, des fonctions sont disponibles pour afficher les informations du noyau dans le tampon d'informations du noyau.Linux
printk()
La sortie du journal du noyau est divisée en différents niveaux, fichier de définition : , comprenant :include/linux/kern_levels.h
#define LOGLEVEL_EMERG 0 /* le système est inutilisable */ #define LOGLEVEL_ALERT 1 /* une action doit être prise immédiatement */ #define LOGLEVEL_CRIT 2 /* conditions critiques */ #define LOGLEVEL_ERR 3 /* conditions d'erreur */ #define LOGLEVEL_WARNING 4 /* conditions d'avertissement */ #define LOGLEVEL_NOTICE 5 /* condition normale mais significative */ #define LOGLEVEL_INFO 6 /* informatif */ #define LOGLEVEL_DEBUG 7 /* messages de niveau débogage */
En plus des fonctions, vous pouvez également utiliser et .printk()
pr_**()
dev_**()
pr_**
Fichier de définition : , la macro est définie comme suit :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_**
Fichier de définition : , la fonction est définie comme suit :drivers/base/core.c
#define definition_dev_printk_level(func, kern_level) \ void func(const struct périphérique *dev, const char *fmt, ...) \ { \ struct va_format vaf; \ va_list arguments ; \ \ 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); définir_dev_printk_level(dev_alert, KERN_ALERT); définir_dev_printk_level(dev_crit, KERN_CRIT); définir_dev_printk_level(dev_err, KERN_ERR); définir_dev_printk_level(dev_warn, KERN_WARNING); définir_dev_printk_level(dev_notice, KERN_NOTICE); définir_dev_printk_level(_dev_info, KERN_INFO);
5.1.1. Niveau de sortie du journal
Le niveau de sortie du journal du noyau peut être ajusté en modifiant la valeur de ou .loglevel
/proc/sys/kernel/printk
Avant le démarrage du système, vous pouvez ajuster la sortie du journal du port série via la configuration.loglevel
root@xiaotianbsp:~# cat /boot/extlinux/extlinux.conf ... label kernel-debug kernel /debug/Image fdt /debug/rk3399-rock-pi-4a.dtb ## Modifier le niveau de journalisation pour ajuster la sortie du port série niveau de journalisation ajouter earlyprintk console=ttyFIQ0,1500000n8 loglevel=4 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4 no_console_suspend initcall_debug
D'autres systèmes (tels que : ou ) sont généralement modifiés en .Ubuntun、Buildroot
Android
bootargs
loglevel
Note:
no_console_suspend
Utilisé pour le débogage de la gestion de l'alimentation du système Linux, ce qui signifie qu'une fois le système en veille (suspension), le port série ne se met pas en veille et peut toujours émettre.
Une fois le système démarré, le niveau de sortie du journal du port série peut également être ajusté de manière dynamique.
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
Les nombres correspondent à différents niveaux de journalisation. Modifiez simplement le niveau de journalisation du port.console
int console_printk[4] = { CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */ ## Niveau de journalisation de la console MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */ ## Niveau de journalisation des messages par défaut CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel */ ## Niveau de journalisation minimum de la console CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */ ##Niveau de journalisation de la console par défaut };
5.1.2. Horodatage du journal
Après le démarrage du système, l'affichage des horodatages des journaux du noyau peut être ajusté de manière dynamique.
## 1. La valeur de l'heure est Y, ce qui signifie l'horodatage root@xiaotianbsp:/# cat /sys/module/printk/parameters/time Y ## 2. À ce moment, le journal affiche un horodatage root@xiaotianbsp:/ # find .-name time [ 1719.836194] FAT-fs (sda4) : erreur, accès invalide à FAT (entrée 0x07b03538) [ 1719.836874] FAT-fs (sda4) : erreur, accès invalide à FAT (entrée 0x07b03538) ## 3. Définissez la valeur de l'heure sur N root@xiaotianbsp:/# echo N > /sys/module/printk/parameters/time ## 4. À ce stade, le journal affiche un horodatage root@xiaotianbsp:/# -name time FAT . -fs (sda4) : erreur, accès invalide à FAT (entrée 0x07b03538) FAT-fs (sda4) : erreur, accès invalide à FAT (entrée 0x07b03538)
5.2、dmesg
Après le démarrage du système, si vous avez manqué la phase de démarrage du noyau ou si vous utilisez un port non série (par exemple : connexion) pour connecter la carte de débogage, vous pouvez utiliser pour afficher le journal du noyau.adb/ssh
dmesg
dmesg
L'utilisation est la suivante :
root@xiaotianbsp:/# dmesg -h Utilisation : dmesg [options] Afficher ou contrôler le tampon en anneau du noyau. Options : -C, --clear effacer le tampon en anneau du noyau -c, --read-clear lire et effacer tous les messages -D, --console-off désactiver l'impression des messages sur la console -E, --console-on activer l'impression des messages sur la console -F, --file <fichier> utiliser le fichier à la place du tampon du journal du noyau -f, - -facility <list> restreindre la sortie aux fonctionnalités définies -H, --human sortie lisible par l'homme -k, --kernel afficher les messages du noyau -L, --color[=<when>] coloriser les messages (auto, toujours ou jamais) les couleurs sont activés par défaut -l, --level <list> restreindre la sortie aux niveaux définis -n, --console-level <level> définir le niveau des messages imprimés sur la console -P, --nopager ne pas diriger la sortie vers un pager - r, --raw affiche le tampon de message brut -S, --syslog force à utiliser syslog(2) plutôt que /dev/kmsg -s, --buffer-size <size> taille du tampon pour interroger le tampon en anneau du noyau -u , --userspace afficher les messages de l'espace utilisateur -w, --follow attendre les nouveaux messages -x, --decode fonction de décodage et niveau en chaîne lisible -d, --show-delta afficher le delta de temps entre les messages imprimés -e, --reltime afficher l'heure locale et le delta de l'heure dans un format lisible -T, --ctime afficher un horodatage lisible par l'homme (peut être inexact !) -t, --notime n'afficher aucun horodatage avec les messages --time-format <format> afficher l'horodatage en utilisant le format donné : [delta|reltime|ctime|notime|iso] La suspension/la reprise rendra les horodatages ctime et iso inexacts. -h , --help affiche cette aide et quitte -V, --version affiche les informations de version et quitte Facilités de journalisation prises en charge kern - messages utilisateur du noyau - courrier de messages aléatoires au niveau de l'utilisateur - démon du système de messagerie - authentification des démons système - messages de sécurité/autorisation syslog - messages générés en interne par syslogd lpr - actualités du sous-système d'imprimante en ligne - sous-système d'actualités réseau Journal pris en charge émergent - le système est inutilisable alerte - une action doit être prise immédiatement critique - conditions critiques err - avertissement des conditions d'erreur - avis des conditions d'avertissement - informations sur les conditions normales mais significatives - débogage informatif - messages de niveau débogage Pour plus de détails, voir dmesg(1).
5.2.1. Afficher les journaux du noyau
root @ xiaotianbsp: / # dmesg [0,000000] démarrage de Linux sur le CPU physique 0x0 [0,000000] Initialisation du CGROUP subsys CPUSET [0.000000 ] Initialisation du CGROUP CPU CPU [0.000000] CGROUP INITIAL ga14f6502e045 (root@2705a206000b) (gcc version 7.3.1 20180425 [linaro-7.3-2018.05 révision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) # 22 SMP mar. 30 juillet 10:32:28 UTC 2019
5.2.2. Limiter le niveau de sortie du journal
## 仅输出error信息 root@xiaotianbsp:/# dmesg -l err [ 2.170152] rockchip-pcie f8000000.pcie : délai d'expiration de la formation de liaison PCIe gen1 ! [ 2.175658] rk-vcodec ff650000.vpu_service : impossible de trouver le nœud power_model [ 2.180010] rk-vcodec ff660000.rkvdec : impossible de trouver le nœud power_model [ 2.200359] rockchip-vop ff900000.vop : propriété rockchip, grf manquante [ 2.201913] rockchip- vop ff8f0000.vop : propriété rockchip, grf manquante [2.203632] i2c i2c-9 : of_i2c : échec des modalités sur /hdmi@ff940000/ports [2.240381] mali ff9a0000.gpu : échec de l'obtention du régulateur [2.240839] mali : Puissance échec de l'initialisation du contrôle [2.260317] rk_gmac-dwmac fe300000.ethernet : impossible d'obtenir l'horloge clk_mac_speed
## 同时输出error和warning信息 root@xiaotianbsp:/# dmesg -l err,warn [ 0.000000] rockchip_clk_register_frac_branch : impossible de trouver dclk_vop0_frac en tant que parent de dclk_vop0, les changements de taux peuvent ne pas fonctionner [ 0.000000] ister_frac_branch : impossible de trouver dclk_vop1_frac comme parent de DCLK_VOP1, les changements de taux peuvent ne pas fonctionner [0,000000] ROCKCHIP_CPUCLK_PRE_RATE_CHANGE: Limitant Alt-Divider 33 à 31 [1.589058] Thermal Thermal_zone1: Power_Allocator: Sustainable_Power sera estimé [1.637902] Phy.1C Échec de l'obtention du régulateur d'alimentation VBUS [ 1.639962] phy phy-ff770000.syscon:[email protected] : Échec de l'obtention du régulateur d'alimentation VBUS [ 2.170152] rockchip-pcie f8000000.pcie : délai d'expiration de la formation de liaison PCIe gen1 !
5.2.3. Rechercher une certaine information
root@xiaotianbsp:~# dmesg | grep rockchip-vop [ 2.197270] rockchip-vop ff900000.vop : propriété rockchip, grf manquante [ 2.198853] rockchip-vop ff8f0000.vop : propriété rockchip, grf manquante root@xiaotianbsp : ~# dmesg | grep xiaotianbsp root@xiaotianbsp : ~#
5.2.4. Effacer les informations du tampon en anneau
root@xiaotianbsp:/# dmesg -c [ 0.000000] Démarrage de Linux sur le processeur physique 0x0 [ 0.000000] Initialisation du sous-système cgroup cpuset [ 0.000000] Initialisation du processeur du sous-système cgroup [ 0.000000] Initialisation du sous-système cgroup cpuacct ... root@xiaotianbsp:/# dmesg root @xiaotianbsp :/#
dmesg
Vous pouvez tester davantage d'utilisations par vous-même.
Remarque : Veuillez indiquer l’auteur et la source lors de la réimpression.
RustDesk a suspendu le service national Taobao (taobao.com) en raison d'une fraude généralisée, a repris le travail d'optimisation de la version Web, Apple a publié la puce M4, les lycéens ont créé leur propre langage de programmation open source en guise de cérémonie de passage à l'âge adulte - Les internautes ont commenté : S'appuyer sur Selon la défense, Yunfeng a démissionné d'Alibaba et envisage de produire à l'avenir la destination des programmeurs de jeux indépendants Visual Studio Code 1.89, a été officiellement annoncé par Huawei. L'ajustement du poste de Yu Chengdong a été cloué au « pilier de la honte FFmpeg ». « Il y a 15 ans, mais aujourd'hui il doit nous remercier - Tencent QQ Video venge sa honte précédente ? La station miroir open source de l'Université des sciences et technologies de Huazhong est officiellement ouverte à l'accès au réseau externe