app_mesh_device.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include "drv_gpio.h"
  6. #include "mesh_command.h"
  7. #include "mesh_node.h"
  8. #define LOG_TAG "mesh_device"
  9. #define LOG_LVL LOG_LVL_DBG
  10. #include <ulog.h>
  11. #define RX_THREAD_STACK_SIZE 512
  12. #define TX_THREAD_STACK_SIZE 512
  13. #define THREAD_TIMESLICE 40
  14. #define UART_NAME "uart5"
  15. static struct rt_messagequeue mesh_mq;
  16. static rt_thread_t mesh_command_tx_thread = RT_NULL;
  17. static rt_thread_t mesh_command_rx_thread = RT_NULL;
  18. static rt_uint8_t thread_priority = 20;
  19. static rt_device_t serial;
  20. static struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  21. static struct rt_semaphore rx_sem;
  22. static rt_uint8_t msg_pool[2048];
  23. void mesh_send_command(command_opcode_t opc, uint16_t addr, uint8_t *data)
  24. {
  25. uint8_t command[11];
  26. if (opc != COMMAND_OPCODE_FIND && opc != COMMAND_OPCODE_GET && opc != COMMAND_OPCODE_SET)
  27. return;
  28. command[0] = opc;
  29. memcpy(&command[1], &addr, 2);
  30. if (data != NULL)
  31. memcpy(&command[3], data, COMMAND_DATA_LENGTH);
  32. rt_mq_send(&mesh_mq, command, sizeof(command));
  33. LOG_HEX("Uart send data", 11, command, sizeof(command));
  34. }
  35. static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
  36. {
  37. rt_sem_release(&rx_sem);
  38. return RT_EOK;
  39. }
  40. static void mesh_command_tx_thread_entry(void *params)
  41. {
  42. serial = rt_device_find(UART_NAME);
  43. if (serial != RT_NULL)
  44. {
  45. config.baud_rate = BAUD_RATE_115200;
  46. config.data_bits = DATA_BITS_8;
  47. config.stop_bits = STOP_BITS_1;
  48. config.bufsz = 128;
  49. config.parity = PARITY_NONE;
  50. rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
  51. rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
  52. rt_device_set_rx_indicate(serial, uart_input);
  53. while (1)
  54. {
  55. char command[11];
  56. if (rt_mq_recv(&mesh_mq, command, sizeof(command), RT_WAITING_FOREVER) == RT_EOK)
  57. {
  58. rt_size_t res = rt_device_write(serial, 0, command, sizeof(command));
  59. if (res < 0)
  60. {
  61. // TODO: print error
  62. }
  63. }
  64. }
  65. }
  66. }
  67. static void command_handler(uint8_t *command)
  68. {
  69. uint8_t opcode = command[0];
  70. switch (opcode)
  71. {
  72. case COMMAND_OPCODE_REGISTER:
  73. {
  74. mesh_node_t node;
  75. memcpy(&node.addr, &command[1], 2);
  76. node.type = command[3];
  77. (void)mesh_node_add(node); // 不关心结果
  78. break;
  79. }
  80. case COMMAND_OPCODE_DATA:
  81. case COMMAND_OPCODE_STATUS:
  82. {
  83. mesh_node_t node;
  84. memcpy(&node.addr, &command[1], 2);
  85. memcpy(&node.data, &command[3], COMMAND_DATA_LENGTH);
  86. int16_t index = mesh_node_find(node.addr);
  87. if (index != -1)
  88. {
  89. mesh_node_update_data(index, node.data);
  90. }
  91. }
  92. }
  93. }
  94. static void mesh_command_rx_thread_entry(void *parameter)
  95. {
  96. rt_uint32_t rx_length = 0;
  97. char rx_buffer[11];
  98. while (1)
  99. {
  100. uint8_t ch;
  101. while (rt_device_read(serial, -1, &ch, 1) != 1)
  102. {
  103. rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
  104. }
  105. rx_buffer[rx_length++] = ch;
  106. if (rx_length == sizeof(rx_buffer))
  107. {
  108. LOG_HEX("Uart receive data", 11, rx_buffer, sizeof(rx_buffer));
  109. rx_length = 0;
  110. command_handler(rx_buffer);
  111. }
  112. }
  113. }
  114. int create_mesh_command_thread(void)
  115. {
  116. rt_err_t result;
  117. rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
  118. result = rt_mq_init(&mesh_mq,
  119. "mesh_mq",
  120. &msg_pool[0],
  121. 11,
  122. sizeof(msg_pool),
  123. RT_IPC_FLAG_FIFO);
  124. if (result != RT_EOK)
  125. {
  126. rt_kprintf("init message queue failed.\n");
  127. return -1;
  128. }
  129. mesh_command_tx_thread = rt_thread_create("mesh_tx", mesh_command_tx_thread_entry,
  130. RT_NULL, TX_THREAD_STACK_SIZE, thread_priority, THREAD_TIMESLICE);
  131. if (mesh_command_tx_thread != RT_NULL)
  132. {
  133. rt_thread_startup(mesh_command_tx_thread);
  134. }
  135. mesh_command_rx_thread = rt_thread_create("mesh_rx", mesh_command_rx_thread_entry,
  136. RT_NULL, RX_THREAD_STACK_SIZE, thread_priority, THREAD_TIMESLICE);
  137. if (mesh_command_rx_thread != RT_NULL)
  138. {
  139. rt_thread_startup(mesh_command_rx_thread);
  140. }
  141. return 0;
  142. }
  143. INIT_APP_EXPORT(create_mesh_command_thread);