command.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #define MAX_MSGS 16
  12. static rt_mq_t msg_cmd = RT_NULL;
  13. // Table
  14. #define TABLE_MAX_SIZE 32
  15. struct command
  16. {
  17. rt_int16_t robot_cmd;
  18. void (*handler)(command_info_t info);
  19. };
  20. static struct command command_table[TABLE_MAX_SIZE];
  21. static uint16_t command_table_size = 0;
  22. rt_err_t command_register(rt_int16_t cmd, void (*handler)(command_info_t info))
  23. {
  24. if (command_table_size > TABLE_MAX_SIZE - 1)
  25. {
  26. LOG_E("Command table voerflow");
  27. return RT_ERROR;
  28. }
  29. command_table[command_table_size].robot_cmd = cmd;
  30. command_table[command_table_size].handler = handler;
  31. command_table_size++;
  32. return RT_EOK;
  33. }
  34. rt_err_t command_unregister(rt_int16_t cmd)
  35. {
  36. for (int i = 0; i < command_table_size; i++)
  37. {
  38. if (command_table[i].robot_cmd == cmd)
  39. {
  40. for (int j = i; j < command_table_size - 1; j++)
  41. {
  42. rt_memcpy(&command_table[j], &command_table[j+1], sizeof(struct command));
  43. }
  44. command_table_size--;
  45. break;
  46. }
  47. }
  48. return RT_EOK;
  49. }
  50. rt_err_t command_send(command_info_t info)
  51. {
  52. return rt_mq_send(msg_cmd, info, sizeof(struct command_info));
  53. }
  54. static void command_thread_entry(void *param)
  55. {
  56. struct command_info info;
  57. while (1)
  58. {
  59. rt_mq_recv(msg_cmd, &info, sizeof(struct command_info), RT_WAITING_FOREVER);
  60. // look-up table and call callback
  61. for (int i = 0; i < command_table_size; i++)
  62. {
  63. if (command_table[i].robot_cmd == info.cmd)
  64. {
  65. command_table[i].handler(&info);
  66. break;
  67. }
  68. }
  69. }
  70. }
  71. void command_init(void)
  72. {
  73. msg_cmd = rt_mq_create("command", sizeof(struct command_info), MAX_MSGS, RT_IPC_FLAG_FIFO);
  74. if (msg_cmd == RT_NULL)
  75. {
  76. LOG_E("Failed to creat meassage queue");
  77. return;
  78. }
  79. trd_cmd = rt_thread_create("command",
  80. command_thread_entry, RT_NULL,
  81. THREAD_STACK_SIZE,
  82. THREAD_PRIORITY, THREAD_TIMESLICE);
  83. if (trd_cmd == RT_NULL)
  84. {
  85. LOG_E("Failed to creat thread");
  86. return;
  87. }
  88. rt_thread_startup(trd_cmd);
  89. }