• [海思] HI3531D串口调试


    [海思] HI3531D串口调试

    背景

    • 根据需求,我需要测试和使用海思3531d的串口1和串口3,而板子默认是只有调试串口UART0,因此需要将其他的串口进行使能和配置

    步骤

    1. 修改设备树,使能其他串口

      # 修改板子相关的dts,这里为hisi3531d-demb.dts
      $ vim arch/arm/boot/dts/hisi3531d-demb.dts
      ...
      &uart0 { 
      	status = "okay";
      };
      
      &uart1 { 
      	status = "okay";
      };
      # 这里我不用打开串口2,需要打开过程类似
      &uart3 {
      	status = "okay";
      }; 
      ...
      
      #编译内核并烧写到板子上
      $ make ARCH=arm CROSS_COMPILE=arm-hisiv500-linux- uImage
      
      # 烧写内核后查看是否有其他节点 AMA0~2
      $ ls /dev/ttyAMA*
      /dev/ttyAMA0  /dev/ttyAMA1  /dev/ttyAMA2(这个是串口三的节点)
      
    2. 引脚复用

      # uart1
      $ himm 0x120f0208 0x2
      $ himm 0x120f020C 0x2
      
      # uart3
      $ himm 0x120f0218 0x1
      $ himm 0x120f021C 0x1
      
    3. 简单测试输入输出

      #/dev/ttyAMA0是调试串口,因此只要启动时有打印,就是可以用的
      #测试/dev/ttyAMA1
      #发送数据(PC串口助手接收)
      $ echo 111 > /dev/ttyAMA1
      #接收数据(PC串口助手发送)
      $ cat /dev/ttyAMA1
      
    4. 查看串口的硬件分配和发送接收状态

      $ cat /proc/tty/driver/ttyAMA
      

    问题与解决方案

    • 现象:在uart1和uart3发送数据给PC时,PC的串口调试助手可以收到消息,但在接收数据(cat /dev/ttyAMA1)时,PC串口助手发送的数据没有在终端上显示,而是原路返回到PC串口助手上显示,导致应用程序读不到

    • 原因:串口没有正确初始化,即结构体struct termios里的参数没有初始化好

    • 解决方案:写一个应用程序初始化并测试,下列参考代码在板子上可以正确运行

      参考链接:(1条消息) 海思HI35XX串口调试_Biao-CSDN博客

      #include<stdio.h>       
      #include<stdlib.h>     
      #include<unistd.h>    
      #include<sys/types.h>   
      #include<sys/stat.h>     
      #include<fcntl.h>     
      #include<termios.h>    
      #include<errno.h>      
      #include<string.h> 
      #include <signal.h>  
       
      //宏定义  
      #define HI_FALSE  -1  
      #define HI_TRUE     0   
       
      #ifdef debugprintf
      	#define debugpri(mesg, args...) fprintf(stderr, "[HI Serial print:%s:%d:] " mesg "
      ", __FILE__, __LINE__, ##args) 
      #else
      	#define debugpri(mesg, args...)
      #endif
       
      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!
      ");
      	fclose(stderr);
      	abort();
      }
       
      void Hi_sigterm(int dummy)
      {
      	if(HiSerfd > 0)
      		HI_Serial_Close(HiSerfd);
      	fprintf(stderr, "Hi Serial Caught SIGTERM, Abort!
      ");
      	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);
      }
       
      int HI_Serial_Usage(void)
      {
          printf("Usage:
      ");
          printf("	myhicom [-d] <HiSerialDevice> [-s] get netdeviece info [-rw] read or wite select
      ");
          printf("	myhicom [-h] for more usage
      ");
          printf("	myhicom [-v] the verson of the sofware
      ");
      	printf("	Example:
      	myhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld
      ");
      }
       
      /*
      *Function: HI_Serial_Open(int fd,char* ComDevice)  
      *Param: fd:file descirbe handle	 Serial Device: /dev/ttyAMA1 /dev/ttyAMA2
      *Output: Ok or Fail
      */
       
      int HI_Serial_Open(char* HiSerDevice)  
      {  
          int fd;
      		
      	fd = open(HiSerDevice, O_RDWR|O_NOCTTY|O_NDELAY);  
      	if (HI_FALSE == fd)  
      	{  
      		perror("HiSerial Can't Open Serial HiSerDevice");  
      		return(HI_FALSE);  
      	}  
      	//恢复串口为阻塞状态                                 
      	if(fcntl(fd, F_SETFL, 0) < 0)  
      	{  
      		debugpri("fcntl failed!
      ");  
      		return(HI_FALSE);  
      	}       
      	else  
      	{  
      		debugpri("fcntl=%d
      ",fcntl(fd, F_SETFL,0));  
      	}  
      	//测试是否为终端设备      
      	if(0 == isatty(STDIN_FILENO))  
      	{  
      		debugpri("standard input is not a terminal device
      ");  
      		return(HI_FALSE);  
      	}  
      	else  
      	{  
      		debugpri("isatty success!
      ");  
      	}                
      	printf("fd->open=%d
      ",fd);  
      	return fd;  
      }  
       
      /*
      *Function: HI_Serial_Close(int fd) 
      *Param: fd:file descirbe handle	 
      *Output: Null
      */
       
      void HI_Serial_Close(int fd)  
      {  
      	if(fd > 0)
      		close(fd); 
      	return;	
      }  
       
      /*
      *Function: HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity) 
      *Param1: fd: file descirbe handle	 
      *Param2: speed: select the Serial speed.115200,19200,9600...
      *Param3: flow_ctrl: if use flow control
      *Param4: databits: data bit select
      *Param5: stopbits: stopbits select	
      *Param5: parity: partiy select	
      *Output: Ok or Fail
      */
      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(HI_FALSE);   
      	}  
          
          //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;  
          options.c_cflag |= CREAD;  
          
          //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
      ");  
                       return (HI_FALSE);   
          }  
          //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
      ");      
                       return (HI_FALSE);   
          }   
          // set stopbit  
          switch (stopbits)  
          {    
      		case 1:     
                       options.c_cflag &= ~CSTOPB; break;   
      		case 2:     
                       options.c_cflag |= CSTOPB; break;  
      		default:     
                             fprintf(stderr,"Unsupported stop bits
      ");   
                             return (HI_FALSE);  
          }  
           
      	//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(fd,TCIFLUSH);  
           
          //set the attribute to HiSerial device 
          if (tcsetattr(fd,TCSANOW,&options) != 0)    
      	{  
      		perror("com set error!
      ");    
      		return (HI_FALSE);   
      	}  
          return (HI_TRUE);   
      }  
       
      /*
      *Function: HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)  
      *Param: ...
      *Output: HI_TRUE or HI_FALSE
      */
      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) == HI_FALSE)  
      	{                                                           
      		return HI_FALSE;  
      	}  
          else  
      	{  
      		return  HI_TRUE;  
      	}  
      }  
       
      /*
      *Function: HI_Serial_Send(int fd, char *send_buf,int data_len)
      *Param1: fd:file descirbe handle	
      *Param2: send_buf:Data to be send
      *Param2: data_len:Data len
      *Output: Data send len or HI_FALSE
      */
      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
      ",send_buf);
      		return len;  
      	}       
          else     
      	{                   
      		tcflush(fd,TCOFLUSH);  
      		return HI_FALSE;  
      	}  
           
      } 
       
      /*
      *Function:  HI_Serial_Recv(int fd, char *rcv_buf,int data_len) 
      *Param1: fd:file descirbe handle	
      *Param2: rcv_buf:receive Data 
      *Param2: data_len:receive Data  len
      *Output: Receive Data len or HI_FALSE
      */
      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;  
           
          //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
      ",rcv_buf,len,fs_sel);  
      		return len;  
      	}  
          else  
      	{  
      		debugpri("Hiserial haven't data receive!");  
      		return HI_FALSE;  
      	}       
      } 
       
      int main ( int argc, char *argv[] )
      {
      	int cmd;
      	int len;
          //extern char *optarg;
          //extern int optind, opterr, optopt;
      	char HiSerialDev[32]="/dev/ttyAMA1";
      	char sendbuf[1024]={0};
      	char recvbuf[1024]={0};
      	int SerialSpeed = 115200;
      	
      	Hi_init_signals();
      	if(argc == 1)
      	{
      		HI_Serial_Usage();		
      		exit(0);
      	}
      	else
      	{
      		while ((cmd = getopt(argc, argv, ":d:s:rw:hv")) != -1)
      		{
      			switch (cmd)
      			{
      				case 'h':
      					HI_Serial_Usage();
      					break;
      				case 'v':
      					printf("myHicom --Verson V1.0.0
      ");
      					break;
      				case 'd':
      					//printf("catch -d %s 
      ",optarg);
      					memset(HiSerialDev,0,sizeof(HiSerialDev));
      					sprintf(HiSerialDev,"%s",optarg);
      					printf("myHicom HiSerialDev %s
      ",optarg);
      					break;
      				case 's':
      					SerialSpeed = atoi(optarg);
      					printf("myHicom speed %d
      ",SerialSpeed);
      					break;
      				case 'r':					
      					 debugpri("myHicom read
      ");
      					 HiSerfd = HI_Serial_Open(HiSerialDev);
      					 HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
      					 while(1)
      					 {
      						len = HI_Serial_Recv(HiSerfd, recvbuf,sizeof(recvbuf));  
      						if(len > 0)  
      						{  
      							recvbuf[len] = '';  
      							printf("Hiserial receive data: %s
      ",recvbuf);  
      							memset(recvbuf,0,sizeof(recvbuf));
      							//break;  
      						}  
      						else  
      						{  
      							debugpri("Hiserial haven't data receive 
      ");  
      						}  						 
      					 };		
      					 break;
      				case 'w':
      					 debugpri("myHicom write %s
      ",optarg);
      					 HiSerfd = HI_Serial_Open(HiSerialDev);
      					 printf("fd = %d device = %s speed = %d
      ",HiSerfd,HiSerialDev,SerialSpeed);
      					 HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');					 
      					 sprintf(sendbuf,"%s
      ",optarg);					 
      					 HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1); 
      					 if(HiSerfd > 0)
      						 HI_Serial_Close(HiSerfd);					
      					 break;
      			    case ':':
                          printf ("option: -%c missing argument. -h for help.
      ",(char)optopt);
                          break;
      			    case '?':
                          printf("Unknown option: -%c
      ",(char)optopt);
                          break;
      				default:
      					exit(0);
      			}
      		}	
      	}	
      	return 0;
      }	
      
      # 测试发送和接收
      $ ./myhicom -d /dev/ttyAMA1 -s 115200 -r
      $ ./myhicom -d /dev/ttyAMA1 -s 115200 -w helloworld
      
  • 相关阅读:
    Spring + mybatis 主从数据库分离读写的几种方式(二)
    Spring + mybatis 主从数据库分离读写的几种方式(一)
    AS3隐藏特性——深拷贝数据对象
    如何高效地抽离出两个数组中的相同元素
    资料合集2
    Trace类
    网页游戏心跳机制
    stage3d 你不知道的巨坑
    打包一组xml数据ByteArray
    利用BlendMode做镂空擦除效果
  • 原文地址:https://www.cnblogs.com/chenj-nry/p/15189303.html
Copyright © 2020-2023  润新知