esp_event.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright 2018 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef ESP_EVENT_H_
  15. #define ESP_EVENT_H_
  16. #include "esp_err.h"
  17. #include "freertos/FreeRTOS.h"
  18. #include "freertos/task.h"
  19. #include "freertos/queue.h"
  20. #include "freertos/semphr.h"
  21. #include "esp_event_base.h"
  22. #include "esp_event_legacy.h"
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. /// Configuration for creating event loops
  27. typedef struct {
  28. int32_t queue_size; /**< size of the event loop queue */
  29. const char* task_name; /**< name of the event loop task; if NULL,
  30. a dedicated task is not created for event loop*/
  31. UBaseType_t task_priority; /**< priority of the event loop task, ignored if task name is NULL */
  32. uint32_t task_stack_size; /**< stack size of the event loop task, ignored if task name is NULL */
  33. BaseType_t task_core_id; /**< core to which the event loop task is pinned to,
  34. ignored if task name is NULL */
  35. } esp_event_loop_args_t;
  36. /**
  37. * @brief Create a new event loop.
  38. *
  39. * @param[in] event_loop_args configuration structure for the event loop to create
  40. * @param[out] event_loop handle to the created event loop
  41. *
  42. * @return
  43. * - ESP_OK: Success
  44. * - ESP_ERR_INVALID_ARG: event_loop_args or event_loop was NULL
  45. * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
  46. * - ESP_FAIL: Failed to create task loop
  47. * - Others: Fail
  48. */
  49. esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop);
  50. /**
  51. * @brief Delete an existing event loop.
  52. *
  53. * @param[in] event_loop event loop to delete, must not be NULL
  54. *
  55. * @return
  56. * - ESP_OK: Success
  57. * - Others: Fail
  58. */
  59. esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop);
  60. /**
  61. * @brief Create default event loop
  62. *
  63. * @return
  64. * - ESP_OK: Success
  65. * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
  66. * - ESP_FAIL: Failed to create task loop
  67. * - Others: Fail
  68. */
  69. esp_err_t esp_event_loop_create_default(void);
  70. /**
  71. * @brief Delete the default event loop
  72. *
  73. * @return
  74. * - ESP_OK: Success
  75. * - Others: Fail
  76. */
  77. esp_err_t esp_event_loop_delete_default(void);
  78. /**
  79. * @brief Dispatch events posted to an event loop.
  80. *
  81. * This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL
  82. * in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time
  83. * it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee
  84. * that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have
  85. * been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue.
  86. * Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being
  87. * able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued
  88. * event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code
  89. * execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch
  90. * the last unqueued event.
  91. *
  92. * In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is
  93. * normal behavior.
  94. *
  95. * @param[in] event_loop event loop to dispatch posted events from, must not be NULL
  96. * @param[in] ticks_to_run number of ticks to run the loop
  97. *
  98. * @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error.
  99. *
  100. * @return
  101. * - ESP_OK: Success
  102. * - Others: Fail
  103. */
  104. esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t ticks_to_run);
  105. /**
  106. * @brief Register an event handler to the system event loop.
  107. *
  108. * This function can be used to register a handler for either: (1) specific events,
  109. * (2) all events of a certain event base, or (3) all events known by the system event loop.
  110. *
  111. * - specific events: specify exact event_base and event_id
  112. * - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
  113. * - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
  114. *
  115. * Registering multiple handlers to events is possible. Registering a single handler to multiple events is
  116. * also possible. However, registering the same handler to the same event multiple times would cause the
  117. * previous registrations to be overwritten.
  118. *
  119. * @param[in] event_base the base id of the event to register the handler for
  120. * @param[in] event_id the id of the event to register the handler for
  121. * @param[in] event_handler the handler function which gets called when the event is dispatched
  122. * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
  123. *
  124. * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
  125. * ensure that event_handler_arg still points to a valid location by the time the handler gets called
  126. *
  127. * @return
  128. * - ESP_OK: Success
  129. * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
  130. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
  131. * - Others: Fail
  132. */
  133. esp_err_t esp_event_handler_register(esp_event_base_t event_base,
  134. int32_t event_id,
  135. esp_event_handler_t event_handler,
  136. void* event_handler_arg);
  137. /**
  138. * @brief Register an event handler to a specific loop.
  139. *
  140. * This function behaves in the same manner as esp_event_handler_register, except the additional
  141. * specification of the event loop to register the handler to.
  142. *
  143. * @param[in] event_loop the event loop to register this handler function to, must not be NULL
  144. * @param[in] event_base the base id of the event to register the handler for
  145. * @param[in] event_id the id of the event to register the handler for
  146. * @param[in] event_handler the handler function which gets called when the event is dispatched
  147. * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
  148. *
  149. * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
  150. * ensure that event_handler_arg still points to a valid location by the time the handler gets called
  151. *
  152. * @return
  153. * - ESP_OK: Success
  154. * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
  155. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
  156. * - Others: Fail
  157. */
  158. esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
  159. esp_event_base_t event_base,
  160. int32_t event_id,
  161. esp_event_handler_t event_handler,
  162. void *event_handler_arg);
  163. /**
  164. * @brief Unregister a handler with the system event loop.
  165. *
  166. * Unregisters a handler so it will no longer be called during dispatch.
  167. * Handlers can be unregistered for any combination of event_base and event_id which were previously registered.
  168. * To unregister a handler, the event_base and event_id arguments must match exactly the arguments passed to
  169. * esp_event_handler_register() when that handler was registered. Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID
  170. * will only unregister handlers that were registered with the same wildcard arguments.
  171. *
  172. * @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be
  173. * unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be
  174. * unregistered. This avoids accidental unregistration of handlers registered by other users or components.
  175. *
  176. * @param[in] event_base the base of the event with which to unregister the handler
  177. * @param[in] event_id the id of the event with which to unregister the handler
  178. * @param[in] event_handler the handler to unregister
  179. *
  180. * @return ESP_OK success
  181. * @return ESP_ERR_INVALID_ARG invalid combination of event base and event id
  182. * @return others fail
  183. */
  184. esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler);
  185. /**
  186. * @brief Unregister a handler with the system event loop.
  187. *
  188. * This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of
  189. * the event loop to unregister the handler with.
  190. *
  191. * @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
  192. * @param[in] event_base the base of the event with which to unregister the handler
  193. * @param[in] event_id the id of the event with which to unregister the handler
  194. * @param[in] event_handler the handler to unregister
  195. *
  196. * @return
  197. * - ESP_OK: Success
  198. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
  199. * - Others: Fail
  200. */
  201. esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
  202. esp_event_base_t event_base,
  203. int32_t event_id,
  204. esp_event_handler_t event_handler);
  205. /**
  206. * @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages
  207. * the copy's lifetime automatically (allocation + deletion); this ensures that the data the
  208. * handler recieves is always valid.
  209. *
  210. * @param[in] event_base the event base that identifies the event
  211. * @param[in] event_id the event id that identifies the event
  212. * @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
  213. * @param[in] event_data_size the size of the event data
  214. * @param[in] ticks_to_wait number of ticks to block on a full event queue
  215. *
  216. * @return
  217. * - ESP_OK: Success
  218. * - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
  219. * queue full when posting from ISR
  220. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
  221. * - Others: Fail
  222. */
  223. esp_err_t esp_event_post(esp_event_base_t event_base,
  224. int32_t event_id,
  225. void* event_data,
  226. size_t event_data_size,
  227. TickType_t ticks_to_wait);
  228. /**
  229. * @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages
  230. * the copy's lifetime automatically (allocation + deletion); this ensures that the data the
  231. * handler recieves is always valid.
  232. *
  233. * This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop
  234. * to post the event to.
  235. *
  236. * @param[in] event_loop the event loop to post to, must not be NULL
  237. * @param[in] event_base the event base that identifies the event
  238. * @param[in] event_id the event id that identifies the event
  239. * @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
  240. * @param[in] event_data_size the size of the event data
  241. * @param[in] ticks_to_wait number of ticks to block on a full event queue
  242. *
  243. * @return
  244. * - ESP_OK: Success
  245. * - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
  246. * queue full when posting from ISR
  247. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
  248. * - Others: Fail
  249. */
  250. esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
  251. esp_event_base_t event_base,
  252. int32_t event_id,
  253. void* event_data,
  254. size_t event_data_size,
  255. TickType_t ticks_to_wait);
  256. #if CONFIG_ESP_EVENT_POST_FROM_ISR
  257. /**
  258. * @brief Special variant of esp_event_post for posting events from interrupt handlers.
  259. *
  260. * @param[in] event_base the event base that identifies the event
  261. * @param[in] event_id the event id that identifies the event
  262. * @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
  263. * @param[in] event_data_size the size of the event data; max is 4 bytes
  264. * @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
  265. * higher priority than currently running task has been unblocked by the posted event;
  266. * a context switch should be requested before the interrupt is exited.
  267. *
  268. * @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled
  269. * @note when this function is called from an interrupt handler placed in IRAM, this function should
  270. * be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
  271. *
  272. * @return
  273. * - ESP_OK: Success
  274. * - ESP_FAIL: Event queue for the default event loop full
  275. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
  276. * data size of more than 4 bytes
  277. * - Others: Fail
  278. */
  279. esp_err_t esp_event_isr_post(esp_event_base_t event_base,
  280. int32_t event_id,
  281. void* event_data,
  282. size_t event_data_size,
  283. BaseType_t* task_unblocked);
  284. /**
  285. * @brief Special variant of esp_event_post_to for posting events from interrupt handlers
  286. *
  287. * @param[in] event_loop the event loop to post to, must not be NULL
  288. * @param[in] event_base the event base that identifies the event
  289. * @param[in] event_id the event id that identifies the event
  290. * @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
  291. * @param[in] event_data_size the size of the event data
  292. * @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
  293. * higher priority than currently running task has been unblocked by the posted event;
  294. * a context switch should be requested before the interrupt is exited.
  295. *
  296. * @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled
  297. * @note when this function is called from an interrupt handler placed in IRAM, this function should
  298. * be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
  299. *
  300. * @return
  301. * - ESP_OK: Success
  302. * - ESP_FAIL: Event queue for the loop full
  303. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
  304. * data size of more than 4 bytes
  305. * - Others: Fail
  306. */
  307. esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop,
  308. esp_event_base_t event_base,
  309. int32_t event_id,
  310. void* event_data,
  311. size_t event_data_size,
  312. BaseType_t* task_unblocked);
  313. #endif
  314. /**
  315. * @brief Dumps statistics of all event loops.
  316. *
  317. * Dumps event loop info in the format:
  318. *
  319. @verbatim
  320. event loop
  321. handler
  322. handler
  323. ...
  324. event loop
  325. handler
  326. handler
  327. ...
  328. where:
  329. event loop
  330. format: address,name rx:total_recieved dr:total_dropped
  331. where:
  332. address - memory address of the event loop
  333. name - name of the event loop, 'none' if no dedicated task
  334. total_recieved - number of successfully posted events
  335. total_dropped - number of events unsuccessfully posted due to queue being full
  336. handler
  337. format: address ev:base,id inv:total_invoked run:total_runtime
  338. where:
  339. address - address of the handler function
  340. base,id - the event specified by event base and id this handler executes
  341. total_invoked - number of times this handler has been invoked
  342. total_runtime - total amount of time used for invoking this handler
  343. @endverbatim
  344. *
  345. * @param[in] file the file stream to output to
  346. *
  347. * @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled
  348. *
  349. * @return
  350. * - ESP_OK: Success
  351. * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
  352. * - Others: Fail
  353. */
  354. esp_err_t esp_event_dump(FILE* file);
  355. #ifdef __cplusplus
  356. } // extern "C"
  357. #endif
  358. #endif // #ifndef ESP_EVENT_H_