• 海思3559万能平台搭建:串口编程


    前言

      平常的工作使用中,总是免不了要和串口打交道,协议的收发也经常通过串口来实现,海思3559下的串口和标准的linux下串口大同小异,可以参考之前zynq的串口编程,也可以直接阅读本文

    使能串口

      最直接的方式就是将设备树中对应uart的status修改为 status = “okay”。海思实际加载的串口驱动是PL011,menuconfig查看配置Device Drivers > Character devices > Serial drivers中的ARM AMBA PL011 serial port support 和 Support for console on AMBA serial port是否有选择上。重新编译内核烧入,在/dev 下可以查看是否有串口设备ttyAMA0~4。sdk2.0.3.1版本默认是有的

    查看串口配置

      可以使用linux的stty命令查看串口的配置参数。比如:stty -F /dev/ttyAMA0 -a

    在这里插入图片描述
      同样可以使用stty命令设置串口参数,比如:stty -F /dev/ttyAMA0 ispeed 115200 ospeed 115200 cs8

    查看串口数据收发

      一般调试串口,我们可以将TX与RT接在一起,自己发数据给自己接收,看数据是否正常。也可以使用cat 查看串口数据或是echo发送数据。
      发送数据:

    echo "test 1234567890" > /dev/ttyAMA0
    
    • 1

      接收数据:

    cat /dev/ttyAMA0
    
    • 1

    查看串口硬件分配:

      串口的硬件分配状态,比如IO和中断使用情况可以在/proc/tty/driver下的ttyAMA 种查看:
    在这里插入图片描述

    注意

      如果串口的配置和数据的收发命令都能够正常,但是串口的引脚没有电平变化,这个可能是串口的复用功能没有设置,需要设置一下GPIO复用为串口功能。复用功能可以在设备树dts中设置,也可以使用海思的himm命令直接设置:

    himm 0x120f0100 0x01 #UART2_RXD
    himm 0x120f0104 0x01 #UART2_TXD

       这些都是和标注的linux一致的,不一样的是海思的串口经常需要代码初始化后才能操作,或者使用海思自己的microcom
    在这里插入图片描述

    收发测试代码

    操作库函数头文件

    /************************************************************************************************
    *****Describe: This program is writen to operate HI35xx serial devices.                     *****
    *****Author: xin.han															        	*****
    *****Date: 2022-09-17																		*****
    *************************************************************************************************/
    #ifndef _UART_H_
    #define _UART_H_
    
    #include       
    #include     
    #include    
    #include   
    #include     
    #include     
    #include    
    #include      
    #include 
    #include   
    #include "platform.h"
    #include "parser.h"
    #include "queue.h"
    
    //宏定义 
    // #define HI_FALSE  -1  
    // #define HI_TRUE     0   
    #ifdef debugprintf
    	#define debugpri(mesg, args...) fprintf(stderr, "[HI Serial print:%s:%d:] " mesg "\n", __FILE__, __LINE__, ##args) 
    #else
    	#define debugpri(mesg, args...)
    
    /*
    *描述  : 打开串口
    *参数  : HiSerDevice串口设备名 串口设备举例: /dev/ttyAMA1 /dev/ttyAMA2
    *返回值: 成功返回fd,失败返回-1
    *注意  :无
    */
    int HI_Serial_Open(char* HiSerDevice);  
    /*
    *描述  : 关闭串口
    *参数  : fd文件描述符 
    *返回值: 成功返回fd,失败返回-1
    *注意  :无
    */
    void HI_Serial_Close(int fd); 
    /*
    *描述  : 串口参数设置
    *参数  : fd: 文件描述符	 
    *        speed: 波特率.115200,19200,9600...
    *        flow_ctrl: 流控
    *        databits: 数据位 取值为5,6,7,8
    *        stopbits: 停止位 取值为1,2
    *        parity: 奇偶校验位	 取值为N,W,O,S
    *返回值: 成功返回0,失败返回-1
    *注意  :无
    */ 
    int HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity) ;
    /*
    *描述  : 串口初始化,实际还是串口参数设置
    *参数  : fd: 文件描述符	 
    *        speed: 波特率.115200,19200,9600...
    *        flow_ctrl: 流控
    *        databits: 数据位 取值为5,6,7,8
    *        stopbits: 停止位 取值为1,2
    *        parity: 奇偶校验位	 取值为N,W,O,S
    *返回值: 成功返回0,失败返回-1
    *注意  :无
    */ 
    int HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity);
    /*
    *描述  : 串口发送
    *参数  : fd:文件描述符	
    *        send_buf:发送buf
    *        data_len:数据长度
    *返回值: 成功返回数据长度,失败返回-1
    *注意  :无
    */
    int HI_Serial_Send(int fd, char *send_buf,int data_len) ;
    /*
    *描述  : 串口接受
    *参数  : fd:文件描述符	
    *        send_buf:接收buf
    *        data_len:数据长度
    *返回值: 成功返回数据长度,失败返回-1
    *注意  :无
    */
    int HI_Serial_Recv(int fd, char *rcv_buf,int data_len) ;
    /*
    *描述  : 串口接受函数线程
    *参数  : 无
    *返回值: 无
    *注意  :无
    */
    HI_VOID *uart_recv_task(HI_VOID *arg);
    /*
    *描述  : 串口发送函数线程
    *参数  : 无
    *返回值: 无
    *注意  :无
    */
    HI_VOID *uart_send_task(HI_VOID *arg);
    
    
    #endif
    
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    操作库函数

    /************************************************************************************************
    *****Describe: This program is writen to operate HI35xx serial devices.                     *****
    *****Author: xin.han															        	*****
    *****Date: 2022-09-17																		*****
    *************************************************************************************************/
     
    #include "uart.h"
     
    int HiSerfd; 
    void HI_Serial_Close(int fd);
      
    void Hi_sigsegv(int dummy)
    {
    	if(HiSerfd > 0)
    		HI_Serial_Close(HiSerfd);
    	fprintf(stderr, "Hi Serial Caught SIGSEGV, Abort!\n");
    	fclose(stderr);
    	abort();
    }
     
    void Hi_sigterm(int dummy)
    {
    	if(HiSerfd > 0)
    		HI_Serial_Close(HiSerfd);
    	fprintf(stderr, "Hi Serial Caught SIGTERM, Abort!\n");
    	fclose(stderr);
    	exit(0);
    }
     
    void Hi_init_signals(void)
    {
    	struct sigaction sa;
    	sa.sa_flags = 0;
    	
    	sigemptyset(&sa.sa_mask);
    	sigaddset(&sa.sa_mask, SIGSEGV);
    	sigaddset(&sa.sa_mask, SIGTERM);
    	sigaddset(&sa.sa_mask, SIGPIPE);
    	
    	sa.sa_handler = Hi_sigsegv;
    	sigaction(SIGSEGV, &sa, NULL);
     
    	sa.sa_handler = Hi_sigterm;
    	sigaction(SIGTERM, &sa, NULL);
     
    	sa.sa_handler = SIG_IGN;
    	sigaction(SIGPIPE, &sa, NULL);
    }
     
    void HI_Serial_Usage(void)
    {
        printf("Usage:\n");
        printf("\tmyhicom [-d]  [-s] get netdeviece info [-rw] read or wite select\n");
        printf("\tmyhicom [-h] for more usage\n");
        printf("\tmyhicom [-v] the verson of the sofware\n");
    	printf("\tExample:\n\tmyhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld\n");
    }
     
    int HI_Serial_Open(char* HiSerDevice)  
    {  
        int fd;
    		
    	 fd = open( HiSerDevice, O_RDWR|O_NOCTTY);//  O_RDWR : 可读可写 
    											  //  O_NOCTTY :该参数不会使打开的文件成为该进程的控制终端。如果没有指定这个标志,那么任何一个 输入都将会影响用户的进程。
     											  //  O_NDELAY :这个程序不关心DCD信号线所处的状态,端口的另一端是否激活或者停止。如果用户不指定了这个标志,则进程将会一直处在睡眠状态,直到DCD信号线被激活。
    
    	// fd = open(HiSerDevice, O_RDWR|O_NOCTTY|O_NDELAY);  
    	if (-1 == fd)  
    	{  
    		perror("HiSerial Can't Open Serial HiSerDevice");  
    		return(-1);  
    	}  
    	//恢复串口为阻塞状态                                 
    	if(fcntl(fd, F_SETFL, 0) < 0)  
    	{  
    		debugpri("fcntl failed!\n");  
    		return(-1);  
    	}       
    	else  
    	{  
    		debugpri("fcntl=%d\n",fcntl(fd, F_SETFL,0));  
    	}  
    	//测试是否为终端设备      
    	if(0 == isatty(STDIN_FILENO))  
    	{  
    		debugpri("standard input is not a terminal device\n");  
    		return(-1);  
    	}  
    	else  
    	{  
    		debugpri("isatty success!\n");  
    	}                
    	printf("fd->open=%d\n",fd);  
    	return fd;  
    }  
     
    void HI_Serial_Close(int fd)  
    {  
    	if(fd > 0)
    		close(fd); 
    	return;	
    }  
     
    int HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)  
    {  
         
    	int   i;  
    	// int   status;  
    	int   speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300};  
    	int   name_arr[] = {115200,  19200,  9600,  4800,  2400,  1200,  300};  
               
    	struct termios options;  
         
     
    	if( tcgetattr( fd,&options)  !=  0)  
    	{  
    		perror("SetupSerial 1");      
    		return(-1);   
    	}  
        
        //set buater rate 
    	for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)  
    	{  
    		if  (speed == name_arr[i])  
    		{               
    			cfsetispeed(&options, speed_arr[i]);   
    			cfsetospeed(&options, speed_arr[i]);    
    		}  
    	}       
         
        //set control model 
        options.c_cflag |= CLOCAL;  //清bit位 关闭流控字符 0x11 0x13
        options.c_cflag |= CREAD;  //清bit位 关闭流控字符 0x11 0x13
        options.c_iflag &= ~(INLCR|ICRNL);//清bit位 关闭字符映射 0x0a 0x0d
        options.c_iflag &= ~(IXON);//清bit位 关闭流控字符 0x11 0x13
        
        //set flow control
        switch(flow_ctrl)  
        {  
            
    		case 0 ://none  
                  options.c_cflag &= ~CRTSCTS;  
                  break;     
            
    		case 1 ://use hard ware 
                  options.c_cflag |= CRTSCTS;  
                  break;  
    		case 2 ://use sofware
                  options.c_cflag |= IXON | IXOFF | IXANY;  
                  break;  
        }  
      
        //select data bit   
        options.c_cflag &= ~CSIZE;  
        switch (databits)  
        {    
    		case 5    :  
                         options.c_cflag |= CS5;  
                         break;  
    		case 6    :  
                         options.c_cflag |= CS6;  
                         break;  
    		case 7    :      
                     options.c_cflag |= CS7;  
                     break;  
    		case 8:      
                     options.c_cflag |= CS8;  
                     break;    
    		default:     
                     fprintf(stderr,"Unsupported data size\n");  
                     return (-1);   
        }  
        //select parity bit 
        switch (parity)  
        {    
    		case 'n':  
    		case 'N'://无奇偶校验位  
                     options.c_cflag &= ~PARENB;   
                     options.c_iflag &= ~INPCK;      
                     break;   
    		case 'o':    
    		case 'O'://设置为奇校验    
                     options.c_cflag |= (PARODD | PARENB);   
                     options.c_iflag |= INPCK;               
                     break;   
    		case 'e':   
    		case 'E'://设置为偶校验  
                     options.c_cflag |= PARENB;         
                     options.c_cflag &= ~PARODD;         
                     options.c_iflag |= INPCK;        
                     break;  
    		case 's':  
    		case 'S'://设置为空格    
                     options.c_cflag &= ~PARENB;  
                     options.c_cflag &= ~CSTOPB;  
                     break;   
            default:    
                     fprintf(stderr,"Unsupported parity\n");      
                     return (-1);   
        }   
        // set stopbit  
        switch (stopbits)  
        {    
    		case 1:     
                     options.c_cflag &= ~CSTOPB; break;   
    		case 2:     
                     options.c_cflag |= CSTOPB; break;  
    		default:     
                           fprintf(stderr,"Unsupported stop bits\n");   
                           return (-1);  
        }  
         
    	//修改输出模式,原始数据输出    
    	options.c_oflag &= ~OPOST;  
        
    	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  
    	//options.c_lflag &= ~(ISIG | ICANON);  
         
        //set wait time   主要影响read函数
    	/* options.c_cc[VTIME] = X;   //设置从获取到1个字节后开始计时的超时时间
    
    		options.c_cc[VMIN] = Y;   //设置要求等待的最小字节数
    
    		在原始模式下对read()函数的影响:
    
    		1、X=0,Y!=0。函数read()只有在读取了Y个字节的数据或者收到一个信号的时候才返回;
    
    		2、X!=0,Y=0。即使没有数据可以读取,read()函数等待X时间量后返回;
    
    		3、X!=0,Y!=0。第一个字节数据到时开始,最先满足收到Y个字节或达超时时间X任意一个条件,read()返回;
    
    		4、X=0,Y=0。即使读取不到任何数据,函数read也会立即返回。 */
        options.c_cc[VTIME] = 1;    /* 读取一个字符等待1*(1/10)s */      
        options.c_cc[VMIN] = 32;    /* 读取字符的最少个数为xx,单位是字节 */  
         
      
        tcflush(fd,TCIFLUSH);  
         
        // //激活配置 (将修改后的termios数据设置到串口中)  
        if (tcsetattr(fd,TCSANOW,&options) != 0)    
    	{  
    		perror("com set error!\n");    
    		return -1;   
    	}  
        return 0;   
    }  
     
    
    int HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)  
    {  
        // int err;  
        //设置串口数据帧格式  
        if (HI_Serial_Set(fd,speed,flow_ctrl,databits,stopbits,parity) == -1)  
    	{                                                           
    		return -1;  
    	}  
        else  
    	{  
    		return  0;  
    	}  
    }  
     
    int HI_Serial_Send(int fd, char *send_buf,int data_len)  
    {  
        int len = 0;  
         
        len = write(fd,send_buf,data_len);  
        if (len == data_len )  
    	{  
    		debugpri("send data is %s\n",send_buf);
    		return len;  
    	}       
        else     
    	{                   
    		tcflush(fd,TCOFLUSH);  
    		return -1;  
    	}  
         
    } 
     
    int HI_Serial_Recv(int fd, char *rcv_buf,int data_len)  
    {  
    	int len,fs_sel;  
        fd_set fs_read;  
         
        struct timeval time;  
         
        FD_ZERO(&fs_read);  
        FD_SET(fd,&fs_read);  
         
        time.tv_sec = 30;  
        time.tv_usec = 0;  
        // len = read(fd,rcv_buf,data_len);  
        // select fdset
        fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);  
        if(fs_sel)  
    	{  
    		len = read(fd,rcv_buf,data_len);  
    		debugpri("HiSeral Receive Data = %s len = %d fs_sel = %d\n",rcv_buf,len,fs_sel);  
    		return len;  
    	}  
        else  
    	{  
    		debugpri("Hiserial haven't data receive!");  
    		return -1;  
    	}       
    } 
    HI_VOID *uart_recv_task(HI_VOID *arg)
    {
    	int len;
    	char HiSerialDev[32]="/dev/ttyAMA1";
    	// char sendbuf[1024]={0};
    	char recvbuf[1024]={0};
    	int SerialSpeed = 115200;
        int HiSerfd;
        int i;
    	
    	// Hi_init_signals();
    	// HI_Serial_Usage();		
    	
        HiSerfd = HI_Serial_Open(HiSerialDev);
        HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
        while(1)
        {
        len = HI_Serial_Recv(HiSerfd, recvbuf,sizeof(recvbuf)); 
        // printf("serial_recv length is %d\n",len); 
        if(len > 0)  
        {  
            printf(" ttyAMA1:recv origin data \n");
            // recvbuf[len] = '\0';  
            for (i = 0;i < len ;i++)
            {
                printf("%02x  ",recvbuf[i]);  
            }
            printf("\n");  
            // memset(recvbuf,0,sizeof(recvbuf));
            //break;  
        }  
        else  
        {  
        //     printf("Hiserial haven't data receive \n");  
        }  
        // sleep(2); 						 
        }
    				
        // debugpri("myHicom write %s\n",optarg);
        // HiSerfd = HI_Serial_Open(HiSerialDev);
        // printf("fd = %d device = %s speed = %d\n",HiSerfd,HiSerialDev,SerialSpeed);
        // HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');					 
        // sprintf(sendbuf,"%s\n",optarg);					 
        // HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1); 
        // if(HiSerfd > 0)
        //     HI_Serial_Close(HiSerfd);					
        // break;
    	
    	return 0;
    }
    
    HI_VOID *uart_send_task(HI_VOID *arg)
    {
    	char HiSerialDev[32]="/dev/ttyAMA1";
    	char sendbuf[1024]="HelloWorld1234567890";
    	// char recvbuf[1024]={0};
    	// char sendbuf[] = {0};
    	int SerialSpeed = 115200;
        int HiSerfd;
    	
    	// Hi_init_signals();
    	// HI_Serial_Usage();		
    	
        HiSerfd = HI_Serial_Open(HiSerialDev);
        HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
        while(1)
        {
      		HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1); 
            sleep(1);			 
        }
    				
        // debugpri("myHicom write %s\n",optarg);
        // HiSerfd = HI_Serial_Open(HiSerialDev);
        // printf("fd = %d device = %s speed = %d\n",HiSerfd,HiSerialDev,SerialSpeed);
        // HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');					 
        // sprintf(sendbuf,"%s\n",optarg);					 
        // HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1); 
        // if(HiSerfd > 0)
        //     HI_Serial_Close(HiSerfd);					
        // break;
    	
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392

    还是新建两个线程,一个收一个发

    HI_VOID *uart_recv_task(HI_VOID *arg)
    {
    	int len;
    	char HiSerialDev[32]="/dev/ttyAMA1";
    	// char sendbuf[1024]={0};
    	char recvbuf[1024]={0};
    	int SerialSpeed = 115200;
        int HiSerfd;
        int i;
    	
        HiSerfd = HI_Serial_Open(HiSerialDev);
        HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
        while(1)
        {
    		len = HI_Serial_Recv(HiSerfd, recvbuf,sizeof(recvbuf)); 
    		// printf("serial_recv length is %d\n",len); 
    		if(len > 0)  
    		{  
    			printf(" ttyAMA1:recv origin data \n");
    			// recvbuf[len] = '\0';  
    			for (i = 0;i < len ;i++)
    			{
    				printf("%02x  ",recvbuf[i]);  
    			}
    			printf("\n");  
    			// memset(recvbuf,0,sizeof(recvbuf));
    			//break;  
    		}  
    		else  
    		{  
    		//     printf("Hiserial haven't data receive \n");  
    		}  
     			 
        }
    	
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    HI_VOID *uart_send_task(HI_VOID *arg)
    {
    	char HiSerialDev[32]="/dev/ttyAMA1";
    	char sendbuf[1024]="HelloWorld1234567890";
    	// char recvbuf[1024]={0};
    	// char sendbuf[] = {0};
    	int SerialSpeed = 115200;
        int HiSerfd;
    
        HiSerfd = HI_Serial_Open(HiSerialDev);
        HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
        while(1)
        {
      		HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1); 
            sleep(1);			 
        }	
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

      还是比较简单的

      其实也不是海思的坑,做驱动的时候不影响,做应用的时候会稍微恶心一点
      每次接收的时候,如果内容短还好,一旦大于8个字,就会分成几次接收,倒也不会丢,现在自己要写应用了,为了方便肯定不能这么用了呀,一番检查发现是options.c_cc[VMIN] 的原因,默认是1,单位是字节,表示最少收到的字节数,select收到就会返回了
      options.c_cc[VTIME] = X;   //设置从获取到1个字节后开始计时的超时时间
      options.c_cc[VMIN] = Y;   //设置要求等待的最小字节数
      在原始模式下对read()函数的影响:
      1、X=0,Y!=0。函数read()只有在读取了Y个字节的数据或者收到一个信号的时候才返回;
      2、X!=0,Y=0。即使没有数据可以读取,read()函数等待X时间量后返回;
      3、X!=0,Y!=0。第一个字节数据到时开始,最先满足收到Y个字节或达超时时间X任意一个条件,read()返回;
      4、X=0,Y=0。即使读取不到任何数据,函数read也会立即返回。

  • 相关阅读:
    货币系统类的题(计数型DP)
    vue项目中 jsconfig.json是什么
    墨西哥专线清关有什么要求?
    初始Redis(入门篇)
    [JavaScript 刷题] 树 - 二叉搜索树迭代器, leetcode 173
    React关于渲染列表时的key属性
    常用集合之HashMap
    Python爬虫实战:从API获取数据
    IB数学与音乐的融合
    深度学习常见激活函数:ReLU,sigmoid,Tanh,softmax,Leaky ReLU,PReLU,ELU,Maxout整理集合,场景应用
  • 原文地址:https://blog.csdn.net/qq_42330920/article/details/127075475