usart_sim.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #ifdef _WIN32
  4. #include <windows.h>
  5. #include <mmsystem.h>
  6. #include <conio.h>
  7. #endif
  8. #include <stdio.h>
  9. #include "serial.h"
  10. struct serial_int_rx serial_rx;
  11. extern struct rt_device serial_device;
  12. #ifdef _WIN32
  13. /*
  14. * Handler for OSKey Thread
  15. */
  16. static HANDLE OSKey_Thread;
  17. static DWORD OSKey_ThreadID;
  18. static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam);
  19. void rt_hw_usart_init(void)
  20. {
  21. /*
  22. * create serial thread that receive key input from keyboard
  23. */
  24. OSKey_Thread = CreateThread(NULL,
  25. 0,
  26. (LPTHREAD_START_ROUTINE)ThreadforKeyGet,
  27. 0,
  28. CREATE_SUSPENDED,
  29. &OSKey_ThreadID);
  30. if (OSKey_Thread == NULL)
  31. {
  32. //Display Error Message
  33. return;
  34. }
  35. SetThreadPriority(OSKey_Thread,
  36. THREAD_PRIORITY_NORMAL);
  37. SetThreadPriorityBoost(OSKey_Thread,
  38. TRUE);
  39. SetThreadAffinityMask(OSKey_Thread,
  40. 0x01);
  41. /*
  42. * Start OS get key Thread
  43. */
  44. ResumeThread(OSKey_Thread);
  45. }
  46. #else /* POSIX version */
  47. #include <pthread.h>
  48. #include <semaphore.h>
  49. #include <stdlib.h>
  50. #include <signal.h>
  51. #include <termios.h> /* for tcxxxattr, ECHO, etc */
  52. #include <unistd.h> /* for STDIN_FILENO */
  53. static void * ThreadforKeyGet(void * lpParam);
  54. static pthread_t OSKey_Thread;
  55. void rt_hw_usart_init(void)
  56. {
  57. int res;
  58. res = pthread_create(&OSKey_Thread, NULL, &ThreadforKeyGet, NULL);
  59. if (res)
  60. {
  61. printf("pthread create faild, <%d>\n", res);
  62. exit(EXIT_FAILURE);
  63. }
  64. }
  65. #endif
  66. /*
  67. * 方向键(←): 0xe04b
  68. * 方向键(↑): 0xe048
  69. * 方向键(→): 0xe04d
  70. * 方向键(↓): 0xe050
  71. */
  72. static int savekey(unsigned char key)
  73. {
  74. /* save on rx buffer */
  75. {
  76. rt_base_t level;
  77. /* disable interrupt */
  78. //暂时关闭中断,因为要操作uart数据结构
  79. level = rt_hw_interrupt_disable();
  80. /* save character */
  81. serial_rx.rx_buffer[serial_rx.save_index] = key;
  82. serial_rx.save_index ++;
  83. //下面的代码检查save_index是否已经到到缓冲区尾部,如果是则回转到头部,称为一个环形缓冲区
  84. if (serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE)
  85. serial_rx.save_index = 0;
  86. //这种情况表示反转后的save_index追上了read_index,则增大read_index,丢弃一个旧的数据
  87. /* if the next position is read index, discard this 'read char' */
  88. if (serial_rx.save_index == serial_rx.read_index)
  89. {
  90. serial_rx.read_index ++;
  91. if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
  92. serial_rx.read_index = 0;
  93. }
  94. /* enable interrupt */
  95. //uart数据结构已经操作完成,重新使能中断
  96. rt_hw_interrupt_enable(level);
  97. }
  98. /* invoke callback */
  99. if (serial_device.rx_indicate != RT_NULL)
  100. {
  101. rt_size_t rx_length;
  102. /* get rx length */
  103. rx_length = serial_rx.read_index > serial_rx.save_index ?
  104. SERIAL_RX_BUFFER_SIZE - serial_rx.read_index + serial_rx.save_index :
  105. serial_rx.save_index - serial_rx.read_index;
  106. serial_device.rx_indicate(&serial_device, rx_length);
  107. }
  108. return 0;
  109. }
  110. #ifdef _WIN32
  111. static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam)
  112. #else
  113. static struct termios oldt, newt;
  114. /*simulate windows' getch(), it works!!*/
  115. void set_stty(void)
  116. {
  117. /* get terminal input's attribute */
  118. tcgetattr(STDIN_FILENO, &oldt);
  119. newt = oldt;
  120. /* set termios' local mode */
  121. newt.c_lflag &= ~(ECHO|ICANON);
  122. tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  123. }
  124. void restore_stty(void)
  125. {
  126. /* recover terminal's attribute */
  127. tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  128. }
  129. #define getch getchar
  130. static void * ThreadforKeyGet(void * lpParam)
  131. #endif /* not _WIN32*/
  132. {
  133. unsigned char key;
  134. #ifndef _WIN32
  135. sigset_t sigmask, oldmask;
  136. /* set the getchar without buffer */
  137. sigfillset(&sigmask);
  138. pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
  139. set_stty();
  140. #endif
  141. (void)lpParam; //prevent compiler warnings
  142. for (;;)
  143. {
  144. key = getch();
  145. #ifdef _WIN32
  146. if (key == 0xE0)
  147. {
  148. key = getch();
  149. if (key == 0x48) //up key , 0x1b 0x5b 0x41
  150. {
  151. savekey(0x1b);
  152. savekey(0x5b);
  153. savekey(0x41);
  154. }
  155. else if (key == 0x50)//0x1b 0x5b 0x42
  156. {
  157. savekey(0x1b);
  158. savekey(0x5b);
  159. savekey(0x42);
  160. }
  161. continue;
  162. }
  163. #endif
  164. savekey(key);
  165. }
  166. } /*** ThreadforKeyGet ***/