lsiosr.cpp
Go to the documentation of this file.
1 /*******************************************************
2 @company: Copyright (C) 2018, Leishen Intelligent System
3 @product: serial
4 @filename: lsiosr.cpp
5 @brief:
6 @version: date: author: comments:
7 @v1.0 18-8-21 fu new
8 *******************************************************/
9 #include "ls01b_v2/lsiosr.h"
10 
11 namespace ls {
12 
13 LSIOSR * LSIOSR::instance(std::string name, int speed, int fd)
14 {
15  static LSIOSR obj(name, speed, fd);
16  return &obj;
17 }
18 
19 LSIOSR::LSIOSR(std::string port, int baud_rate, int fd):port_(port), baud_rate_(baud_rate), fd_(fd)
20 {
21  printf("port = %s, baud_rate = %d\n", port.c_str(), baud_rate);
22 }
23 
25 {
26  close();
27 }
28 /* 串口配置的函数 */
29 int LSIOSR::setOpt(int nBits, uint8_t nEvent, int nStop)
30 {
31  struct termios newtio, oldtio;
32  /*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/
33  if (tcgetattr(fd_, &oldtio) != 0)
34  {
35  perror("SetupSerial 1");
36  return -1;
37  }
38  bzero(&newtio, sizeof(newtio));
39  /*步骤一,设置字符大小*/
40  newtio.c_cflag |= CLOCAL; //如果设置,modem 的控制线将会被忽略。如果没有设置,则 open()函数会阻塞直到载波检测线宣告 modem 处于摘机状态为止。
41  newtio.c_cflag |= CREAD; //使端口能读取输入的数据
42  /*设置每个数据的位数*/
43  switch (nBits)
44  {
45  case 7:
46  newtio.c_cflag |= CS7;
47  break;
48  case 8:
49  newtio.c_cflag |= CS8;
50  break;
51  }
52  /*设置奇偶校验位*/
53  switch (nEvent)
54  {
55  case 'O': //奇数
56  newtio.c_iflag |= (INPCK | ISTRIP);
57  newtio.c_cflag |= PARENB; //使能校验,如果不设PARODD则是偶校验
58  newtio.c_cflag |= PARODD; //奇校验
59  break;
60  case 'E': //偶数
61  newtio.c_iflag |= (INPCK | ISTRIP);
62  newtio.c_cflag |= PARENB;
63  newtio.c_cflag &= ~PARODD;
64  break;
65  case 'N': //无奇偶校验位
66  newtio.c_cflag &= ~PARENB;
67  break;
68  }
69  /*设置波特率*/
70  switch (baud_rate_)
71  {
72  case 2400:
73  cfsetispeed(&newtio, B2400);
74  cfsetospeed(&newtio, B2400);
75  break;
76  case 4800:
77  cfsetispeed(&newtio, B4800);
78  cfsetospeed(&newtio, B4800);
79  break;
80  case 9600:
81  cfsetispeed(&newtio, B9600);
82  cfsetospeed(&newtio, B9600);
83  break;
84  case 115200:
85  cfsetispeed(&newtio, B115200);
86  cfsetospeed(&newtio, B115200);
87  break;
88  case 230400:
89  cfsetispeed(&newtio, B230400);
90  cfsetospeed(&newtio, B230400);
91  break;
92  case 460800:
93  cfsetispeed(&newtio, B460800);
94  cfsetospeed(&newtio, B460800);
95  break;
96  default:
97  cfsetispeed(&newtio, B9600);
98  cfsetospeed(&newtio, B9600);
99  break;
100  }
101 
102  /*
103  * 设置停止位
104  * 设置停止位的位数, 如果设置,则会在每帧后产生两个停止位, 如果没有设置,则产生一个
105  * 停止位。一般都是使用一位停止位。需要两位停止位的设备已过时了。
106  * */
107  if (nStop == 1)
108  newtio.c_cflag &= ~CSTOPB;
109  else if (nStop == 2)
110  newtio.c_cflag |= CSTOPB;
111  /*设置等待时间和最小接收字符*/
112  newtio.c_cc[VTIME] = 0;
113  newtio.c_cc[VMIN] = 0;
114  /*处理未接收字符*/
115  tcflush(fd_, TCIFLUSH);
116  /*激活新配置*/
117  if ((tcsetattr(fd_, TCSANOW, &newtio)) != 0)
118  {
119  perror("serial set error");
120  return -1;
121  }
122 
123  return 0;
124 }
125 
126 /* 从串口中读取数据 */
127 int LSIOSR::read(char *buffer, int length, int timeout)
128 {
129  memset(buffer, 0, length);
130 
131  int totalBytesRead = 0;
132  int rc;
133  char* pb = buffer;
134  if (timeout > 0)
135  {
136  rc = waitReadable(timeout);
137  if (rc <= 0)
138  {
139  return (rc == 0) ? 0 : -1;
140  }
141 
142  int retry = 3;
143  while (length > 0)
144  {
145  rc = ::read(fd_, pb, (size_t)length);
146  if (rc > 0)
147  {
148  length -= rc;
149  pb += rc;
150  totalBytesRead += rc;
151 
152  if (length == 0)
153  {
154  break;
155  }
156  }
157  else if (rc < 0)
158  {
159  printf("error \n");
160  retry--;
161  if (retry <= 0)
162  {
163  break;
164  }
165  }
166 
167  rc = waitReadable(20);
168  if (rc <= 0)
169  {
170  break;
171  }
172  }
173  }
174  else
175  {
176  rc = ::read(fd_, pb, (size_t)length);
177  if (rc > 0)
178  {
179  totalBytesRead += rc;
180  }
181  else if ((rc < 0) && (errno != EINTR) && (errno != EAGAIN))
182  {
183  printf("read error\n");
184  return -1;
185  }
186  }
187 
188  if(0)
189  {
190  printf("Serial Rx: ");
191  for(int i = 0; i < totalBytesRead; i++)
192  {
193  printf("%02X ", (buffer[i]) & 0xFF);
194  }
195  printf("\n\n");
196  }
197 
198  return totalBytesRead;
199 }
200 
201 int LSIOSR::waitReadable(int millis)
202 {
203  if (fd_ < 0)
204  {
205  return -1;
206  }
207  int serial = fd_;
208 
209  fd_set fdset;
210  struct timeval tv;
211  int rc = 0;
212 
213  while (millis > 0)
214  {
215  if (millis < 5000)
216  {
217  tv.tv_usec = millis % 1000 * 1000;
218  tv.tv_sec = millis / 1000;
219 
220  millis = 0;
221  }
222  else
223  {
224  tv.tv_usec = 0;
225  tv.tv_sec = 5;
226 
227  millis -= 5000;
228  }
229 
230  FD_ZERO(&fdset);
231  FD_SET(serial, &fdset);
232 
233  rc = select(serial + 1, &fdset, NULL, NULL, &tv);
234  if (rc > 0)
235  {
236  rc = (FD_ISSET(serial, &fdset)) ? 1 : -1;
237  break;
238  }
239  else if (rc < 0)
240  {
241  rc = -1;
242  break;
243  }
244  }
245 
246  return rc;
247 }
248 
249 
250 int LSIOSR::waitWritable(int millis)
251 {
252  if (fd_ < 0)
253  {
254  return -1;
255  }
256  int serial = fd_;
257 
258  fd_set fdset;
259  struct timeval tv;
260  int rc = 0;
261 
262  while (millis > 0)
263  {
264  if (millis < 5000)
265  {
266  tv.tv_usec = millis % 1000 * 1000;
267  tv.tv_sec = millis / 1000;
268 
269  millis = 0;
270  }
271  else
272  {
273  tv.tv_usec = 0;
274  tv.tv_sec = 5;
275 
276  millis -= 5000;
277  }
278 
279  FD_ZERO(&fdset);
280  FD_SET(serial, &fdset);
281 
282  rc = select(serial + 1, NULL, &fdset, NULL, &tv);
283  if (rc > 0)
284  {
285  rc = (FD_ISSET(serial, &fdset)) ? 1 : -1;
286  break;
287  }
288  else if (rc < 0)
289  {
290  rc = -1;
291  break;
292  }
293  }
294 
295  return rc;
296 }
297 
298 /* 向串口中发送数据 */
299 int LSIOSR::send(const char* buffer, int length, int timeout)
300 {
301  if (fd_ < 0)
302  {
303  return -1;
304  }
305 
306  if ((buffer == 0) || (length <= 0))
307  {
308  return -1;
309  }
310 
311  int totalBytesWrite = 0;
312  int rc;
313  char* pb = (char*)buffer;
314 
315 
316  if (timeout > 0)
317  {
318  rc = waitWritable(timeout);
319  if (rc <= 0)
320  {
321  return (rc == 0) ? 0 : -1;
322  }
323 
324  int retry = 3;
325  while (length > 0)
326  {
327  rc = write(fd_, pb, (size_t)length);
328  if (rc > 0)
329  {
330  length -= rc;
331  pb += rc;
332  totalBytesWrite += rc;
333 
334  if (length == 0)
335  {
336  break;
337  }
338  }
339  else
340  {
341  retry--;
342  if (retry <= 0)
343  {
344  break;
345  }
346  }
347 
348  rc = waitWritable(50);
349  if (rc <= 0)
350  {
351  break;
352  }
353  }
354  }
355  else
356  {
357  rc = write(fd_, pb, (size_t)length);
358  if (rc > 0)
359  {
360  totalBytesWrite += rc;
361  }
362  else if ((rc < 0) && (errno != EINTR) && (errno != EAGAIN))
363  {
364  return -1;
365  }
366  }
367 
368  if(0)
369  {
370  printf("Serial Tx: ");
371  for(int i = 0; i < totalBytesWrite; i++)
372  {
373  printf("%02X ", (buffer[i]) & 0xFF);
374  }
375  printf("\n\n");
376  }
377 
378  return totalBytesWrite;
379 }
380 
382 {
383  int error_code = 0;
384 
385  fd_ = open(port_.c_str(), O_RDWR|O_NOCTTY|O_NDELAY);
386  if (0 < fd_)
387  {
388  error_code = 0;
389  setOpt(DATA_BIT_8, PARITY_NONE, STOP_BIT_1);//设置串口参数
390  printf("open_port %s , fd %d OK !\n", port_.c_str(), fd_);
391  }
392  else
393  {
394  error_code = -1;
395  printf("open_port %s ERROR !\n", port_.c_str());
396  }
397  printf("LSIOSR::Init\n");
398 
399  return error_code;
400 }
401 
403 {
404  ::close(fd_);
405 }
406 
407 std::string LSIOSR::getPort()
408 {
409  return port_;
410 }
411 
412 int LSIOSR::setPort(std::string name)
413 {
414  port_ = name;
415  return 0;
416 }
417 
418 }
Definition: ls01b.h:17
std::string port_
Definition: lsiosr.h:78
int waitWritable(int millis)
Definition: lsiosr.cpp:250
int waitReadable(int millis)
Definition: lsiosr.cpp:201
int close()
Definition: lsiosr.cpp:402
int read(char *buffer, int length, int timeout=30)
Definition: lsiosr.cpp:127
static LSIOSR * instance(std::string name, int speed, int fd=0)
Definition: lsiosr.cpp:13
int setPort(std::string name)
Definition: lsiosr.cpp:412
#define STOP_BIT_1
Definition: lsiosr.h:38
#define PARITY_NONE
Definition: lsiosr.h:36
int fd_
Definition: lsiosr.h:82
int init()
Definition: lsiosr.cpp:381
#define DATA_BIT_8
Definition: lsiosr.h:42
std::string getPort()
Definition: lsiosr.cpp:407
LSIOSR(std::string name, int speed, int fd)
Definition: lsiosr.cpp:19
int setOpt(int nBits, uint8_t nEvent, int nStop)
Definition: lsiosr.cpp:29
int baud_rate_
Definition: lsiosr.h:80
int send(const char *buffer, int length, int timeout=30)
Definition: lsiosr.cpp:299


ls01b_v2
Author(s): fu
autogenerated on Sat Sep 28 2019 03:51:19