This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

uart可发不可收



问题如下:使用pc端串口调试助手调试am335x的uart4,am335x向外发送数据,PC端可接收到,但是通过PC端调试助手发送给am335x,am335x一直读取数据失败。而且串口调试助手本身会直接收到已发送的数据。

测试代码如下:

#include <stdio.h>
#include     <stdlib.h>     /*标准函数库定义*/
#include     <unistd.h>     /*Unix标准函数定义*/
#include     <sys/types.h>  /**/
#include     <sys/stat.h>   /**/
#include     <fcntl.h>      /*文件控制定义*/
#include     <termios.h>    /*PPSIX终端控制定义*/
#include     <errno.h>      /*错误号定义*/

int fd = -1;


int open_port(char port[])
{
	fd = open( port, O_RDWR | O_NONBLOCK ); 

	if (fd<0) {
	    printf("open serialport failed!\n");
	    return -1;
	}

	struct termios tio;

	tcgetattr(fd, &tio);
	//bzero(&tio, sizeof(tio));
	// these must be set first, don't know why
	tio.c_cflag |= CLOCAL;
	tio.c_cflag |= CREAD;
	tio.c_cflag &= ~CSIZE;
	// baud rate 115200
	if (cfsetispeed(&tio, B115200) != 0)    {
	    printf("cfsetispeed failed\n");
	    return -1;
	}
	if (cfsetospeed(&tio, B115200) != 0)
	{
	    printf("cfsetospeed failed\n");
	    return -1;
	}
	// parity NONE
	tio.c_cflag &= ~PARENB;
	tio.c_iflag &= ~INPCK;
	tio.c_iflag |= IGNBRK;
	// data bit 8
	tio.c_cflag |= CS8;
	// stop bit 1
	tio.c_cflag &= ~CSTOPB;
	// others
	tio.c_cc[VTIME] = 0;
	tio.c_cc[VMIN]  = 0;
	// flush settings
	if(tcflush(fd, TCIOFLUSH) != 0) 
	{
	    printf("open serialport: Flushing %s ERROR!\n\n", port);
	    return -1;
	}

	if(tcsetattr(fd, TCSANOW, &tio) != 0)
	{
	    printf("open serialport: Setting %s ERROR!\n\n", port);
	    return -1;
	}
	return 0;
}


int main(int argc, char* argv[])
{
	char port_num[10] = {0,0,0,0,0,0,0,0,0,0};
	char wr_num[2] = {1,2};
	int ret;

	if(argc != 2)
	{
		printf("%s SerialPortDevFile\n", argv[0]);
		return -1;
	}
	if(open_port(argv[1]) != 0)
	{
		printf("Fail to open %s!\n", argv[1]);
		return -2;
	}
	else 
	{
		while(1)
		{
			printf( "start read %s\n", argv[1] );
			ret = read( fd, (void *)port_num, 9 );
			if( ret == -1 )
			printf( "ret = -1\n" );
			else
			{
				printf("ret = %d\n", ret);
				printf( "%s received : %s\n", argv[1], port_num );
			}
			printf( "start write %s\n", argv[1] );
			ret = write( fd, (void *)wr_num, 2 );
			sleep(5);
		}

		close_com();

		return 0;
	}
}

很简单的程序,只是循环接收发送。dts中配置uart4如下:

&uart4 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&uart4_pins_default>;
	pinctrl-1 = <&uart4_pins_sleep>;

	status = "okay";
};

uart4_pins_default: pinmux_uart4_pins_default {
		pinctrl-single,pins = <
			0x168 (PIN_INPUT_PULLUP | MUX_MODE1)	/* uart0_ctsn.uart4_rxd */ 
			0x16C (PIN_OUTPUT_PULLDOWN | MUX_MODE1) 	/* uart0_rtsn.uart4_txd */
		>;
	};

	uart4_pins_sleep: pinmux_uart4_pins_sleep {
		pinctrl-single,pins = <
			0x168 (PIN_INPUT_PULLDOWN | MUX_MODE7)
			0x16C (PIN_INPUT_PULLDOWN | MUX_MODE7)
		>;
	};

硬件上,uart4的收发信号线 直接 接到 PC端 usb转串口(232)线,信号线上没有连接任何上下拉等。

  • 除了上边的dts中配置外,不知道还有没有哪里需要配置的?

    各位还有什么比较好的测试串口的方法也希望能赐教一下下。

    已经调了两天了,总觉得不是大问题,但是真的很无奈啊!

    先行谢过各位的回复

  • 忘记说了,sdk是用的sdk08版本,文件系统用的sdk包中filesystem下的arago-base-tisdk-image-am335x-evm这个。

  • 日志信息如下:

    root@am335x-evm:~# dmesg | grep tty
    [    0.000000] Kernel command line: console=ttyO0,115200n8 root=ubi0:rootfs rw ubi.mtd=NAND.file-system,2048 rootfstype=ubifs rootwait=1
    [    0.459543] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud = 3000000) is a OMAP UART0
    [    1.134043] console [ttyO0] enabled
    [    1.144560] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89, base_baud = 3000000) is a OMAP UART1
    [    1.160910] 481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61, base_baud = 3000000) is a OMAP UART4
    [    1.207870] (hci_tty): inside hci_tty_init
    [    1.212637] (hci_tty): allocated 249, 0
  • 这是串口设备信息:

    root@am335x-evm:/dev# ls -l ttyO*
    crw-------    1 root     tty       250,   0 Jan  1 00:15 ttyO0
    crw-rw----    1 root     dialout   250,   1 Jan  1  1970 ttyO1
    crw-rw----    1 root     dialout   250,   4 Jan  1 00:02 ttyO4
  • 已经调通了,驱动不动,修改应用程序就可以。只是需要关掉标准输入以及一些特殊的代码转换为指令的功能等就可以了。

  • 你好,“一些特殊的代码转换为指令的功能”,指的是什么呢,怎么关闭?

  • 建议收一下termios结构体,具体问题都不一样,需要根据自几接收到的数据具体分析。我的有以下的修改:给你做个参考。

    tio.c_iflag &= ~(ICRNL|IGNCR); //djf 20150410 add  to cutoff the special value of 03 

  • 非常感谢您的回复!其实我也不确定是不是应用程序出的问题,因为同一个测试程序,uart2和uart5可以正常收发,uart1,write成功返回,但是minicom上看不到所发的字符,read则一直阻塞,我照你说的改了一下termios结构体,情况还是一样,这是我的配置,我用的是AM335X GP EVM,SDK06.00,能帮我看看哪里不对么?

    board-am335xevm.c:

    static struct pinmux_config uart1_pin_mux[] = {  
        {"uart1_rxd.uart1_rxd",   OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
        {"uart1_txd.uart1_txd",   OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT},
        {NULL, 0},
    };

    static void uart1_init(int evm_id, int profile)
    {
        setup_pin_mux(uart1_pin_mux);
        return;
    }

    static struct evm_dev_cfg gen_purp_evm_dev_cfg[] = {

                     .......

        {uart1_init,    DEV_ON_BASEBOARD, PROFILE_ALL},

                     .......

    }

    mux33xx.c:

        _AM33XX_MUXENTRY(UART1_RXD, 0,
            "uart1_rxd", "mmc1_sdwp", NULL, "i2c1_sda",
            NULL, "pr1_uart0_rxd_mux1", NULL, "gpio0_14"),
        _AM33XX_MUXENTRY(UART1_TXD, 0,
            "uart1_txd", "mmc2_sdwp", NULL, "i2c1_scl",
            NULL, "pr1_uart0_txd_mux1", NULL, "gpio0_15"),

    同一个端口,用作uart4的时候,收发是正常的,我短接了rx和tx,uart1的自收自发也不行,整个board-am335xevm.c文件,只有此处用到uart1_rxd和uart1_txd,管脚没有复用,不知道配置对不对,我不是很懂,希望你能为我答疑解惑,感谢!

  • 我觉得可以先不用应用程序调试一下,用命令echo 和cat直接测试下。我当时是可发不可收,pc串口调试助手发给linux的东西自己直接返回,所以可以判断是回显的问题。你先测测吧。收发时也可以用示波器抓一下两个脚的的信号,看一下。

    另外不知道你说的同一个端口,用uart4的时候,是什么意思。

    既然2和5都通了,比对一下硬件连接还有软件初始化配置等,一个个排除吧。

  • 我看到这个 http://processors.wiki.ti.com/index.php/AM335x-PSP_04.06.00.03_Release_Notes#What.27s_Supported,GP EVM板中,uart1是用在蓝牙模块的,是不是uart1不能作为普通串口使用?uart1和uart4共用一个COM口,uart4收发是正常的,uart1的配置正确,但是却不能正常工作,是不是这个原因呢?