ADD 增加modbus协议;
parent
4a304f38e4
commit
e23e448bd4
@ -0,0 +1,49 @@
|
||||
#ifndef __PD_MODBUS_H__
|
||||
#define __PD_MODBUS_H__
|
||||
|
||||
#ifdef CFG_DEV_TYPE_LAND_PD
|
||||
|
||||
#define WRITE 1
|
||||
#define READ 0
|
||||
|
||||
#define MODBUS_IR_CURRENT_ADDR 0x0 // 铁芯
|
||||
#define MODBUS_IR_CURRENT_LEN 2
|
||||
#define MODBUS_DC_CURRENT_ADDR 0x34 // 直流偏磁
|
||||
#define MODBUS_DC_CURRENT_LEN 2
|
||||
|
||||
#define MODBUS_UNIT_IR 0x01
|
||||
|
||||
#define MODBUS_CURRENT_LEN 4
|
||||
#define MODBUS_ADDR_ALARM 0x32
|
||||
#define MODBUS_ALARM_LEN 2
|
||||
|
||||
|
||||
// 定义Modbus TCP MBAP头
|
||||
//#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint16_t transaction_id; // 事务处理标识
|
||||
uint16_t protocol_id; // 协议标识
|
||||
uint16_t length; // 数据长度
|
||||
uint8_t unit_id; // 设备地址
|
||||
uint8_t function_code; // 功能码
|
||||
} modbus_tcp_t;
|
||||
//#pragma pack(pop)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t function;
|
||||
uint16_t address;
|
||||
uint16_t length;
|
||||
} pdu_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
uint8_t txbuf[512];
|
||||
uint8_t rxbuf[512];
|
||||
}modbus_t;
|
||||
|
||||
extern int32_t modbus_handle_init_after(void);
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,33 @@
|
||||
#ifndef __SERIAL_H__
|
||||
#define __SERIAL_H__
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Define --------------------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char tty[20]; //tty: 0, 1, 2, 3, 4, 5, 6, 7
|
||||
unsigned int baudrate; //baudrate
|
||||
unsigned char prompt; //prompt after reciving data
|
||||
unsigned char databit; //data bits, 5, 6, 7, 8
|
||||
unsigned char debug; //debug mode, 0: none, 1: debug
|
||||
unsigned char echo; //echo mode, 0: none, 1: echo
|
||||
unsigned char fctl; //flow control, 0: none, 1: hardware, 2: software
|
||||
unsigned char parity; //parity 0: none, 1: odd, 2: even
|
||||
unsigned char stopbit; //stop bits, 1, 2
|
||||
unsigned char reserved;
|
||||
} serial_attr_t;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/* Extern global variables ---------------------------------------------------*/
|
||||
|
||||
/* Extern functions ----------------------------------------------------------*/
|
||||
extern int serial_open(const char * devname, int baudrate);
|
||||
extern int serial_read(int fd, unsigned char * data, int len);
|
||||
extern int serial_write(int fd, unsigned char * data, int len);
|
||||
extern void serial_close(int fd);
|
||||
#endif
|
@ -0,0 +1,288 @@
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* 标准C库头文件. */
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* 用户代码头文件. */
|
||||
#include "serial.h"
|
||||
|
||||
int serial_band_convert(unsigned int baudrate)
|
||||
{
|
||||
switch (baudrate)
|
||||
{
|
||||
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;
|
||||
|
||||
case 921600:
|
||||
return B921600;
|
||||
|
||||
case 1152000:
|
||||
return B1152000;
|
||||
|
||||
default:
|
||||
return B115200;
|
||||
}
|
||||
}
|
||||
|
||||
int serial_attr_set(int fd, serial_attr_t * attr)
|
||||
{
|
||||
unsigned char databit = 0;
|
||||
unsigned char stopbit = 0;
|
||||
unsigned char parity = 0;
|
||||
unsigned char fctl = 0;
|
||||
int ret = -1;
|
||||
unsigned int baudrate = 0;
|
||||
|
||||
struct termios termios_old;
|
||||
struct termios termios_new;
|
||||
|
||||
memset(&termios_old, 0, sizeof(termios_old));
|
||||
memset(&termios_new, 0, sizeof(termios_new));
|
||||
|
||||
cfmakeraw(&termios_new);
|
||||
|
||||
if (tcgetattr(fd, &termios_old) != 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "Setup Serial!\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
//baudrates
|
||||
baudrate = serial_band_convert(attr->baudrate);
|
||||
cfsetispeed(&termios_new, baudrate);
|
||||
cfsetospeed(&termios_new, baudrate);
|
||||
termios_new.c_cflag |= CLOCAL;
|
||||
termios_new.c_cflag |= CREAD;
|
||||
|
||||
//flow control
|
||||
fctl = attr-> fctl;
|
||||
switch (fctl)
|
||||
{
|
||||
case 0:
|
||||
termios_new.c_cflag &= ~CRTSCTS; //no flow control
|
||||
break;
|
||||
case 1:
|
||||
termios_new.c_cflag |= CRTSCTS; //hardware flow control
|
||||
break;
|
||||
|
||||
case 2:
|
||||
termios_new.c_iflag |= IXON | IXOFF | IXANY; //software flow control
|
||||
break;
|
||||
}
|
||||
|
||||
//data bits
|
||||
termios_new.c_cflag &= ~CSIZE; //控制模式,屏蔽字符大小位
|
||||
databit = attr->databit;
|
||||
switch (databit)
|
||||
{
|
||||
case 5:
|
||||
termios_new.c_cflag |= CS5;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
termios_new.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
termios_new.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
termios_new.c_cflag |= CS8;
|
||||
break;
|
||||
|
||||
default:
|
||||
termios_new.c_cflag |= CS8;
|
||||
break;
|
||||
}
|
||||
|
||||
//parity check
|
||||
parity = attr->parity;
|
||||
switch (parity)
|
||||
{
|
||||
case 0: //no parity check
|
||||
termios_new.c_cflag &= ~PARENB;
|
||||
break;
|
||||
|
||||
case 1: //odd check
|
||||
termios_new.c_cflag |= PARENB;
|
||||
termios_new.c_cflag &= ~PARODD;
|
||||
break;
|
||||
|
||||
case 2: //even check
|
||||
termios_new.c_cflag |= PARENB;
|
||||
termios_new.c_cflag |= PARODD;
|
||||
break;
|
||||
}
|
||||
|
||||
//stop bits
|
||||
stopbit = attr->stopbit;
|
||||
if (stopbit == 2)
|
||||
{
|
||||
termios_new.c_cflag |= CSTOPB;
|
||||
}
|
||||
else if (stopbit == 1)
|
||||
{
|
||||
termios_new.c_cflag &= ~CSTOPB;
|
||||
}
|
||||
|
||||
//other attributions default
|
||||
termios_new.c_oflag &= ~OPOST;
|
||||
termios_new.c_cc[VMIN] = 1;
|
||||
termios_new.c_cc[VTIME] = 1;
|
||||
tcflush(fd, TCIFLUSH);
|
||||
ret = tcsetattr(fd, TCSANOW, &termios_new);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int serial_open(const char * devname, int baudrate)
|
||||
{
|
||||
int fd;
|
||||
serial_attr_t attr;
|
||||
fd = open(devname, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (fd < 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "Open SerialPort(%s) failed[error = %d, %s]!!!!!!!\r\n",
|
||||
devname, errno, strerror(errno));
|
||||
return E_SYS_CALL;
|
||||
}
|
||||
|
||||
strcpy(attr.tty, devname);
|
||||
attr.baudrate = baudrate;
|
||||
|
||||
serial_attr_set(fd, &attr);
|
||||
|
||||
DBG(DBG_M_SERIAL, "Open SerialPort(%s:%d) port success!!!\r\n", devname, baudrate);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int serial_read(int fd, unsigned char * data, int len)
|
||||
{
|
||||
int ret = -1;
|
||||
fd_set fs_read;
|
||||
int maxfd = -1;
|
||||
|
||||
if (fd < 0 || data == NULL || len <= 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "Param Error, fd = %d or NULL == data or len <= 0.\r\n", fd);
|
||||
return E_ERROR;
|
||||
}
|
||||
|
||||
FD_ZERO(&fs_read);
|
||||
FD_SET(fd, &fs_read);
|
||||
maxfd = fd + 1;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000 * 1000;
|
||||
|
||||
ret = select(maxfd, &fs_read, NULL, NULL, &tv);
|
||||
if (ret < 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "select error[%d, %s]!!!\r\n", errno, strerror(errno));
|
||||
return E_SYS_CALL;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "Timeout......\r\n");
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
ret = read(fd, data, len);
|
||||
if (ret < 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "read error[%d, %s]\r\n", errno, strerror(errno));
|
||||
return E_SYS_CALL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int serial_write(int fd, unsigned char * data, int len)
|
||||
{
|
||||
if (fd < 0 || NULL == data || len <= 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "Param Error, fd = %d or NULL == data or len = %d.\r\n", fd, len);
|
||||
return E_BAD_PARAM;
|
||||
}
|
||||
|
||||
fd_set fs_write;
|
||||
FD_ZERO(&fs_write);
|
||||
FD_SET(fd, &fs_write);
|
||||
|
||||
int maxfd = fd + 1;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000 * 1000;
|
||||
|
||||
int ret = select(maxfd, NULL, &fs_write, NULL, &tv);
|
||||
if (ret < 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "select Error[errno = %d, %s]\r\n", errno, strerror(errno));
|
||||
return E_SYS_CALL;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "Timeout!\r\n");
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &fs_write))
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
ret = write(fd, data + pos, len);
|
||||
if (ret < 0)
|
||||
{
|
||||
DBG(DBG_M_SERIAL, "write com[fd = %d] error[errno = %d, %s]\r\n", fd, errno, strerror(errno));
|
||||
return E_SYS_CALL;
|
||||
}
|
||||
len -= ret;
|
||||
pos += ret;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void serial_close(int fd)
|
||||
{
|
||||
if (fd > 0)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue