上传文件至 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