command.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <command.h>
  2. #define DBG_SECTION_NAME "command"
  3. #define DBG_LEVEL DBG_LOG
  4. #include <rtdbg.h>
  5. // Thread
  6. #define THREAD_PRIORITY ((RT_THREAD_PRIORITY_MAX / 3) + 1)
  7. #define THREAD_STACK_SIZE 512
  8. #define THREAD_TIMESLICE 10
  9. static rt_thread_t trd_cmd = RT_NULL;
  10. // Message Queue
  11. struct command_msg
  12. {
  13. struct command_info info;
  14. void *param;
  15. rt_uint16_t size;
  16. };
  17. #define MAX_MSGS 16
  18. static rt_mq_t msg_cmd = RT_NULL;
  19. // Table
  20. #define TABLE_MAX_SIZE 32
  21. struct command
  22. {
  23. rt_int16_t robot_cmd;
  24. void (*handler)(command_info_t info, void *param, rt_uint16_t size);
  25. };
  26. static struct command command_table[TABLE_MAX_SIZE];
  27. static uint16_t command_table_size = 0;
  28. rt_err_t command_register(rt_int16_t cmd, void (*handler)(command_info_t info, void *param, rt_uint16_t size))
  29. {
  30. if (command_table_size > TABLE_MAX_SIZE - 1)
  31. {
  32. LOG_E("Command table voerflow");
  33. return RT_ERROR;
  34. }
  35. command_table[command_table_size].robot_cmd = cmd;
  36. command_table[command_table_size].handler = handler;
  37. command_table_size++;
  38. return RT_EOK;
  39. }
  40. rt_err_t command_unregister(rt_int16_t cmd)
  41. {
  42. for (int i = 0; i < command_table_size; i++)
  43. {
  44. if (command_table[i].robot_cmd == cmd)
  45. {
  46. for (int j = i; j < command_table_size - 1; j++)
  47. {
  48. rt_memcpy(&command_table[j], &command_table[j+1], sizeof(struct command));
  49. }
  50. command_table_size--;
  51. break;
  52. }
  53. }
  54. return RT_EOK;
  55. }
  56. rt_err_t command_handle(rt_int16_t cmd, void *param, rt_uint16_t size, void *target)
  57. {
  58. struct command_msg msg = {
  59. .param = param,
  60. .size = size,
  61. .info = {
  62. .target = target,
  63. .cmd = cmd,
  64. }
  65. };
  66. return rt_mq_send(msg_cmd, &msg, sizeof(struct command_msg));
  67. }
  68. rt_err_t command_send(command_sender_t sender, rt_int16_t cmd, void *param, rt_uint16_t size)
  69. {
  70. if (sender->send != RT_NULL)
  71. {
  72. return sender->send(cmd, param, size);
  73. }
  74. return RT_EOK;
  75. }
  76. static void command_thread_entry(void *param)
  77. {
  78. struct command_msg msg;
  79. while (1)
  80. {
  81. rt_mq_recv(msg_cmd, &msg, sizeof(struct command_msg), RT_WAITING_FOREVER);
  82. // look-up table and call callback
  83. for (int i = 0; i < command_table_size; i++)
  84. {
  85. if (command_table[i].robot_cmd == msg.info.cmd)
  86. {
  87. command_table[i].handler(&msg.info, msg.param, msg.size);
  88. break;
  89. }
  90. }
  91. }
  92. }
  93. void command_init(void)
  94. {
  95. msg_cmd = rt_mq_create("command", sizeof(struct command_info), MAX_MSGS, RT_IPC_FLAG_FIFO);
  96. if (msg_cmd == RT_NULL)
  97. {
  98. LOG_E("Failed to creat meassage queue");
  99. return;
  100. }
  101. trd_cmd = rt_thread_create("command",
  102. command_thread_entry, RT_NULL,
  103. THREAD_STACK_SIZE,
  104. THREAD_PRIORITY, THREAD_TIMESLICE);
  105. if (trd_cmd == RT_NULL)
  106. {
  107. LOG_E("Failed to creat thread");
  108. return;
  109. }
  110. rt_thread_startup(trd_cmd);
  111. }