imx6sx uart

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

imx6sx uart

694 Views
2548903578
Contributor III

Hello,everyone

Recently, I am using the imx6sx serial port for debugging, using other serial ports, and writing an application program to read data, and use other upper computers to send. After the kernel is fully started, the application program is executed first and then the serial port host computer is used to send data, which can be obtained normally. But I first used the serial port host computer to send data and then started the board and opened the application program. I found that the data were all garbage values, and the number of bytes was also defined as the largest. After a while, the number of bytes became 0, and there was no data. It is normal after restarting the application several times.

 

 

QQ截图20210714111623.pngQQ截图20210714111641.pngQQ截图20210714111832.png

 

code:

#include <stdio.h>        //标准输入输出,如printf、scanf以及文件操作
#include <stdlib.h>        //标准库头文件,定义了五种类型、一些宏和通用工具函数
#include <unistd.h>        //定义 read write close lseek 等Unix标准函数
#include <sys/types.h>    //定义数据类型,如 ssiz e_t off_t 等
#include <sys/stat.h>    //文件状态
#include <fcntl.h>        //文件控制定义
#include <termios.h>    //终端I/O
#include <errno.h>        //与全局变量 errno 相关的定义
#include <getopt.h>        //处理命令行参数
#include <string.h>        //字符串操作
#include <time.h>        //时间
#include <sys/select.h>    //select函数
#include <signal.h>
int fd;

void close_fd(int sg_no)
{
    if(SIGINT == sg_no) {
        close(fd);   
        printf("close serialport file\r\n");
        exit(0);
    }
}
int setOpt(int fdint nSpeedint nBitsint nParityint nStop)
{
    struct termios newtiooldtio;

    // 保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息
    if (tcgetattr(fd, &oldtio) != 0)
    {
        perror("SetupSerial 1");
        return -1;
    }

    bzero(&newtiosizeof(newtio));        //新termios参数清零
    newtio.c_cflag |= CLOCAL | CREAD;    //CLOCAL--忽略 modem 控制线,本地连线, 不具数据机控制功能, CREAD--使能接收标志
    // 设置数据位数
    newtio.c_cflag &= ~CSIZE;    //清数据位标志
    switch (nBits)
    {
        case 7:
            newtio.c_cflag |= CS7;
        break;
        case 8:
            newtio.c_cflag |= CS8;
        break;
        default:
            fprintf(stderr"Unsupported data size\n");
            return -1;
    }
    // 设置校验位
    switch (nParity)
    {
        case 'o':
        case 'O':                     //奇校验
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            newtio.c_iflag |= (INPCK | ISTRIP);
            break;
        case 'e':
        case 'E':                     //偶校验
            newtio.c_iflag |= (INPCK | ISTRIP);
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            break;
        case 'n':
        case 'N':                    //无校验
            newtio.c_cflag &= ~PARENB;
            break;
        default:
            fprintf(stderr"Unsupported parity\n");
            return -1;
    }
    // 设置停止位
    switch (nStop)
    {
        case 1:
            newtio.c_cflag &= ~CSTOPB;
        break;
        case 2:
            newtio.c_cflag |= CSTOPB;
        break;
        default:
            fprintf(stderr,"Unsupported stop bits\n");
            return -1;
    }
    // 设置波特率 2400/4800/9600/19200/38400/57600/115200/230400
    switch (nSpeed)
    {
        case 2400:
            cfsetispeed(&newtioB2400);
            cfsetospeed(&newtioB2400);
            break;
        case 4800:
            cfsetispeed(&newtioB4800);
            cfsetospeed(&newtioB4800);
            break;
        case 9600:
            cfsetispeed(&newtioB9600);
            cfsetospeed(&newtioB9600);
            break;
        case 19200:
            cfsetispeed(&newtioB19200);
            cfsetospeed(&newtioB19200);
            break;
        case 38400:
            cfsetispeed(&newtioB38400);
            cfsetospeed(&newtioB38400);
            break;
        case 57600:
            cfsetispeed(&newtioB57600);
            cfsetospeed(&newtioB57600);
            break;
        case 115200:
            cfsetispeed(&newtioB115200);
            cfsetospeed(&newtioB115200);
            break;
        case 230400:
            cfsetispeed(&newtioB230400);
            cfsetospeed(&newtioB230400);
            break;
        default:
            printf("\tSorry, Unsupported baud rate, set default 9600!\n\n");
            cfsetispeed(&newtioB9600);
            cfsetospeed(&newtioB9600);
            break;
    }
    // 设置read读取最小字节数和超时时间
    newtio.c_cc[VTIME] = 1;     // 读取一个字符等待1*(1/10)s
    newtio.c_cc[VMIN] = 1;        // 读取字符的最少个数为1
    
      tcflush(fd,TCIFLUSH);         //清空缓冲区
      if (tcsetattr(fdTCSANOW, &newtio) != 0)    //激活新设置
      {
        perror("SetupSerial 3");
          return -1;
     }
      printf("Serial set done!\n");
    return 0;
}
int uart_init(int fd)
{
    struct termios newtiooldtio;
    //fcntl(fd, F_SETFL, 0);
   
    if(tcgetattr(fd, &oldtio) !=0 ){
        printf("tcgetattr error\r\n");
        return -1;
    }
    bzero(&newtiosizeof(newtio));
    newtio.c_cflag |=  CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;
    newtio.c_cflag |= CS8;
    newtio.c_cflag &= ~CSTOPB;
    newtio.c_cflag &= ~PARENB;
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;
    //     newtio.c_cflag &= ~HUPCL;
    //  newtio.c_iflag &= ~INPCK;
    //  newtio.c_iflag |= IGNBRK;
    //  newtio.c_iflag &= ~ICRNL;
    //  newtio.c_iflag &= ~IXON;
    //  newtio.c_lflag &= ~IEXTEN;
    //  newtio.c_lflag &= ~ECHOK;
    //  newtio.c_lflag &= ~ECHOCTL;
    //  newtio.c_lflag &= ~ECHOKE;
    //  newtio.c_oflag &= ~ONLCR;  
    
    cfsetispeed(&newtioB9600); 
    cfsetospeed(&newtioB9600);

    sleep(1);
    //tcflush(fd, TCIOFLUSH);
    tcflush(fd,TCIOFLUSH);
    if(tcsetattr(fdTCSANOW, &newtio) != 0){
        printf("com set error\r\n");
    }
    
    return 0;

}
int UART_Recv(int fdchar *rcv_bufint data_lenint timeout)
{
    int lenfs_sel;
    fd_set fs_read;
    struct timeval time;

    time.tv_sec = timeout / 1000;              //set the rcv wait time
    time.tv_usec = timeout % 1000 * 1000;    //100000us = 0.1s

    FD_ZERO(&fs_read);        //每次循环都要清空集合,否则不能检测描述符变化
    FD_SET(fd, &fs_read);    //添加描述符

    // 超时等待读变化,>0:就绪描述字的正数目, -1:出错, 0 :超时
    fs_sel = select(fd + 1, &fs_readNULLNULL, &time);
    printf("fs_sel = %d\n"fs_sel);
    if(fs_sel)
    {
        len = read(fdrcv_bufdata_len);
        return len;
    }
    else
    {
//        printf("Sorry,I am wrong!");
        return -1;
    }
}
int main(int argcchar *argv[])
{
    char read_buf[100];
    int read_size = 0;
    int ret,i;
    char tmp[50];

    signal(SIGINT,close_fd);
    fd = open("/dev/ttymxc3"O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd < 0) {
        printf("can't open serialport\r\n");
        return -1;
    } else{
        printf("open serialport success\r\n");
    }
    if (fcntl(fdF_SETFL0) < 0)    //阻塞,即使前面在open串口设备时设置的是非阻塞的
    {
        printf("fcntl failed!\n");
    }
       if (isatty(fd) == 0)
    {
        printf("standard input is not a terminal device\n");
        close(fd);
        return -1;
    }
    else
    {
        printf("is a tty success!\n");
    }
    printf("fd-open=%d\n"fd);
    

   // uart_init(fd);
       // 设置串口参数
    if (setOpt(fd96008'N'1)== -1)    //设置8位数据位、1位停止位、无校验
    {
        fprintf(stderr"Set opt Error\n");
        close(fd);
        exit(1);
    }
    tcflush(fdTCIOFLUSH);    //清掉串口缓存
    fcntl(fdF_SETFL0);    //串口阻塞
    while(1)
    {
        // scanf("%s",tmp);
        // ret = strcmp(tmp, "hello");
        // if(!ret) {
        //     write_size = write(fd, write_buf, sizeof(write_buf));
        //     if(write_size < 0) {
        //         printf("write error\r\n");
        //         return -1;
        //     }
        memset(read_buf0sizeof(read_buf));
        ret = UART_Recv(fdread_buf100,10000);
        printf("read len:%d\r\n",ret);
        for(i = 0ireti++){
            printf("%c",read_buf[i]);
        }
        printf("\r\n");
        usleep(300000);
    }
    close(fd);

    return 0;
}
0 Kudos
2 Replies

673 Views
igorpadykov
NXP Employee
NXP Employee

Hi

 

for using uart one can look at below examples:

https://source.codeaurora.org/external/imx/imx-test/tree/test/mxc_uart_test?h=lf-5.10.y_2.0.0

 

Best regards
igor

0 Kudos

646 Views
2548903578
Contributor III

Hi,igo

     I have found the reason, because the sdma method used by the serial port, our board failed to load the sdma firmware when it was started. So I failed to run the software directly after entering the file system. However, after a minute or so, the firmware will be successfully loaded again, and there is no problem in running the software afterwards.

0 Kudos