리눅스 커널 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 직렬 포트
핀8(UART2_TXD) RXD
PIN9(GND) 접지
핀10(UART2_RXD) TXD

RockPI 4A단일 보드의 디버깅 직렬 포트 구성은 아래 그림에 표시됩니다.

직렬 포트를 연결할 때 먼저 연결이 올바른지 확인한 다음 직렬 포트 핀 레벨이 호환되는지, 직렬 포트 매개변수 구성이 올바른지 확인해야 합니다. 그렇지 않으면 직렬 포트를 사용할 수 없거나 깨질 수 있습니다.GND

3. UART 구성

소개 에서 구성을 구성하려면 단일 보드를 예로 들어 보겠습니다 .ROCKPI 4ARK3399 DTSUART

3.1. 직렬 포트 별칭

일반 시리얼 포트 장치는 시리얼 포트 번호에 따라 번호가 매겨져 해당 장치로 등록 됩니다 .dtsaliasesserialxttySx

구성 파일: .arch/arm64/boot/dts/rockchip/rk3399.dtsi

RK3399 DTS다음과 같이 정의됩니다 .aliases

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

수정사항을 로 등록 하면 다음과 같은 수정이 가능합니다.UART4ttyS1

    aliases { 
... serial0 = &uart0; serial1 = &uart4; ## uart1 대체하려면 uart4 = &uart1 ;        
        
        
        
        
    

3.2. 직렬 포트 구성

구성 파일: .arch/arm64/boot/dts/rockchip/rk3399.dtsi

UART0 dts구성은 다음과 같습니다.

    uart0: serial@ff180000 { 
Compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; reg = <0x0 0xff180000 0x0 0x100> ## uart0 레지스터 주소 0xff180000 및 매핑 크기 0x100 클럭 = <&cru SCLK_UART0 >, <&cru PCLK_UART0>; ## uart0에서 사용되는 시계 clock-names = "baudclk", "apb_pclk" Interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0> ## uart0은 SPI 인터럽트, 인터럽트 번호 131(99+32)을 사용합니다. , DMA 모드는 사용되지 않습니다. reg-shift = <2>; ## 레지스터 주소는 2비트만큼 오프셋됩니다. 즉, 오프셋+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/인터럽트 
           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 레벨 직렬 
... 
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, "okay") || !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"; Compatible = "rockchip,fiq-debugger"; rockchip,serial-id = <2>; ## 직렬 포트 번호(UART2)를 사용하여 이 속성의 값을 수정합니다. 동시에 직렬 포트의 pinmux를 전환합니다. rockchip,signal-irq = <182> rockchip, irq-mode-enable = <1>; * uart가 fiq 대신 irq를 사용하는 경우 */ rockchip ,baudrate = <1500000> /* 115200 및 1500000만 */ pinctrl-names = "default"; ## pinmux는 직렬과 일치해야 합니다 . -ID };                    
        
               
        
        
        
        
        
             
    

RockPI 4A보드에서 사용하는 시스템의 경우 구성 파일에서 매개변수를 설정합니다 .Debianextlinux.confconsole

root@xiaotianbsp:/boot/extlinux# cat extlinux.conf 
timeout 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/cmdline 
earlyprintk 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

#define Define_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); 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. 로그 출력 수준

커널 로그 출력 수준 은 또는 값을 수정하여 조정할 수 있습니다.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 
    ## loglevel을 수정하여 직렬 포트 출력 조정 로그 수준 
    추가 earlyprintk console=ttyFIQ0,1500000n8 loglevel=4 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4 no_console_suspens 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, /* 최소_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 -name time 
FAT 가 표시됩니다. -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 - 커널 메시지     사용자 - 임의 사용자 수준 메시지     메일 - 메일 시스템   데몬 - 시스템 데몬     인증 - 보안/인증 메시지   syslog - syslogd에 의해 내부적으로 생성된 메시지      lpr - 라인 프린터 하위 시스템     뉴스 - 네트워크 뉴스 하위 시스템 ​지원되는 로그 수준(우선순위):    emerg - 시스템을 사용할 수 없음    경고 - 즉시 조치를 취해야 함     crit - 위험 조건














































     err - 오류 조건 
    경고 - 경고 조건 
  주의 - 정상이지만 중요한 조건 
    정보 - 정보 
   디버그 - 디버그 수준 메시지 
​​자세한 내용은 dmesg(1)을 참조하세요.

5.2.1. 커널 로그 표시

root@xiaotianbsp:/# dmesg 
[ 0.000000] 물리적 CPU 0x0에서 Linux 부팅 
[ 0.000000] cgroup subsys cpuset 초기화 
[ 0.000000] cgroup subsys CPU 초기화 
[ 0.000000] cgroup subsys cpuacct 초기화 
[ 0.000000] Linux 버전 4.4.154-90-rockchip- 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. 로그 출력 수준 제한

## 仅输流error信息
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] rockchip - vop ff8f0000.vop: rockchip,grf 속성 누락 
[ 2.203632] i2c i2c-9: of_i2c: /hdmi@ff940000/ports의 모달리아 실패 
[ 2.240381] 말리 ff9a0000.gpu: 조정기를 가져오지 못했습니다. 
[ 2.240839] 말리 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 Thermal_zone1: power_allocator: 지속 가능한_전력이 추정됩니다. 
[ 1.637902] phy 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(taobao.com)를 중단하고 웹 버전 최적화 작업을 재개했으며 Apple은 M4 칩을 출시했으며 고등학생들은 성인식으로 자신의 오픈 소스 프로그래밍 언어를 만들었습니다. 네티즌들은 다음과 같이 논평했습니다. 변호인인 Yunfeng은 Alibaba에서 사임했으며 향후 Windows 플랫폼의 Visual Studio Code 1.89를 독립 게임 프로그래머를 위한 대상인 Huawei에 의해 공식적으로 발표되었습니다. Yu Chengdong의 직업 조정은 "FFmpeg Pillar of Shame"에 포함되었습니다. ” 15년 전, 오늘 그는 우리에게 감사해야 합니다. Tencent QQ Video가 이전의 수치심을 복수한다고요? 화중과기대학교 오픈소스 미러 스테이션이 외부 네트워크 접속에 공식적으로 개방되었습니다.
{{o.이름}}
{{이름}}

추천

출처my.oschina.net/u/4702401/blog/5558194