UartContext.cpp 6.7 KB

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