post_state.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. * Copyright (c) 2019, redoc
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-01-12 redoc the first version
  9. */
  10. #define LOG_TAG "state.post"
  11. #define LOG_LVL LOG_LVL_DBG
  12. #include "state.h"
  13. #include <ulog.h>
  14. /* post state graph
  15. *
  16. *
  17. * +-----------------------------------------------------------------+
  18. * | root--------+ |
  19. * | | |
  20. * | | |
  21. * | +----------+ fail +----------+ pass +----------+ |
  22. * | | postfail | <-------- | post | --------> | postpass | |
  23. * | +----------+ +----------+ +----------+ |
  24. * | ^ \post |
  25. * | post| \break |
  26. * | break| \on |
  27. * | off| \----> +-----------+ |
  28. * | +------------- | postbreak | |
  29. * | +-----------+ |
  30. * | |
  31. * +-----------------------------------------------------------------+
  32. *
  33. */
  34. enum event_post_type
  35. {
  36. EVENT_POST_NULL,
  37. EVENT_POST_START,
  38. EVENT_POST_BREAKON,
  39. EVENT_POST_BREAKOFF,
  40. EVENT_POST_ANSWER,
  41. EVENT_POST_NUMS,
  42. };
  43. static struct state state_root, state_post, state_postpass, state_postfail,
  44. state_postbreak;
  45. static void print_msg_err( void *state_data, struct event *event );
  46. static void print_msg_enter( void *state_data, struct event *event );
  47. static void print_msg_exit( void *state_data, struct event *event );
  48. static void state_post_enter( void *state_data, struct event *event );
  49. static bool guard_post_pass( void *condition, struct event *event );
  50. static bool guard_post_fail( void *condition, struct event *event );
  51. static void action_post_break( void *oldstate_data, struct event *event,
  52. void *state_new_data );
  53. static void action_post_pass( void *oldstate_data, struct event *event,
  54. void *state_new_data );
  55. static void action_post_fail( void *oldstate_data, struct event *event,
  56. void *state_new_data );
  57. static struct state state_root = {
  58. .state_parent = NULL,
  59. .state_entry = NULL,
  60. .transitions = (struct transition[]){
  61. /* event_type, condition, guard, action, next, state */
  62. { EVENT_POST_START, NULL, NULL, NULL, &state_post },
  63. },
  64. .transition_nums = 1,
  65. .data = "ROOT",
  66. .action_entry = &print_msg_enter,
  67. .action_exti = &print_msg_exit,
  68. };
  69. static struct state state_post = {
  70. .state_parent = NULL,
  71. .state_entry = NULL,
  72. .transitions = (struct transition[]){
  73. { EVENT_POST_BREAKON, NULL, NULL, &action_post_break, &state_postbreak },
  74. { EVENT_POST_ANSWER, (void*)1, &guard_post_fail, &action_post_fail, &state_postfail },
  75. { EVENT_POST_ANSWER, (void*)2, &guard_post_pass, &action_post_pass, &state_postpass },
  76. },
  77. .transition_nums = 3,
  78. .data = "POST",
  79. .action_entry = &state_post_enter,
  80. .action_exti = &print_msg_exit,
  81. };
  82. static struct state state_postpass = {
  83. .state_parent = NULL,
  84. .state_entry = NULL,
  85. .data = "POSTPASS",
  86. .action_entry = &print_msg_enter,
  87. .action_exti = &print_msg_exit,
  88. };
  89. static struct state state_postfail = {
  90. .state_parent = NULL,
  91. .state_entry = NULL,
  92. .data = "POSTFAIL",
  93. .action_entry = &print_msg_enter,
  94. .action_exti = &print_msg_exit,
  95. };
  96. static struct state state_postbreak = {
  97. .state_parent = NULL,
  98. .state_entry = NULL,
  99. .transitions = (struct transition[]){
  100. { EVENT_POST_BREAKOFF, NULL, NULL, NULL, &state_post },
  101. },
  102. .transition_nums = 1,
  103. .data = "POSTBREAK",
  104. .action_entry = &print_msg_enter,
  105. .action_exti = &print_msg_exit,
  106. };
  107. static struct state state_error = {
  108. .data = "ERROR",
  109. .action_entry = &print_msg_err,
  110. };
  111. /* post process start */
  112. static void state_post_enter( void *state_data, struct event *event )
  113. {
  114. print_msg_enter(state_data, event);
  115. log_i("post start...");
  116. }
  117. static void action_post_break( void *oldstate_data, struct event *event,
  118. void *state_new_data )
  119. {
  120. log_i("post break,display break...");
  121. }
  122. static bool guard_post_pass( void *condition, struct event *event )
  123. {
  124. if(event->type != EVENT_POST_ANSWER)
  125. {
  126. return false;
  127. }
  128. return ((int)event->data == (int)condition);
  129. }
  130. static void action_post_pass( void *oldstate_data, struct event *event,
  131. void *state_new_data )
  132. {
  133. log_i("post pass,display pass...");
  134. }
  135. static bool guard_post_fail( void *condition, struct event *event )
  136. {
  137. if(event->type != EVENT_POST_ANSWER)
  138. {
  139. return false;
  140. }
  141. return ((int)event->data == (int)condition);
  142. }
  143. static void action_post_fail( void *oldstate_data, struct event *event,
  144. void *state_new_data )
  145. {
  146. log_i("post fail,display fail...");
  147. }
  148. /* post process end */
  149. static void print_msg_err( void *state_data, struct event *event )
  150. {
  151. log_e( "entered error state!" );
  152. }
  153. static void print_msg_enter( void *state_data, struct event *event )
  154. {
  155. log_i( "entering %s state", (char *)state_data );
  156. }
  157. static void print_msg_exit( void *state_data, struct event *event )
  158. {
  159. log_i( "Eexiting %s state", (char *)state_data );
  160. }
  161. static rt_mq_t mq_event_post;
  162. static struct state_machine m_post;
  163. int state_post_event_set(enum event_post_type event, void* data)
  164. {
  165. struct event e;
  166. RT_ASSERT(event < EVENT_POST_NUMS);
  167. e.type = event;
  168. e.data = data;
  169. return rt_mq_send(mq_event_post, &e, sizeof(struct event));
  170. }
  171. static void state_process(void *parameter)
  172. {
  173. struct event e;
  174. statem_init( &m_post, &state_root, &state_error );
  175. while(1)
  176. {
  177. if(RT_EOK == rt_mq_recv(mq_event_post, &e, sizeof(struct event), 20))
  178. {
  179. statem_handle_event( &m_post, &(struct event){ e.type, e.data } );
  180. }
  181. }
  182. }
  183. static int state_post_init(void)
  184. {
  185. rt_thread_t tid = RT_NULL;
  186. mq_event_post = rt_mq_create("event_post",sizeof(struct event), 16, RT_IPC_FLAG_FIFO);
  187. tid = rt_thread_create("state_post", state_process, RT_NULL, 1024, 10, 100);
  188. if (tid == RT_NULL)
  189. {
  190. rt_kprintf("state post initialize failed! thread create failed!\r\n");
  191. return -RT_ENOMEM;
  192. }
  193. rt_thread_startup(tid);
  194. return RT_EOK;
  195. }
  196. INIT_APP_EXPORT(state_post_init);
  197. #ifdef FINSH_USING_MSH
  198. static void post_event_set(uint8_t argc, char **argv)
  199. {
  200. struct event e;
  201. if(argc < 2)
  202. {
  203. rt_kprintf("state post event set <event> <data>\n");
  204. }
  205. else
  206. {
  207. const char *operator = argv[1];
  208. if (argc == 3)
  209. {
  210. e.data = (void*)atoi(argv[2]);
  211. }
  212. else
  213. {
  214. e.data = RT_NULL;
  215. }
  216. if (!rt_strcmp(operator, "start"))
  217. {
  218. e.type = EVENT_POST_START;
  219. }
  220. else if (!rt_strcmp(operator, "breakon"))
  221. {
  222. e.type = EVENT_POST_BREAKON;
  223. }
  224. else if (!rt_strcmp(operator, "breakoff"))
  225. {
  226. e.type = EVENT_POST_BREAKOFF;
  227. }
  228. else if (!rt_strcmp(operator, "answer"))
  229. {
  230. e.type = EVENT_POST_ANSWER;
  231. }
  232. else
  233. {
  234. rt_kprintf("state key set:%s\n",argv[1]);
  235. return;
  236. }
  237. state_post_event_set(e.type, e.data);
  238. }
  239. }
  240. MSH_CMD_EXPORT(post_event_set, state post event set <event> <data>.);
  241. static void post_current_get(uint8_t argc, char **argv)
  242. {
  243. if(!m_post.state_current->data)
  244. {
  245. rt_kprintf("post current state is NULL\n");
  246. }
  247. else
  248. {
  249. rt_kprintf("post current state is %s\n",m_post.state_current->data);
  250. }
  251. }
  252. MSH_CMD_EXPORT(post_current_get, get current state.);
  253. #endif /* FINSH_USING_MSH */