上传文件至 src
This commit is contained in:
		
							parent
							
								
									f48627f6fa
								
							
						
					
					
						commit
						e8732009f2
					
				
							
								
								
									
										313
									
								
								src/jlinux_uart.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								src/jlinux_uart.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,313 @@ | ||||
| /***********************************************************************
 | ||||
|  * @file jctrl_uart.cpp | ||||
|      JCTRL_UART | ||||
|  * @brief   header file | ||||
|  * @history | ||||
|  * Date       Version Author    description | ||||
|  * ========== ======= ========= ======================================= | ||||
|  * 2022-07-21 V1.0    Lucky,lukai@jovision.com   Create | ||||
|  * | ||||
|  * @Copyright (C)  2022  Jovision Technology Co., Ltd. | ||||
| ***********************************************************************/ | ||||
| #include <termios.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <linux/stat.h> | ||||
| #include <sys/prctl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/types.h> | ||||
| #include <fcntl.h> | ||||
| #include <linux/serial.h> | ||||
| #include "jlinux_uart.h" | ||||
| 
 | ||||
| struct _uart_ctx{ | ||||
|     int fd; | ||||
| }; | ||||
| 
 | ||||
| int _get_baudrate(int nBaud) | ||||
| { | ||||
|     switch(nBaud) | ||||
|     { | ||||
|     case 1200: | ||||
|         return B1200;	//注:B1200为系统定义
 | ||||
|     case 2400: | ||||
|         return B2400; | ||||
|     case 4800: | ||||
|         return B4800; | ||||
|     case 9600: | ||||
|         return B9600; | ||||
|  	case 19200 : | ||||
|         return B19200; | ||||
| 	case 38400: | ||||
| 	     return B38400; | ||||
| 	case 57600: | ||||
| 	     return B57600; | ||||
| 	case 115200: | ||||
| 	     return B115200; | ||||
|     default: | ||||
|         return B2400; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| juart_hdl_t juart_open(const char *name){ | ||||
|     juart_hdl_t uart = new _uart_ctx; | ||||
|     uart->fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY |  O_EXCL|O_SYNC); | ||||
|     return uart; | ||||
| } | ||||
| int juart_close(juart_hdl_t uart){ | ||||
|     if(uart->fd>0) | ||||
| 		close(uart->fd); | ||||
| 	uart->fd = 0; | ||||
|     return 0; | ||||
| } | ||||
| int juart_get_fd(juart_hdl_t uart){ | ||||
|     return uart->fd; | ||||
| } | ||||
| int juart_set_attr(juart_hdl_t uart, JUartAttr_t *attr){ | ||||
|     if (uart->fd <= 0) | ||||
|     { | ||||
|         printf("jv_uart_recv_ex fd error\n"); | ||||
|         return -1; | ||||
|     } | ||||
|     struct termios newtio, oldtio; | ||||
|     memset(&oldtio, 0, sizeof(oldtio)); | ||||
|     /* save the old serial port configuration */ | ||||
|     if (tcgetattr(uart->fd, &oldtio) != 0) { | ||||
|         perror("set_port/tcgetattr"); | ||||
|         return -1; | ||||
|     } | ||||
|     memset(&newtio, 0, sizeof(newtio)); | ||||
|     //设置波特率
 | ||||
|     int nBaud = _get_baudrate(attr->baudrate); | ||||
|     switch (nBaud) | ||||
|     { | ||||
|     case B300: | ||||
|     case B1200: | ||||
|     case B2400: | ||||
|     case B4800: | ||||
|     case B9600: | ||||
|     case B19200: | ||||
|     case B38400: | ||||
|     case B57600: | ||||
|     case B115200: | ||||
|         cfsetospeed(&newtio, nBaud); | ||||
|         cfsetispeed(&newtio, nBaud); | ||||
|         break; | ||||
|     default: | ||||
|         printf("jv_uart_set_attr:Unsupported baudrate!\n"); | ||||
|         return -1; | ||||
|     } | ||||
|     /* ignore modem control lines and enable receiver */ | ||||
|     newtio.c_cflag |= CLOCAL | CREAD; | ||||
|     newtio.c_cflag &= ~CSIZE; | ||||
|     /* set character size */ | ||||
|     switch (attr->datawidth) { | ||||
|     case 5: | ||||
|         newtio.c_cflag |= CS5; | ||||
|         break; | ||||
|     case 6: | ||||
|         newtio.c_cflag |= CS6; | ||||
|         break; | ||||
|     case 7: | ||||
|         newtio.c_cflag |= CS7; | ||||
|         break; | ||||
|     case 8: | ||||
|     default: | ||||
|         newtio.c_cflag |= CS8; | ||||
|         break; | ||||
|     } | ||||
|     /* set the stop bits */ | ||||
|     switch (attr->stopbit) { | ||||
|     default: | ||||
|     case 1: | ||||
|         newtio.c_cflag &= ~CSTOPB; | ||||
|         break; | ||||
|     case 2: | ||||
|         newtio.c_cflag |= CSTOPB; | ||||
|         break; | ||||
|     } | ||||
|     /* set the parity */ | ||||
|     switch (attr->parity) { | ||||
|     case 'o': | ||||
|     case 'O': | ||||
|     case 1: | ||||
|         newtio.c_cflag |= PARENB; | ||||
|         newtio.c_cflag |= PARODD; | ||||
|         newtio.c_iflag |= INPCK; | ||||
|         break; | ||||
|     case 'e': | ||||
|     case 'E': | ||||
|     case 2: | ||||
|         newtio.c_cflag |= PARENB; | ||||
|         newtio.c_cflag &= ~PARODD; | ||||
|         newtio.c_iflag |= INPCK; | ||||
|         break; | ||||
|     case 'n': | ||||
|     case 'N': | ||||
|     case 0: | ||||
|     default: | ||||
|         newtio.c_cflag &= ~PARENB; | ||||
|         newtio.c_iflag &= ~INPCK; | ||||
|         break; | ||||
|     } | ||||
|     /* Raw input */ | ||||
|     newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); | ||||
|     /* Software flow control is disabled */ | ||||
|     newtio.c_iflag &= ~(IXON | IXOFF | IXANY); | ||||
|     /* Raw ouput */ | ||||
|     newtio.c_oflag &=~ OPOST; | ||||
|     /* set timeout in deciseconds for non-canonical read */ | ||||
|     newtio.c_cc[VTIME] = 0; | ||||
|     /* set minimum number of characters for non-canonical read */ | ||||
|     newtio.c_cc[VMIN] = 0; | ||||
|     /* flushes data received but not read */ | ||||
|     tcflush(uart->fd, TCIFLUSH); | ||||
|     /* set the parameters associated with the terminal from
 | ||||
|         the termios structure and the change occurs immediately */ | ||||
|     if ((tcsetattr(uart->fd, TCSANOW, &newtio)) != 0) { | ||||
|         perror("set_port/tcsetattr"); | ||||
|         return -1; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| int juart_send(juart_hdl_t uart, char *data, int len){ | ||||
|     if (uart->fd > 0) | ||||
|     { | ||||
|         int ret = write(uart->fd, data, len); | ||||
|         if (ret == len) | ||||
|             return 0; | ||||
|     } | ||||
|     return -1; | ||||
| } | ||||
| int _modbus_rtu_select(juart_hdl_t uart, struct timeval *tv) | ||||
| { | ||||
|     fd_set rfds; | ||||
|     FD_ZERO(&rfds); | ||||
|     FD_SET(uart->fd, &rfds); | ||||
|     int s_rc; | ||||
|     while ((s_rc = select(uart->fd+1, &rfds, NULL, NULL, tv)) == -1) { | ||||
|         if (errno == EINTR) { | ||||
|             fprintf(stderr, "A non blocked signal was caught\n"); | ||||
|             /* Necessary after an error */ | ||||
|             FD_ZERO(&rfds); | ||||
|             FD_SET(uart->fd, &rfds); | ||||
|         } else { | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
|     if (s_rc == 0) { | ||||
|         /* Timeout */ | ||||
|         errno = ETIMEDOUT; | ||||
|         return -1; | ||||
|     } | ||||
|     return s_rc; | ||||
| } | ||||
| int juart_recv(juart_hdl_t uart, char *data, int len, int timeout){ | ||||
|     if (uart->fd > 0) | ||||
|     { | ||||
|         struct timeval tv; | ||||
|         tv.tv_sec = 0; | ||||
|         tv.tv_usec = timeout*1000; | ||||
|         if(_modbus_rtu_select(uart, &tv) > 0){ | ||||
|             return read(uart->fd, data, len); | ||||
|         } | ||||
|         return -1; | ||||
|     }else{ | ||||
|         usleep(timeout*1000); | ||||
|     } | ||||
|     return -1; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief 接收串口数据扩展接口,从收到start开始接收,到收到stop返回 | ||||
|  *@param handle 句柄 | ||||
|  *@param data 接收数据缓存 | ||||
|  *@param len 缓存大小 | ||||
|  *@param start 数据头标志:前nstart个字节 | ||||
|  *@param nstart 数据头字节数 | ||||
|  *@param stop 数据截止标志:后nstop个字节 | ||||
|  *@param nstop 数据截止标志的字节数 | ||||
|  */ | ||||
| extern "C" int juart_recv_ex(juart_hdl_t handle, char *data, int len, char *start, int nstart, char *stop, int nstop, int timeout); | ||||
| int juart_recv_ex(juart_hdl_t uart, char *data, int len, char *start, int nstart, char *stop, int nstop, int timeout){ | ||||
|     if (uart->fd <= 0) | ||||
|     { | ||||
|         printf("jv_uart_recv_ex fd error\n"); | ||||
|         return -1; | ||||
|     } | ||||
|     int offset = 0; | ||||
|     int offset_end = 0; | ||||
|     int bytes_read = 0; | ||||
|     while (1) | ||||
|     { | ||||
|         bytes_read = read(uart->fd, &data[offset], 1); | ||||
|         if (bytes_read == 1 && offset < nstart && data[offset] == start[offset]) | ||||
|         { | ||||
|             offset++; | ||||
|         } | ||||
|         if (offset == nstart) | ||||
|             break; | ||||
|         if (bytes_read < 1) | ||||
|             usleep(0); | ||||
|     } | ||||
|     while (offset < len) | ||||
|     { | ||||
|         if (data[offset] == stop[offset_end]) | ||||
|         { | ||||
|             offset_end++; | ||||
|         } | ||||
|         if (offset_end == nstop) | ||||
|             break; | ||||
|         bytes_read = read(uart->fd, &data[offset], 1); | ||||
|         if (bytes_read == 1) | ||||
|         { | ||||
|             offset++; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             usleep(0); | ||||
|         } | ||||
|     } | ||||
|     return offset; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief 设置rs485模式 | ||||
|  *@param handle 句柄 | ||||
|  *@param mode 0:发送后立刻置为接收状态;非0:发送后保持发送状态 | ||||
|  *@return 0 成功 | ||||
|  */ | ||||
| int juart_set_rs485(juart_hdl_t handle, int mode) | ||||
| { | ||||
|     struct serial_rs485 rs485; | ||||
| 	if (ioctl(handle->fd, TIOCGRS485, &rs485) == -1) | ||||
| 	{ | ||||
| 		printf("TIOCGRS485 ioctl error.\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	rs485.flags |= SER_RS485_ENABLED; | ||||
| 	if (mode == 0) | ||||
| 	{ | ||||
| 		rs485.flags &= ~SER_RS485_RTS_ON_SEND; | ||||
| 		rs485.flags |= SER_RS485_RTS_AFTER_SEND; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		rs485.flags |= SER_RS485_RTS_ON_SEND; | ||||
| 		rs485.flags &= ~SER_RS485_RTS_AFTER_SEND; | ||||
| 	} | ||||
| 	rs485.delay_rts_before_send = 0; | ||||
| 	rs485.delay_rts_after_send = 0; | ||||
| 	if (ioctl(handle->fd, TIOCSRS485, &rs485) == -1) | ||||
| 	{ | ||||
| 	    printf("TIOCSRS485 ioctrl error.\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user