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