UartContext.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * UartContext.cpp
  3. *
  4. */
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <memory.h>
  9. #include <termio.h>
  10. #include <string>
  11. #include <sys/ioctl.h>
  12. #include "uart/UartContext.h"
  13. #include "utils/Log.h"
  14. #include "base/strings.hpp"
  15. #define UART_DATA_BUF_LEN 16384 // 16KB
  16. extern int parseProtocol(const BYTE *pData, UINT len);
  17. extern void buildProtocolData(std::string info);
  18. static const char* getBaudRate(UINT baudRate) {
  19. struct {
  20. UINT baud;
  21. const char *pBaudStr;
  22. } baudInfoTab[] = {
  23. { B1200, "B1200" },
  24. { B2400, "B2400" },
  25. { B4800, "B4800" },
  26. { B9600, "B9600" },
  27. { B19200, "B19200" },
  28. { B38400, "B38400" },
  29. { B57600, "B57600" },
  30. { B115200, "B115200" },
  31. { B230400, "B230400" },
  32. { B460800, "B460800" },
  33. { B921600, "B921600" }
  34. };
  35. int len = sizeof(baudInfoTab) / sizeof(baudInfoTab[0]);
  36. for (int i = 0; i < len; ++i) {
  37. if (baudInfoTab[i].baud == baudRate) {
  38. return baudInfoTab[i].pBaudStr;
  39. }
  40. }
  41. return NULL;
  42. }
  43. UartContext::UartContext(int uartNum) :
  44. mIsOpen(false),
  45. mUartID(0),
  46. mDataBufPtr(NULL),
  47. mDataBufLen(0),
  48. mUartNumber(uartNum){
  49. }
  50. UartContext::~UartContext() {
  51. delete[] mDataBufPtr;
  52. closeUart();
  53. }
  54. static bool mUart1IsOpen = false;
  55. static bool mUart3IsOpen = false;
  56. // 打开串口,pFileName为串口号,baudRate为波特率
  57. bool UartContext::openUart(const char *pFileName, UINT baudRate) {
  58. // LOGD("打开串口 串口号 = %s, 波特率 = %s\n", pFileName, getBaudRate(baudRate));
  59. mUartID = open(pFileName, O_RDWR|O_NOCTTY); // mUartID等于打开的串口
  60. if (mUartID <= 0) {
  61. mIsOpen = false;
  62. if(mUartNumber == 1) {
  63. mUart1IsOpen = false;
  64. }
  65. if(mUartNumber == 2) {
  66. mUart3IsOpen = false;
  67. }
  68. LOGD("uart%d open error", mUartNumber);
  69. } else {
  70. struct termios oldtio = { 0 };
  71. struct termios newtio = { 0 };
  72. tcgetattr(mUartID, &oldtio);
  73. newtio.c_cflag = baudRate|CS8|CLOCAL|CREAD;
  74. newtio.c_iflag = 0; // IGNPAR | ICRNL
  75. newtio.c_oflag = 0;
  76. newtio.c_lflag = 0; // ICANON
  77. newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
  78. newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
  79. tcflush(mUartID, TCIOFLUSH);
  80. tcsetattr(mUartID, TCSANOW, &newtio);
  81. // 设置为非阻塞 Set to non-blocking
  82. fcntl(mUartID, F_SETFL, O_NONBLOCK);
  83. mIsOpen = run("uart");
  84. if (!mIsOpen) {
  85. close(mUartID);
  86. mUartID = 0;
  87. }
  88. if(mUartNumber == 1) {
  89. mUart1IsOpen = true;
  90. }
  91. if(mUartNumber == 3) {
  92. mUart3IsOpen = true;
  93. }
  94. LOGD("openUart mIsOpen = %d\n", mIsOpen);
  95. }
  96. return mIsOpen;
  97. }
  98. void UartContext::closeUart() {
  99. LOGD("closeUart mIsOpen: %d...\n", mIsOpen);
  100. if (mIsOpen) {
  101. requestExit();
  102. close(mUartID);
  103. mUartID = 0;
  104. mIsOpen = false;
  105. }
  106. }
  107. // 发送串口消息
  108. bool UartContext::send(const BYTE *pData, UINT len) {
  109. // 这里是串口没有打开
  110. if (!mIsOpen) {
  111. LOGD("uart%d not opend", mUartNumber);
  112. return false;
  113. }
  114. int ret = write(mUartID, pData, len); // 这是发送串口消息
  115. if (ret != (int) len) { // 这里是发送失败
  116. LOGD("发送串口消息失败\n");
  117. return false;
  118. }
  119. std::string logInfo = " >>> ";
  120. for (int i = 0; i < len; ++i) {
  121. logInfo += base::format("%02x",pData[i]);
  122. }
  123. LOGD("%s",logInfo.c_str());
  124. // success
  125. LOGD("send Success\n");
  126. return true;
  127. }
  128. //UartContext* UartContext::getInstance() {
  129. // static UartContext sUC;
  130. // return &sUC;
  131. //}
  132. bool UartContext::readyToRun() {
  133. if (mDataBufPtr == NULL) {
  134. mDataBufPtr = new BYTE[UART_DATA_BUF_LEN];
  135. }
  136. if (mDataBufPtr == NULL) {
  137. closeUart();
  138. }
  139. return (mDataBufPtr != NULL);
  140. }
  141. bool UartContext::threadLoop() {
  142. if (mIsOpen) {
  143. #if 0
  144. // 可能上一次解析后有残留数据,需要拼接起来
  145. int readNum = read(mUartID, mDataBufPtr + mDataBufLen, UART_DATA_BUF_LEN - mDataBufLen);
  146. if (readNum > 0) {
  147. mDataBufLen += readNum;
  148. // 解析协议
  149. int len = parseProtocol(mDataBufPtr, mDataBufLen);
  150. if ((len > 0) && (len < mDataBufLen)) {
  151. // 将未解析的数据移到头部
  152. memcpy(mDataBufPtr, mDataBufPtr + len, mDataBufLen - len);
  153. }
  154. mDataBufLen -= len;
  155. } else {
  156. Thread::sleep(50);
  157. }
  158. #else
  159. unsigned char buffer[1024] = {0};
  160. int ret = read(mUartID, buffer, sizeof(buffer));
  161. if (ret > 0) {
  162. if (buffer[0]==CMD_HEAD && buffer[ret-2] == CMD_END1 && buffer[ret-1] == CMD_END2){
  163. std::string revStr = "";
  164. //std::string logInfo = " <<< ";
  165. //依次将读取到的数据输出到日志
  166. for (int i = 0; i < ret; ++i) {
  167. if (i==0 || i==ret-1 || i==ret-2){
  168. continue;
  169. }
  170. //LOGD(" <<< %02x", buffer[i]);
  171. revStr += buffer[i];
  172. //logInfo += base::format("%02x",buffer[i]);
  173. }
  174. //LOGD(" %s",logInfo.c_str());
  175. buildProtocolData(revStr);
  176. }
  177. } else {
  178. //没收到数据时,休眠50ms,防止过度消耗cpu
  179. usleep(1000 * 50);
  180. }
  181. #endif
  182. return true;
  183. }
  184. return false;
  185. }
  186. static UartContext* uart0 = NULL;
  187. static UartContext* uart1 = NULL;
  188. static UartContext* uart2 = NULL;
  189. static UartContext* uart3 = NULL;
  190. void UartContext::init() {
  191. // uart0 = new UartContext(UART_TTYS0);
  192. // uart0->openUart("/dev/ttyS0", B115200);
  193. // uart1 = new UartContext(UART_TTYS1);
  194. // uart1->openUart("/dev/ttyS1", B115200);
  195. // 20221108的板子打开了串口2
  196. uart2 = new UartContext(UART_TTYS2);
  197. uart2->openUart("/dev/ttyS2", B115200);
  198. uart3 = new UartContext(UART_TTYS3);
  199. uart3->openUart("/dev/ttyS3", B115200);
  200. LOGD("打开串口");
  201. }
  202. void UartContext::destroy() {
  203. if (uart0) {
  204. delete uart0;
  205. uart0 = NULL;
  206. }
  207. if (uart1) {
  208. delete uart1;
  209. uart1 = NULL;
  210. }
  211. if (uart2) {
  212. delete uart1;
  213. uart2 = NULL;
  214. }
  215. if (uart3) {
  216. delete uart1;
  217. uart3 = NULL;
  218. }
  219. }
  220. bool UartContext::sendTo(int uart, const BYTE* pData, UINT len) {
  221. switch (uart) {
  222. case UART_TTYS0:
  223. return uart0->send(pData, len);
  224. case UART_TTYS1:
  225. return uart1->send(pData, len);
  226. case UART_TTYS2:
  227. return uart2->send(pData, len);
  228. case UART_TTYS3:
  229. return uart3->send(pData, len);
  230. }
  231. LOGD("无效的串口号");
  232. return false;
  233. }
  234. bool UartContext::Uart1IsOpen() {return mUart1IsOpen;}
  235. bool UartContext::Uart3IsOpen() {return mUart3IsOpen;}