Linux カーネル UART

組み込みシステムでは、シリアル ポートはシステム デバッグ用のログ出力に使用でき、短距離低速通信にも使用でき、非常に実用的な通信ポートです。

この記事ではシングルボードカーネルをベースにした機能を紹介します。RockPI 4ALinux 4.4RK3399 UART

1. UART の概要

UART(Universal Asynchronous Receiver/Transmitter): 汎用の非同期送受信機で、短距離、低速、シリアルおよび全二重データ伝送に適しています。

中国では、シリアル ポートは一般にシリアル通信ポートを指します。ピンは 9 本あり、レベルを使用します。PCCOMRS-232

組み込みシステムでは、シリアル ポートは通常ポートを指します。一般的には 3 ピンが使用され、レベルが使用されます。UARTTTL

TTL/RS-232/RS-485レベル基準を指しますが、違いは次のとおりです。

レベル基準 論理0 ロジック 1 転送方法
TTLレベル 0 ~ 0.4V 2.4 ~ 5V 全二重
RS-232レベル 3 ~ 15V -15 ~ -3V 全二重
RS-485レベル -6 ~ -2V 2 ~ 6V 半二重(差動伝送、長距離)

組み込みシングルボードをデバッグする場合、次の図に示すように、シングルボードとのシリアル通信を実装するモジュールを選択できます。USB转TTLPC

RK3399 UARTコントローラーの機能:

1. 5ウェイシリアルポートをサポートします。

2.送信モードをサポートまたは中断します。DMA

3. 2 つの 64 バイト送受信をサポートしますFIFO

4. 5/6/7/8シリアル データの送信または受信をサポートします。bit

5. スタート、ストップ、パリティチェックなどの標準的な非同期通信ビットをサポートします。

6. 最大クロックボーレートは 4 までサポートされます。Mbps

7.自動フロー制御モードをサポートします。UART0/3

RK3399 UARTピンの説明を次の図に示します。

2.UART接続

ROCKPi 4A以下の図に示すように、ボードには 40 ピンの拡張ポートがあります。radxa

RockPI 4A単体ボードはデバッグ用シリアルポートとして使用され、シリアルポートに変換するためのピン接続方法は次のとおりです。UART2USBTTL

RockPI4A シングルボード USB-TTLシリアルポート
PIN8(UART2_TXD) RXD
PIN9(GND) GND
PIN10(UART2_RXD) テキサス州

RockPI 4A単一ボードのデバッグ シリアル ポート構成を次の図に示します。

シリアル ポートを接続するときは、まず接続が正しいことを確認してから、シリアル ポートのピン レベルに互換性があるかどうか、およびシリアル ポートのパラメータ設定が正しいかどうかを確認する必要があります。そうしないと、シリアル ポートが使用できなくなったり、文字化けしたりする可能性があります。GND

3.UARTの設定

はじめに構成を構成する例として単一のボードを取り上げますROCKPI 4ARK3399 DTSUART

3.1. シリアルポートのエイリアス

通常のシリアルポートデバイスは、シリアルポート番号に従って番号が付けられ、対応するデバイスとして登録されますdtsaliasesserialxttySx

設定ファイル: .arch/arm64/boot/dts/rockchip/rk3399.dtsi

RK3399 DTSは次のように定義されますaliases

    エイリアス { 
... serial0 = &uart0;シリアル1 = &uart1;シリアル2 = &uart2;シリアル3 = &uart3;シリアル4 = &uart4; };        
        
        
        
        
        
    

変更を として登録する、次の変更を行うことができます。UART4ttyS1

    エイリアス { 
...シリアル 0 = &uart0;シリアル 1 = &uart4; ## uart1 を uart4 に置き換えます...シリアル 4 = &uart1 ;        
        
        
        
        
    

3.2. シリアルポートの設定

設定ファイル: .arch/arm64/boot/dts/rockchip/rk3399.dtsi

UART0 dts構成は次のとおりです。

    uart0: シリアル@ff180000 {
互換 = "rockchip,rk3399-uart", "snps,dw-apb-uart"; reg = <0x0 0xff180000 0x0 0x100>; ## uart0 レジスタ アドレス 0xff180000 およびマッピング サイズ 0x100クロック = <&cru SCLK_UART0 >, <&cru PCLK_UART0>; ## uart0 によって使用されるクロック クロック名 = "baudclk", "apb_pclk";割り込み = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>; ## uart0 は SPI 割り込み、割り込み番号 131 (99+32) を使用します。 、DMA モードは使用されませんreg-shift = <2>; ## レジスタ アドレスは 2 ビットオフセットされます、つまり、offset+4 reg-io-width = <4>;レジスタ ビット幅は 32 ビットです。 。pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ## uart0 はフロー制御ピンstatus = "disabled" を使用します};        
                       
          
        
        
                    
                 
        
        
        
    

UART0 pinmuxフロー制御ピンを含む構成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>; 
        }; 
    };

注記:

RK3399 UART0割り込み番号は131です。割り込み番号は 32 から始まり、デフォルトでは0 から始まるため、設定された割り込み番号は 131 ~ 32、つまり 99 になります。SPIdtsSPIUART0

システムの起動後、シリアル ポート割り込み (131 および 132) を表示できます。

root@xiaotianbsp:/# cat proc/interrupts 
           CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 
14: 0 0 0 0 0 0 GICv3 29 エッジ Arch_timer 
... 
35: 16 0 0 0 0 0 GICv3 131 レベル シリアル
... 
222: 301 0 0 0 0 0 GICv3 132 レベルのデバッグ
...
エラー: 0

3.3. シリアルポートの有効化

設定ファイル: .arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi

UART0 dts有効にする構成は次のとおりです。

&uart0 { 
    pinctrl-names = "default"; 
    pinctrl-0 = <&uart0_xfer &uart0_cts>; 
    ## ok: シリアル ポート機能をオンにします; 無効: シリアル ポート機能をオフにします。
}; 
&
 uart2 { 
    status = "ok"; ## シリアルポート 2 を有効にする
};

注記:

status = "okay"または、は使用できません"ok"enable

カーネル解析コードは次のとおりです。

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; falseを返します}        
            
    

    

3.4、ttyFIQ0

システムはデバイスとして使用されます。/dev/ttyFIQ0console

設定ファイル: 、内容は次のとおりです。arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi

    fiq_debugger: fiq-debugger { 
status = "disabled";互換性 = "rockchip,fiq-debugger"; Rockchip,serial-id = <2>;シリアル ポート番号 (UART2) を使用して、この属性の値を変更します。同時にシリアルポートの pinmux を切り替えます。Rockchip , irq-mode-enable = <1>; * uart が fiq の代わりに irq を使用する場合 */ rockchip ,baudrate = <1500000>; /* 115200 と 1500000 のみ */ pinctrl-names = "default" = <&uart2c_xfer>; ## pinmux はシリアルに対応する必要があります-id };                    
        
               
        
        
        
        
        
             
    

RockPI 4Aボードが使用するシステムに応じて設定ファイルにパラメータを設定します。Debianextlinux.confconsole

root@xiaotianbsp:/boot/extlinux# cat extlinux.conf
タイムアウト 10
メニュー タイトル カーネルの選択
ラベル
kernel-4.4.154-90-rockchip-ga14f6502e045 
    kernel /vmlinuz-4.4.154-90-rockchip-ga14f6502e045 
    devicetreedir /dtbs/4.4 .154-90-rockchip-ga14f6502e045 
    ## Early printk を有効にします。ttyFIQ0 がコンソール デバイスとして使用されます。シリアル ポートのボー レートは 1.5M、8 データ ビット、1 ストップ ビットです
    。earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/ init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4

システム起動後はそのままご覧いただけます。cmdline

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

4.UARTドライバー

RK3399 Linux4.4カーネルドライバーは 8250 ユニバーサル ドライバーを使用し、タイプは です。主な実装ファイル:UART16550A

drivers/tty/serial/8250/8250_dma.c ## UART dma 実装
drivers/tty/serial/8250/8250_dw.c ## Synopsys DesignWare 8250 シリアル ポート ドライバー
drivers/tty/serial/8250/8250_early.c ## 初期のコンソール実装
drivers/tty/serial/8250/8250_port.c ## UART ポート設定に関連するインターフェイス

UARTドライバーとデバッグについては後ほど紹介します。

5. カーネルログのデバッグ

組み込みシステムでは、機能デバッグのためにシリアル ポートを使用してカーネル ログを出力することが最も一般的です。Linux

5.1、プリントク

カーネルでは、カーネル情報をカーネル情報バッファに出力する関数が用意されています。Linuxprintk()

カーネル ログ出力は、次のようなさまざまなレベルの定義ファイルに分割されます。include/linux/kern_levels.h

#define LOGLEVEL_EMERG 0 /* システムが使用できません */ 
#define LOGLEVEL_ALERT 1 /* 直ちにアクションを実行する必要があります */ 
#define LOGLEVEL_CRIT 2 /* 重大な状態 */ 
#define LOGLEVEL_ERR 3 /* エラー状態 */ 
#define LOGLEVEL_WARNING 4 /*警告状態 */ 
#define LOGLEVEL_NOTICE 5 /* 通常だが重要な状態 */ 
#define LOGLEVEL_INFO 6 /* 情報 */ 
#define LOGLEVEL_DEBUG 7 /* デバッグレベルのメッセージ */

関数に加えて、も使用できますprintk()pr_**()dev_**()

pr_**定義ファイル: 、マクロは次のように定義されます。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_**定義ファイル: 、関数は次のように定義されます。drivers/base/core.c

#definedefine_dev_printk_level(func, kern_level) \        
void func(const struct device *dev, const char *fmt, ...)    \ 
{ \                                
    struct va_format vaf; \                    
    va_list 引数; \                        
\ 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);定義_dev_printk_level(dev_alert, KERN_ALERT);定義_dev_printk_level(dev_crit, KERN_CRIT);定義_dev_printk_level(dev_err, KERN_ERR);定義_dev_printk_level(dev_warn, KERN_WARNING);定義_dev_printk_level(dev_notice, KERN_NOTICE);定義_dev_printk_level(_dev_info, KERN_INFO);                                
                        
                                
                          
                         
                                
                
                                
                           
                               








5.1.1. ログ出力レベル

カーネル ログの出力レベルは、またはの値を変更することで調整できます。loglevel/proc/sys/kernel/printk

システムを起動する前に、設定を通じてシリアル ポートのログ出力を調整できます。loglevel

root@xiaotianbsp:~# cat /boot/extlinux/extlinux.conf 
... 
label kernel-debug 
    kernel /debug/Image 
    fdt /debug/rk3399-rock-pi-4a.dtb 
    ## シリアル ポート出力を調整するためにログレベルを変更しますログレベル
    追加 Earlyprintk console=ttyFIQ0,1500000n8 loglevel=4 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4 no_console_suspend initcall_debug

他のシステム (:や など) は通常、で変更されますUbuntun、BuildrootAndroidbootargsloglevel

注記:

no_console_suspendLinux システムの電源管理のデバッグに使用されます。つまり、システムがスリープ (サスペンド) した後も、シリアル ポートはスリープせず、引き続き出力できます。

システム起動後、シリアルポートのログ出力レベルを動的に調整することもできます。

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の数字はさまざまなログ レベルに対応しています。ポートのログ レベルを変更するだけです。console

int console_printk[4] = { 
        CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */   ## コンソール ログ レベル        
        MESSAGE_LOGLEVEL_DEFAULT, /*default_message_loglevel */   ## デフォルトのメッセージ ログ レベル
        CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel */ ## 最小コンソール ログ レベル
        CONSOLE_LOGLEVEL_DEFAULT, /*default_console_loglevel */ ##デフォルトのコンソールログレベル
};

5.1.2. ログのタイムスタンプ

システムの起動後、カーネル ログのタイムスタンプの表示を動的に調整できます。

## 1. 時間の値は Y です。これは、タイムスタンプ
root@xiaotianbsp:/# cat /sys/module/printk/parameters/time 
Y 
## 2. この時点で、ログにはタイムスタンプ
root@xiaotianbsp:/が表示されます。 # find . -name time 
[ 1719.836194] FAT-fs (sda4): エラー、FAT への無効なアクセス (エントリ 0x07b03538) 
[1719.836874] FAT-fs (sda4): エラー、FAT への無効なアクセス (エントリ 0x07b03538) 
## 3.時間の値を N root@xiaotianbsp:/# echo 
N > /sys/module/printk/parameters/time 
## 4. この時点で、ログにはタイムスタンプ
root@xiaotianbsp:/# find が表示されます。
-fs (sda4): エラー、FAT への無効なアクセス (エントリ 0x07b03538) 
FAT-fs (sda4): エラー、FAT への無効なアクセス (エントリ 0x07b03538)

5.2、dmesg

システムの起動後、カーネルの起動フェーズを見逃した場合、または非シリアル ポート (ログインなど) を使用してデバッグ ボードに接続した場合は、 を使用してカーネル ログを表示できます。adb/sshdmesg

dmesg使用方法は次のとおりです。

root@xiaotianbsp:/# dmesg -h
使用法
: 
dmesg [オプション]
カーネル リング バッファを表示
オプション: -C, --clear カーネル リング バッファをクリアします-c, --read-clear 読み取りおよびクリアすべてのメッセージ-D、--console-off コンソールへのメッセージの印刷を無効にする-E、--console-on コンソールへのメッセージの印刷を有効にする-F、--file <file> カーネル ログ バッファの代わりにファイルを使用する-f、- -facility <list> 出力を定義された機能に制限します-H, --human 人間が判読できる出力-k, --kernel カーネル メッセージを表示します-L, --color[=<when>]                               メッセージを色付けします (自動、常にまたはなし)。デフォルトで有効になります-l, --level <list> 出力を定義されたレベルに制限します-n, --console-level <level> コンソールに出力されるメッセージのレベルを設定します-P, --nopager 出力をページャーにパイプしません- r, --raw 生のメッセージ バッファを出力します-S, --syslog /dev/kmsg ではなく syslog(2) を強制的に使用します-s, --buffer-size <size> カーネル リング バッファをクエリするためのバッファ サイズ-u 、 --userspace ユーザー空間メッセージを表示します-w、 --follow 新しいメッセージを待ちます-x、 --decode 機能とレベルを読み取り可能な文字列にデコードします-d、 --show-delta 印刷されたメッセージ間の時間デルタを表示します-e、 --reltimeローカル時刻とタイムデルタを読み取り可能な形式で表示します。 -T、--ctime 人間が判読できるタイムスタンプを表示します (不正確な可能性があります!) -t、-notime メッセージ付きのタイムスタンプは表示しません     --time-format <format> タイムスタンプを表示します指定された形式を使用します:                                [delta|reltime|ctime|notime|iso]一時停止/再開すると、ctime および iso タイムスタンプが不正確になります。-h , --help このヘルプを表示して終了します。-V, --version バージョン情報を出力して終了します。サポートされるログ機能:     kern - カーネル メッセージ    user - ランダムなユーザー レベル メッセージ    mail - メール システム  デーモン - システム デーモン    auth - セキュリティ/認可メッセージ  syslog - syslogd によって内部的に生成されるメッセージ     lpr - ライン プリンタ サブシステム    ニュース - ネットワーク ニュース サブシステムサポートされるログレベル (優先度):    emerg - システムが使用不可です   alert - 直ちにアクションを実行する必要があります    crit - 重大な状態














































     err - エラー状態
    warn - 警告状態
  Notice - 正常だが重要な状態
    info - 情報
   デバッグ - デバッグレベルのメッセージ
詳細については

5.2.1. カーネルログの表示

root@xiaotianbsp:/# dmesg 
[ 0.000000] 物理 CPU 0x0 での Linux の起動
[ 0.000000] cgroup subsys cpuset の初期化
[ 0.000000] 
cgroup subsys cpuacct の初期化
[ 0.000000] Linux バージョン 4.4.154 -90-ロックチップ- ga14f6502e045 (root@2705a206000b) (gcc バージョン 7.3.1 20180425 [linaro-7.3-2018.05 リビジョン d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) # 22 SMP 2019 年 7 月 30 日火曜日 10:32:28 UTC

5.2.2. ログ出力レベルの制限

## 仅输出力エラー情報
root@xiaotianbsp:/# dmesg -l err 
[ 2.170152] Rockchip-pcie f8000000.pcie: PCIe リンク トレーニング gen1 タイムアウト! 
[ 2.175658] rk-vcodec ff650000.vpu_service: power_model ノードが見つかりませんでした
[ 2.180010] rk-vcodec ff660000.rkvdec: power_model ノードが見つかりませんでした
[ 2.200359] Rockchip-vop ff900000.vop: Rockchip,grf プロパティが見つかりません
[ 2.201913]ロックチップ- vop ff8f0000.vop: Rockchip,grf プロパティがありません
[ 2.203632] i2c i2c-9: of_i2c: /hdmi@ff940000/ports でのモーダリア障害
[ 2.240381] mali ff9a0000.gpu: レギュレーターの取得に失敗しました
[ 2.240839] mali ff9a0000.gpu:パワーコントロールの初期化に失敗しました
[ 2.260317] rk_gmac-dwmac fe300000.ethernet: クロック clk_mac_speed を取得できません
## 同時出力エラーと警告情報
root@xiaotianbsp:/# dmesg -l err,warn 
[ 0.000000] Rockchip_clk_register_frac_branch: dclk_vop0 の親として dclk_vop0_frac が見つかりませんでした。レート変更が機能しない可能性があります
[ 0.000000] Rockchip_clk_register_frac_branch: 見つかりませんでした親としての dclk_vop1_frac dclk_vop1 の場合、レート変更が機能しない可能性があります
[ 0.000000] Rockchip_cpuclk_pre_rate_change: alt-divider 33 を 31 に制限します
[ 1.589058] サーマル Thermal_zone1: power_allocator: Sustainable_power が推定されます
[ 1.637902] phy-ff770000.syscon:[email protected] : VBUS 供給レギュレータの取得に失敗しました
[ 1.639962] phy phy-ff770000.syscon:[email protected]: VBUS 供給レギュレータの取得に失敗しました
[ 2.170152] Rockchip-pcie f8000000.pcie: PCIe リンク トレーニング gen1 タイムアウト!

5.2.3. 特定の情報を検索する

root@xiaotianbsp:~# dmesg | grep Rockchip-vop 
[ 2.197270] Rockchip-vop ff900000.vop: Rockchip,grf プロパティが欠落しています
[ 2.198853] Rockchip-vop ff8f0000.vop: Rockchip,grf プロパティが欠落しています
root@xiaotianbsp:~# dmesg | grep xiaotianbsp 
root@xiaotianbsp:~#

5.2.4. リングバッファ情報のクリア

root@xiaotianbsp:/# dmesg -c 
[ 0.000000] 物理 CPU 0x0 で Linux を起動
[ 0.000000] cgroup subsys cpuset の初期化
[ 0.000000] cgroup subsys cpu の初期化
[ 0.000000] cgroup subsys cpuacct の初期化
... 
root@xiaotianbsp:/# dmesg 
root @xiaotianbsp:/#

dmesgさらに多くの使い方を自分でテストできます。

注:転載する場合は、著者と出典を明記してください。

RustDesk、詐欺横行のため 国内サービス淘宝網(taobao.com)を停止、ウェブバージョンの最適化作業を再開、 アップルがM4チップをリリース、 高校生が成人式として独自のオープンソースプログラミング言語を作成 - ネチズンのコメント:弁護側は、 ユンフェン氏がアリババを辞任し、将来的にはWindowsプラットフォーム上で Visual Studio Code 1.89を開発する予定であると、 独立系ゲームプログラマーの目標となる Yu Chengdong氏の雇用調整が 「FFmpegの恥の柱」に釘付けになったと正式に発表した15年前、しかし今日彼は私たちに感謝しなければなりません - Tencent QQ Videoは以前の恥を晴らしますか?華中科技大学のオープンソースミラーステーションが外部ネットワークアクセスに正式にオープン
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4702401/blog/5558194