linux驱动.之 tty uart应用层测试工具demon(一)

本文介绍了Linux驱动中的TTY UART应用层测试工具tty_uart_test的使用。通过编译该测试程序并运行`./tty_uart_test -D /dev/ttyTHS1 -w 0x55`,可以测试UART发送数据功能,配合示波器检查是否成功发送方波,从而验证UART通信的正确性。
摘要由CSDN通过智能技术生成

一、设置uart的例子,测试uart,发出方波,或去读数据

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <stdio.h>       
#include <stdlib.h>
#include <termios.h>
#include <string.h>

int main()
{  	
	char *filename1 = NULL;
    char buf1[100]={0x55,0x55,0x55,0x55};
	char buf2[100]={0x55,0x55,0x55,0x55};
	int ret = -1;
	int Oflags = 0;
	int fd1 = -1;
	int len = 0;

	filename1 = "/dev/ttyAMA2";
	struct termios options;

    fd1 = open(filename1, O_RDWR);
   	if (fd1 < 0) {
        	printf("app open %s fail\n", filename1);
        	return 0;
    } else {
		printf("app open  %s success\r\n",filename1);
    }
	//int flags = fcntl(fd1, F_GETFL, 0);
	//fcntl(fd1, F_SETFL, flags | O_NONBLOCK);


	if(tcgetattr(fd1,&options)  !=  0)  
	{  
		printf("get serial attibute fail");     
		return(-1);   
	}
	else{
		printf("get serial attibute success");
		printf("control model options.c_cflag : %d\n",options.c_cflag);
		printf("data bit options.c_cflag : %d\n",options.c_cflag);
		printf("parity bit options.c_cflag : %d\n",options.c_cflag);
		printf("raw data output options.c_oflag : %d\n",options.c_oflag);
	} 
	

	cfsetispeed(&options, B115200);   
	cfsetospeed(&options, B115200);   


  	//set control model 
    options.c_cflag |= CLOCAL;  
    options.c_cflag |= CREAD;

	options.c_cflag &= ~CRTSCTS;  

    //select data bit   
    options.c_cflag &= ~CSIZE; 
	
	options.c_cflag |= CS8;  
	
	//select parity bit   
    options.c_cflag &= ~PARENB;   
    options.c_iflag &= ~INPCK;
	
	// set stopbit  
	options.c_cflag &= ~CSTOPB;  

	//set raw data output 
	options.c_oflag &= ~OPOST;     
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  
	//options.c_lflag &= ~(ISIG | ICANON);  
     
	//set wait time  
	options.c_cc[VTIME] = 1;    
	options.c_cc[VMIN] = 1; 
     
	tcflush(fd1,TCIFLUSH);  
     
	//set the attribute to HiSerial device 
	if (tcsetattr(fd1,TCSANOW,&options) != 0)    
	{  
   		printf("set serial attibute fail");
		return (-1);   
	}
	else
	{  
   		printf("set serial attibute success");
		printf("control model options.c_cflag : %d\n",options.c_cflag);
		printf("data bit options.c_cflag : %d\n",options.c_cflag);
		printf("parity bit options.c_cflag : %d\n",options.c_cflag);
		printf("raw data output options.c_oflag : %d\n",options.c_oflag);
	}

	printf("\r\n");

	memset(buf1,0x0,sizeof(buf1));
	memset(buf2,0x0,sizeof(buf2));
	buf2[0]= 0x55;
	buf2[1]= 0x55;
	buf2[2]= 0x55;
	buf2[3]= 0x55;
	buf2[4]= 0x55;

	while(1)
	{
		#if 1
		len = 0;
		len = read(fd1, buf1,10);
		if(len < 0)
		{
			printf("app read serial fail\n");
		}
		else
		{	
			printf("app read serial success %d byte\r\n",len);

			printf("app read serial success: ASCLL ");
			for(int i = 0; i < len; i++)
			printf(" %c ",buf1[i]);
		}
		printf("\r\n");
		#endif

		//len = 0;
		len = write(fd1,buf1,len);
		if(len < 0)
		{
			printf("app write serial fail\r\n");
		}
		else
		{			
			printf("app write buf1 serial success %d byte\r\n",len);
		}
		
		memset(buf1,0,sizeof(buf1));

		sleep(1);
		//len = 0;
		len = write(fd1,buf2,len);
		if(len < 0)
		{
			printf("app write serial fail\n");
		}
		else
		{			
			printf("app write buf2 serial success %d byte\r\n",len);
		}
		
		printf("app is run ......\r\n");
	}

	close(fd1);
   	return 0;
}

二、第二种改进,方便
tty_uart_test.c 测试程序

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

#if 1
static const char *device = "/dev/ttyTHS1";  
#define DEFAULT_BR B115200
#else
static const char *device = "/dev/ttyTHS0";  
#define DEFAULT_BR B9600
#endif

int uart_open(void)
{
    int fd;

    fd = open(device, O_RDWR|O_NOCTTY);
    if(fd < 0){
        printf("error on open\n");
        return -1;
	}

    return fd;
}

int uart_cfg(int fd)
{
    int ret;
    struct termios tm;
    speed_t ispeed = DEFAULT_BR;
    speed_t ospeed = DEFAULT_BR;

    if(tcgetattr(fd, &tm) < 0) {
        printf("error on tcgetattr\n");
        return -1;
    }
    
    cfsetispeed(&tm, ispeed);
    cfsetospeed(&tm, ospeed);

    //8 bit
    tm.c_cflag &= ~CSIZE;   
    tm.c_cflag |= CS8;      //8bit stop

    //no ODD/EVEN
    tm.c_cflag &= ~PARENB;
    tm.c_iflag &= ~INPCK;

    //1 bit stop
    tm.c_cflag &= ~CSTOPB;

    //no flow control
    tm.c_cflag &= ~CRTSCTS;
    tm.c_iflag &= ~(IXON | IXOFF | IXANY);

    /* 忽略modem(调制解调器)控制线 */
    tm.c_cflag |= CLOCAL;
    //enable receive
    tm.c_cflag |= CREAD;   //


    /* 禁能执行定义(implementation-defined)输出处理,意思就是输出的某些特殊数
       据会作特殊处理,如果禁能的话那么就按原始数据输出 */
    tm.c_oflag &= ~OPOST;

    /**
      *  设置本地模式位原始模式
      *  ICANON:规范输入模式,如果设置了那么退格等特殊字符会产生实际动作
      *  ECHO:则将输入字符回送到终端设备
      *  ECHOE:如果ICANON也设置了,那么收到ERASE字符后会从显示字符中擦除一个字符
      *         通俗点理解就是收到退格键后显示内容会往回删一个字符
      *  ISIG:使终端产生的信号起作用。(比如按ctrl+c可以使程序退出)
      */
    tm.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    /**
      * 设置等待时间和最小接收字符
      * 这两个值只有在阻塞模式下有意义,也就是说open的时候不能传入O_NONBLOCK,
      * 如果经过了c_cc[VTIME]这么长时间,缓冲区内有数据,但是还没达到c_cc[VMIN]个
      * 数据,read也会返回。而如果当缓冲区内有了c_cc[VMIN]个数据时,无论等待时间
      * 是否到了c_cc[VTIME],read都会返回,但返回值可能比c_cc[VMIN]还大。如果将
      * c_cc[VMIN]的值设置为0,那么当经过c_cc[VTIME]时间后read也会返回,返回值
      * 为0。如果将c_cc[VTIME]和c_cc[VMIN]都设置为0,那么程序运行的效果与设置
      * O_NONBLOCK类似,不同的是如果设置了O_NONBLOCK,那么在没有数据时read返回-1,
      * 而如果没有设置O_NONBLOCK,那么在没有数据时read返回的是0。
      */
    tm.c_cc[VTIME] = 0;  //wait time
    tm.c_cc[VMIN] = 1;   //read 1 byte at least

    /* 清空读缓冲区 */
    tcflush(fd, TCIFLUSH);          
    
    if(tcsetattr(fd, TCSANOW, &tm) < 0) {
        printf("error on tcsetattr\n");
        return -1;
    }
    
    return 0;
}

static void print_usage(const char *prog)  
{  
    printf("Usage: %s [-hDrw]\n", prog);  
    printf("usage: uart_test\n"
            "       -h --help     print usage\n"
            "       -D --device   device to use (eg /dev/ttyTHS1)\n"
            "       -r --read     loop fore read\n"
            "       -w --write    str\n"
            );
    printf("\n");
    exit(1);  
}  

int fd = -1;
uint8_t buf[1024];

void *soc_update_nor_pthread(void *arg)
{
    uint8_t data = 0;
    printf("start uart rx thread\n");
	while (1)
	{
        read(fd, buf, 1);
        printf("%d\n", buf[0]);
    }

	printf("Thread_1 over\n");
	pthread_exit((void *)1);
}

int main(int argc, char **argv)
{
    int opt;
    
    uint8_t val;
    
    while (1) 
	{  
        static const struct option lopts[] = 
		{  
            { "help",    0, 0, 'h' },  
            { "device",  1, 0, 'D' },  
            { "read",    0, 0, 'r' },  
            { "write",   1, 0, 'w' },  
            { NULL, 0, 0, 0 },  
        };  
        int c;  
  
        c = getopt_long(argc, argv, "hD:rw:", lopts, NULL);  
        if (c == -1) 
            break;
    
        switch (c) {
            case 'h':  
                print_usage(argv[0]);  
                break;  
            case 'D':  
                device = optarg;  
                fd = uart_open();
                if(fd < 0) {
                    printf("open %s error : %d\n", device, fd);
                    return -1;
                }
                
                if(uart_cfg(fd) < 0) {
                    printf("setting %s error : %d\n", device, fd);
                    return -1;
                }
                printf("open %s : %d\n", device, fd);
                break;  
            case 'r':
                if(fd < 0) {
                    printf("error: open device first\n");
                    print_usage(argv[0]);  
                    return -1;
                }
                while(1){
                    read(fd, buf, sizeof(1024));
                    printf("%s", buf);
                }
                break;  
            case 'w':
                if(fd < 0) {
                    printf("error: open device first\n");
                    print_usage(argv[0]);  
                    return -1;
                }
                memset(buf, 0, sizeof(buf));
                strncpy(buf, optarg, strlen(optarg));
                buf[strlen(optarg)] = '\n';
                write(fd, buf, strlen(buf));
                printf("\nwrite %d : %s\n", strlen(buf), buf);

                int rtv1;
                pthread_t tid1, tid2, tid3;
                pthread_attr_t attr;
                pthread_attr_init(&attr);

                // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  //设置线程的分离属性为分离状态
                rtv1 = pthread_create(&tid1, &attr, soc_update_nor_pthread, (void *)0);
                if (0 != rtv1)
                {
                    printf("create thread failed\n");
                    return -1;
                }
                while(1){
                    write(fd, buf, strlen(buf));
                    sleep(1);
                }
                pthread_join(tid1, NULL);
                break;  
            default:  
                print_usage(argv[0]);  
                break;  
        }  
    }  

    if(fd > 0)
        close(fd);
    else if(argc < 2)
        print_usage(argv[0]);
    
    return 0;
}

编译成二进制可执行文件后
在开发板终端 输入指令, ./tty_uart_test -D /dev/ttyTHS1 -w 0x55 ,输出方波,即可测试uart是否发送数据,用示波器看是否有收到方波

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值