在Linux中启用LX2160A的UART2

问题描述 投票:0回答:1

我尝试在 LX2160ARDB 板上运行 Linux 的 SoC 上的用户应用程序中使用 UART 串行端口。

有 2 个 UART 端口使用 PL011 UART 硬件(UART1、UART2)。

Linux启动后,我可以找到2个UART端口的设备节点(/dev/ttyAMA0、/dev/ttyAMA1)。

应用程序对设备文件执行

open(/dev/ttyAMAx)
write()

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

int main( void )
{
    int fd;

    int retn;
    int buf[10] = "write...\n";

    /* Open UART */
    fd = open( "/dev/ttyAMA1", O_RDWR );
    if( fd < 0 )
    {
        perror("Open /dev/ttyAMA1 error!");
        exit(-1);
    }
    printf("Opening /dev/ttyAMA1 -> success!\n");

    /* Write Operation - Tx start */
    int i;
    for( i = 0; i < 10; i++ )
    {
        retn = write( fd, buf, 10 );
        if( retn < 0 )
            printf("Write() failed... retn=%d\n");
        else
            printf("Write() succeeded! retn=%d\n");
        sleep(1);
    }

    /* Close UART */
    printf("Closing /dev/ttyAMA1\n");
    close(fd);

    return 0;
}

我通过 RS232 电缆连接 SoC 的 UART 端口和我的笔记本电脑并运行应用程序,并通过终端仿真器检查信号。

尝试 /dev/ttyAMA0 (UART1) 时,我可以看到信号(“写... “字符串)在连接到 UART1 端口的终端仿真器上,但是当尝试 /dev/ttyAMA1 (UART2) 时,我看不到信号(“写... 连接到 UART2 端口的终端仿真器上的“字符串),并且应用程序进程不会终止。 ( 在这两种情况下,open()、write() 函数都返回有效值。 )

我通过访问/dev/mem检查了每个UART的控制寄存器值,发现UART2的ENABLE位没有设置为1,而UART1的ENABLE位设置为1。 (与设置波特率和数据位相关的寄存器也是如此。)

...
int main( void )
{
...
    fd = open("/dev/mem", O_RDWR | O_SYNC);
...
    /* mmap() UART, x can be 1 or 2 */
    baseaddr = mmap(0,
                    UARTx_SIZE,
                    PROT_READ | PROT_WRITE,
                    MAP_SHARED,
                    fd,
                    UARTx_BASE);
    if( baseaddr == NULL )
    {
        perror("mmap() error");
        exit(-1);
    }
    printf("mmap succeeded!\n");

    /* set pointer of UART Control Register */
    uartcr = ( uint32_t * )( baseaddr + UARTCR_OFFSET );
    
    /* check value of Control Register */
    printf("Current UARTCR value: %#010x\n", *( uartcr ));

...
}

----------
[RESULT]

UART1: Current UARTCR value: 0x00000b01 ( bit[0] is 1 )
UART2: Current UARTCR value: 0x00000300 ( bit[0] is 0 )

UARTCR's bit[0] is UARTEN bit

为控制台选择了 UART1,因此 Bootloader 似乎配置了 UART1 并设置了 ENABLE 位,但没有配置 UART2。

我的问题是:

如何在 Linux 中从用户应用程序设置 UART2 的 ENABLE 位?更准确地说,如何调用 UART2 的初始化,而不是使用 /dev/mem

我们不能在 Linux 上设置 UART 控制器的 ENABLE 位吗?只能在Bootloader中吗?

我搜索了一些驱动程序代码(amba-pl011.c等),但我无法理解串行设备的层..

其他材料


我尝试了

termios
进行 UART2 设置。但看不到 Tx 字符串(“Hello World! ”)。 我使用的终端仿真器 (Tera Term) 设置是“115200 波特率、8 位数据位、无奇偶校验、1 位停止位、无硬件流控制”

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>

int main( void )
{
    int fd, ret;
    char tx_buf[] = "Hello World!\n\r";
    structt termios options;

    /* open UART */
    fd = open( "/dev/ttyAMA1", O_RDWR | O_NOCTTY );
    if( fd < 0 )
    {
        printf("ERROR open /dev/ttyAMA1\n");
        return -1;
    }
    
    /* configure UART */
    tcgetattr( fd, &options );
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cc[VTIME] = 10;
    options.c_cc[VMIN] = 0;
    options.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
    options.c_oflag &= ~OPOST;
    options.c_iflag &= ~( ICRNL | IXON );
    cfsetispeed( &options, B115200 );
    cfsetospeed( &options, B115200 );
    options.c_cflag |= ( CLOCAL | CREAD );
    tcflush( fd, TCIFLUSH );
    tcsetattr( fd, TCSANOW, &options );

    /* test UART */
    int i;
    for( i = 0; i < 10; i++ )
    {
        ret = write( fd, tx_buf, sizeof(tx_buf) );
        if( ret != sizeof(tx_buf) )
            printf("ERROR write, ret=%d\n\r", ret);
        printf("write successfully, ret=%d\n\r", ret);
        sleep(1);
    }
    printf("Tx Test END!\n\r");

    /* close UART */
    close(fd);

    return 0;
}
linux serial-port linux-device-driver uart
1个回答
0
投票

您应该更改 PBI(预引导加载程序初始化)以正确配置 UART 的 CCSR(QorIQ LX2160A 参考手册,第 8 章服务处理器)。或者您可以简单地在 U-boot 甚至 Linux 控制台中更改 CCSR。当我试图使 UART2 工作时,我从 UART1 读取寄存器并通过 bash 脚本将它们复制到 UART2。 (QorIQ LX2160A 参考手册,第 29 章 UART)

 #!/usr/bin/env bash

 # enable uart2
 ccsr -w 0x21d0024 0x5e
 ccsr -w 0x21d0028 0x3c
 ccsr -w 0x21d002c 0x70
 ccsr -w 0x21d0030 0xb01
 ccsr -w 0x21d003c 0x50

 # same with devmem2, but I recommend to use ccsr command
 devmem 0x21d0024 w 0x5e
 devmem 0x21d0028 w 0x3c
 devmem 0x21d002c w 0x70
 devmem 0x21d0030 w 0xb01
 devmem 0x21d003c w 0x50

您还可以使用 md/mw 命令从 U-boot 控制台更改 ccsr。

=> md 21c0000
021c0000: 00000062 00000000 00000000 00000000    b...............
021c0010: 00000000 00000000 0000013e 00000000    ........>.......
021c0020: 00000000 0000005e 0000003c 00000070    ....^...<...p...
021c0030: 00000b01 00000012 00000050 00000002    ........P.......
021c0040: 00000000 00000000 00000000 00000000    ................
021c0050: 00000000 00000000 00000000 00000000    ................
021c0060: 00000000 00000000 00000000 00000000    ................
021c0070: 00000000 00000000 00000000 00000000    ................
021c0080: 00000000 00000009 00000000 00000000    ................
021c0090: 00000000 00000000 00000000 00000000    ................
021c00a0: 00000000 00000000 00000000 00000000    ................
021c00b0: 00000000 00000000 00000000 00000000    ................
021c00c0: 00000000 00000000 00000000 00000000    ................
021c00d0: 00000000 00000000 00000000 00000000    ................
021c00e0: 00000000 00000000 00000000 00000000    ................
021c00f0: 00000000 00000000 00000000 00000000    ................
=> md 21d0000
021d0000: 00000000 00000000 00000000 00000000    ................
021d0010: 00000000 00000000 00000196 00000000    ................
021d0020: 00000000 00000000 00000000 00000000    ................
021d0030: 00000300 00000012 00000000 00000002    ................
021d0040: 00000000 00000000 00000000 00000000    ................
021d0050: 00000000 00000000 00000000 00000000    ................
021d0060: 00000000 00000000 00000000 00000000    ................
021d0070: 00000000 00000000 00000000 00000000    ................
021d0080: 00000000 00000009 00000000 00000000    ................
021d0090: 00000000 00000000 00000000 00000000    ................
021d00a0: 00000000 00000000 00000000 00000000    ................
021d00b0: 00000000 00000000 00000000 00000000    ................
021d00c0: 00000000 00000000 00000000 00000000    ................
021d00d0: 00000000 00000000 00000000 00000000    ................
021d00e0: 00000000 00000000 00000000 00000000    ................
021d00f0: 00000000 00000000 00000000 00000000    ................

如果您想进行持久更改,您应该参考 PBI ccsr 数据配置。

© www.soinside.com 2019 - 2024. All rights reserved.