uart_framework.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /*
  2. * Change Logs:
  3. * Date Author Notes
  4. * 2024-05-24 Slyant the first version
  5. */
  6. #include <rtthread.h>
  7. #include <rtdevice.h>
  8. #include <uart_framework.h>
  9. enum work_model
  10. {
  11. WORK_NORMAL = 0, WORK_TAKE, WORK_RELEASE, WORK_TAKE_RELEASE
  12. };
  13. static rt_err_t rx_ind(rt_device_t dev, rt_size_t size)
  14. {
  15. uart_framework_t uf = dev->user_data;
  16. rt_sem_release(uf->rx_sem);
  17. return RT_EOK;
  18. }
  19. /**
  20. * @brief 创建 UART 框架
  21. *
  22. * 根据给定的 UART 框架配置,创建并初始化 UART 框架。
  23. *
  24. * @param cfg UART 框架配置指针
  25. *
  26. * @return UART 框架指针,如果创建失败则返回 RT_NULL
  27. */
  28. uart_framework_t uart_framework_create(struct uart_framework_cfg *cfg)
  29. {
  30. rt_err_t open_result;
  31. static int rx_sem_count = 0;
  32. static int rx_mut_count = 0;
  33. char ufsem_name[RT_NAME_MAX] = { 0 };
  34. char ufmut_name[RT_NAME_MAX] = { 0 };
  35. uart_framework_t uf = rt_calloc(1, sizeof(struct uart_framework));
  36. if (uf == RT_NULL)
  37. return RT_NULL;
  38. uf->uart_device = rt_device_find(cfg->uart_name);
  39. if (uf->uart_device == RT_NULL || uf->uart_device->type != RT_Device_Class_Char)
  40. {
  41. rt_free(uf);
  42. return RT_NULL;
  43. }
  44. rt_snprintf(ufsem_name, RT_NAME_MAX, "ufsem%d", rx_sem_count++);
  45. uf->rx_sem = rt_sem_create(ufsem_name, 0, RT_IPC_FLAG_FIFO);
  46. if (uf->rx_sem == RT_NULL)
  47. {
  48. rt_free(uf);
  49. return RT_NULL;
  50. }
  51. rt_snprintf(ufmut_name, RT_NAME_MAX, "ufmut%d", rx_mut_count++);
  52. uf->dev_lock = rt_mutex_create(ufmut_name, RT_IPC_FLAG_FIFO);
  53. if (uf->dev_lock == RT_NULL)
  54. {
  55. rt_sem_delete(uf->rx_sem);
  56. rt_free(uf);
  57. return RT_NULL;
  58. }
  59. uf->rx_buf = rt_calloc(1, cfg->max_frame_size);
  60. if (uf->rx_buf == RT_NULL)
  61. {
  62. rt_sem_delete(uf->rx_sem);
  63. rt_mutex_delete(uf->dev_lock);
  64. rt_free(uf);
  65. return RT_NULL;
  66. }
  67. rt_memcpy(&uf->cfg, cfg, sizeof(struct uart_framework_cfg));
  68. #ifdef RT_USING_SERIAL_V2
  69. open_result = rt_device_open(uf->uart_device, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
  70. #else
  71. #ifdef RT_SERIAL_USING_DMA
  72. /* using DMA mode first */
  73. open_result = rt_device_open(uf->uart_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
  74. /* using interrupt mode when DMA mode not supported */
  75. if (open_result == RT_EOK)
  76. {
  77. }
  78. else if (open_result == -RT_EIO)
  79. #endif
  80. {
  81. open_result = rt_device_open(uf->uart_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
  82. }
  83. #endif
  84. RT_ASSERT(open_result == RT_EOK);
  85. if (uf->cfg.rx_ind)
  86. {
  87. rt_device_set_rx_indicate(uf->uart_device, uf->cfg.rx_ind);
  88. }
  89. else
  90. {
  91. if (uf->uart_device->user_data == RT_NULL)
  92. {
  93. uf->uart_device->user_data = uf;
  94. rt_device_set_rx_indicate(uf->uart_device, rx_ind);
  95. }
  96. }
  97. uf->is_waiting_response = RT_FALSE;
  98. return uf;
  99. }
  100. /**
  101. * @brief 发送数据
  102. *
  103. * 根据给定的工作模式和 UART 框架,发送数据到 UART 设备,并进入等待响应状态。
  104. *
  105. * @param model 工作模式
  106. * @param uf UART 框架结构体指针
  107. * @param data 数据指针
  108. * @param size 数据大小
  109. *
  110. * @return 实际发送的字节数
  111. */
  112. static rt_size_t _send(enum work_model model, uart_framework_t uf, rt_uint8_t *data, rt_size_t size)
  113. {
  114. while (rt_tick_get() - uf->send_tick < rt_tick_from_millisecond(uf->cfg.send_interval_ms))
  115. {
  116. rt_thread_mdelay(10);
  117. }
  118. if (model == WORK_TAKE || model == WORK_TAKE_RELEASE)
  119. {
  120. rt_mutex_take(uf->dev_lock, RT_WAITING_FOREVER);
  121. rt_sem_control(uf->rx_sem, RT_IPC_CMD_RESET, 0);
  122. while (rt_device_read(uf->uart_device, 0, &uf->rx_ch, 1))
  123. ;
  124. }
  125. if (uf->cfg.rs485_txd)
  126. uf->cfg.rs485_txd();
  127. rt_size_t wsize = rt_device_write(uf->uart_device, 0, data, size);
  128. if (uf->cfg.rs485_rxd)
  129. uf->cfg.rs485_rxd();
  130. uf->send_tick = rt_tick_get(); // 重置定时器
  131. if (model == WORK_TAKE_RELEASE)
  132. {
  133. rt_mutex_release(uf->dev_lock);
  134. }
  135. uf->is_waiting_response = RT_TRUE;
  136. return wsize;
  137. }
  138. /**
  139. * @brief 接收串口数据
  140. *
  141. * 根据指定的工作模型,从串口框架中接收数据后,退出等待响应状态。
  142. *
  143. * @param model 工作模型
  144. * @param uf 串口框架对象
  145. * @param timeout_ms 超时时间(毫秒)
  146. * @param frame_handler 数据帧处理函数
  147. * @param out 存储处理结果的缓冲区
  148. * @param out_size 处理结果的实际长度
  149. * @param out_max_size 缓冲区最大容量
  150. *
  151. * @return 错误码,RT_EOK 表示成功,其他值表示错误
  152. */
  153. static rt_err_t _receive(enum work_model model, uart_framework_t uf, rt_uint32_t timeout_ms, rt_uint8_t *out,
  154. rt_size_t *out_size, rt_size_t out_max_size)
  155. {
  156. // rt_memset(uf->rx_buf, 0, uf->cfg.max_frame_size);
  157. uf->rx_size = 0;
  158. uf->last_tick = rt_tick_get();
  159. while (1)
  160. {
  161. if (rt_sem_take(uf->rx_sem, rt_tick_from_millisecond(timeout_ms)) == RT_EOK)
  162. {
  163. if (model == WORK_TAKE_RELEASE)
  164. {
  165. rt_mutex_take(uf->dev_lock, RT_WAITING_FOREVER);
  166. }
  167. while (1)
  168. {
  169. while (rt_device_read(uf->uart_device, 0, &uf->rx_ch, 1))
  170. {
  171. uf->last_tick = rt_tick_get(); // 重置定时器
  172. if (uf->rx_size < uf->cfg.max_frame_size)
  173. {
  174. uf->rx_buf[uf->rx_size++] = uf->rx_ch;
  175. }
  176. }
  177. if (rt_tick_get() - uf->last_tick > rt_tick_from_millisecond(uf->cfg.frame_interval_ms))
  178. {
  179. if (uf->rx_size > 0)
  180. {
  181. if (out)
  182. {
  183. rt_memcpy(out, uf->rx_buf, uf->rx_size > out_max_size ? out_max_size : uf->rx_size);
  184. }
  185. if (out_size)
  186. {
  187. *out_size = uf->rx_size;
  188. }
  189. if (model == WORK_RELEASE || model == WORK_TAKE_RELEASE)
  190. {
  191. rt_mutex_release(uf->dev_lock);
  192. }
  193. uf->is_waiting_response = RT_FALSE;
  194. return RT_EOK;
  195. }
  196. else
  197. {
  198. break;
  199. }
  200. }
  201. rt_thread_mdelay(10);
  202. }
  203. if (model == WORK_RELEASE || model == WORK_TAKE_RELEASE)
  204. {
  205. rt_mutex_release(uf->dev_lock);
  206. }
  207. }
  208. else
  209. {
  210. if (model == WORK_RELEASE)
  211. {
  212. rt_mutex_release(uf->dev_lock);
  213. }
  214. uf->is_waiting_response = RT_FALSE;
  215. return -RT_ETIMEOUT;
  216. }
  217. }
  218. }
  219. /**
  220. * @brief 发送数据到UART框架
  221. *
  222. * 通过UART框架发送指定大小的数据。
  223. *
  224. * @param uf UART框架对象指针
  225. * @param data 要发送的数据指针
  226. * @param size 数据大小
  227. *
  228. * @return 发送的字节数
  229. */
  230. rt_size_t uart_framework_send(uart_framework_t uf, rt_uint8_t *data, rt_size_t size)
  231. {
  232. return _send(WORK_NORMAL, uf, data, size);
  233. }
  234. /**
  235. * @brief UART框架发送数据(独占)
  236. *
  237. * 通过UART框架发送指定大小的数据。
  238. *
  239. * @param uf UART框架对象
  240. * @param data 要发送的数据指针
  241. * @param size 要发送的数据大小
  242. *
  243. * @return 实际发送的数据大小
  244. */
  245. rt_size_t uart_framework_send_take(uart_framework_t uf, rt_uint8_t *data, rt_size_t size)
  246. {
  247. return _send(WORK_TAKE, uf, data, size);
  248. }
  249. /**
  250. * @brief UART框架发送数据(独占发送后释放)
  251. *
  252. * 通过UART框架发送指定大小的数据。
  253. *
  254. * @param uf UART框架对象指针
  255. * @param data 要发送的数据指针
  256. * @param size 要发送的数据大小
  257. *
  258. * @return 实际发送的字节数
  259. */
  260. rt_size_t uart_framework_send_take_release(uart_framework_t uf, rt_uint8_t *data, rt_size_t size)
  261. {
  262. return _send(WORK_TAKE_RELEASE, uf, data, size);
  263. }
  264. /**
  265. * @brief 接收UART框架数据
  266. *
  267. * 在给定的超时时间内,从UART框架中接收数据,并调用帧处理器处理接收到的数据。
  268. *
  269. * @param uf UART框架对象
  270. * @param timeout_ms 超时时间(毫秒)
  271. * @param out 存储处理结果的缓冲区
  272. * @param out_size 处理结果的实际长度
  273. * @param out_max_size 缓冲区最大容量
  274. *
  275. * @return 返回错误码,表示操作是否成功
  276. */
  277. rt_err_t uart_framework_receive(uart_framework_t uf, rt_uint32_t timeout_ms, rt_uint8_t *out, rt_size_t *out_size,
  278. rt_size_t out_max_size)
  279. {
  280. return _receive(WORK_NORMAL, uf, timeout_ms, out, out_size, out_max_size);
  281. }
  282. /**
  283. * @brief UART 框架接收数据(接收后释放独占)
  284. *
  285. * 从 UART 框架收数据,通过回调函数处理接收到的数据帧。
  286. *
  287. * @param uf UART框架对象
  288. * @param timeout_ms 超时时间(毫秒)
  289. * @param out 存储处理结果的缓冲区
  290. * @param out_size 处理结果的实际长度
  291. * @param out_max_size 缓冲区最大容量
  292. *
  293. * @return 返回错误码,表示操作是否成功
  294. */
  295. rt_err_t uart_framework_receive_release(uart_framework_t uf, rt_uint32_t timeout_ms, rt_uint8_t *out,
  296. rt_size_t *out_size, rt_size_t out_max_size)
  297. {
  298. return _receive(WORK_RELEASE, uf, timeout_ms, out, out_size, out_max_size);
  299. }
  300. /**
  301. * @brief UART框架接收数据(独占接收后释放)
  302. *
  303. * 从UART框架中接收数据,并在处理完成后释放相关资源。
  304. *
  305. * @param uf UART框架对象
  306. * @param timeout_ms 超时时间(毫秒)
  307. * @param out 存储处理结果的缓冲区
  308. * @param out_size 处理结果的实际长度
  309. * @param out_max_size 缓冲区最大容量
  310. *
  311. * @return 返回错误码,表示操作是否成功
  312. */
  313. rt_err_t uart_framework_receive_take_release(uart_framework_t uf, rt_uint32_t timeout_ms, rt_uint8_t *out,
  314. rt_size_t *out_size, rt_size_t out_max_size)
  315. {
  316. return _receive(WORK_TAKE_RELEASE, uf, timeout_ms, out, out_size, out_max_size);
  317. }
  318. /**
  319. * @brief 在非等待响应状态,接收串口数据
  320. *
  321. * 在非等待响应状态,从串口框架中接收数据,并在用户回调函数中处理接收到的数据帧。
  322. *
  323. * @param uf 串口框架对象
  324. * @param frame_handler_callback 数据帧处理回调函数
  325. * @param out 存储处理结果的缓冲区
  326. * @param out_size 处理结果的实际长度
  327. * @param out_max_size 缓冲区最大容量
  328. *
  329. * @return 返回错误码,表示操作是否成功
  330. */
  331. rt_err_t uart_framework_receive_without_waiting_response(uart_framework_t uf,
  332. void (*frame_handler_callback)(rt_uint8_t *data, rt_size_t size), rt_uint8_t *out, rt_size_t *out_size,
  333. rt_size_t out_max_size)
  334. {
  335. if (uf->is_waiting_response == RT_FALSE)
  336. {
  337. if (rt_sem_trytake(uf->rx_sem) == RT_EOK)
  338. {
  339. rt_mutex_take(uf->dev_lock, RT_WAITING_FOREVER);
  340. uf->rx_size = 0;
  341. uf->last_tick = rt_tick_get();
  342. while (1)
  343. {
  344. while (rt_device_read(uf->uart_device, 0, &uf->rx_ch, 1))
  345. {
  346. uf->last_tick = rt_tick_get(); // 重置定时器
  347. if (uf->rx_size < uf->cfg.max_frame_size)
  348. {
  349. uf->rx_buf[uf->rx_size++] = uf->rx_ch;
  350. }
  351. }
  352. if (rt_tick_get() - uf->last_tick > rt_tick_from_millisecond(uf->cfg.frame_interval_ms))
  353. {
  354. if (uf->rx_size > 0)
  355. {
  356. if (out)
  357. {
  358. rt_memcpy(out, uf->rx_buf, uf->rx_size > out_max_size ? out_max_size : uf->rx_size);
  359. }
  360. if (out_size)
  361. {
  362. *out_size = uf->rx_size;
  363. }
  364. if (frame_handler_callback)
  365. {
  366. frame_handler_callback(uf->rx_buf, uf->rx_size);
  367. }
  368. rt_mutex_release(uf->dev_lock);
  369. return RT_EOK;
  370. }
  371. else
  372. {
  373. break;
  374. }
  375. }
  376. rt_thread_mdelay(10);
  377. }
  378. rt_mutex_release(uf->dev_lock);
  379. }
  380. }
  381. return -RT_ERROR;
  382. }