esp_event.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /*
  2. * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef ESP_EVENT_H_
  7. #define ESP_EVENT_H_
  8. #include "esp_err.h"
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "freertos/queue.h"
  12. #include "freertos/semphr.h"
  13. #include "esp_event_base.h"
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. /// Configuration for creating event loops
  18. typedef struct {
  19. int32_t queue_size; /**< size of the event loop queue */
  20. const char *task_name; /**< name of the event loop task; if NULL,
  21. a dedicated task is not created for event loop*/
  22. UBaseType_t task_priority; /**< priority of the event loop task, ignored if task name is NULL */
  23. uint32_t task_stack_size; /**< stack size of the event loop task, ignored if task name is NULL */
  24. BaseType_t task_core_id; /**< core to which the event loop task is pinned to,
  25. ignored if task name is NULL */
  26. } esp_event_loop_args_t;
  27. /**
  28. * @brief Create a new event loop.
  29. *
  30. * @param[in] event_loop_args configuration structure for the event loop to create
  31. * @param[out] event_loop handle to the created event loop
  32. *
  33. * @return
  34. * - ESP_OK: Success
  35. * - ESP_ERR_INVALID_ARG: event_loop_args or event_loop was NULL
  36. * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
  37. * - ESP_FAIL: Failed to create task loop
  38. * - Others: Fail
  39. */
  40. esp_err_t esp_event_loop_create(const esp_event_loop_args_t *event_loop_args, esp_event_loop_handle_t *event_loop);
  41. /**
  42. * @brief Delete an existing event loop.
  43. *
  44. * @param[in] event_loop event loop to delete, must not be NULL
  45. *
  46. * @return
  47. * - ESP_OK: Success
  48. * - Others: Fail
  49. */
  50. esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop);
  51. /**
  52. * @brief Create default event loop
  53. *
  54. * @return
  55. * - ESP_OK: Success
  56. * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
  57. * - ESP_ERR_INVALID_STATE: Default event loop has already been created
  58. * - ESP_FAIL: Failed to create task loop
  59. * - Others: Fail
  60. */
  61. esp_err_t esp_event_loop_create_default(void);
  62. /**
  63. * @brief Delete the default event loop
  64. *
  65. * @return
  66. * - ESP_OK: Success
  67. * - Others: Fail
  68. */
  69. esp_err_t esp_event_loop_delete_default(void);
  70. /**
  71. * @brief Dispatch events posted to an event loop.
  72. *
  73. * This function is used to dispatch events posted to a loop with no dedicated task, i.e. task name was set to NULL
  74. * in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time
  75. * it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee
  76. * that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have
  77. * been dispatched during the call, as the function might have spent all the allotted time waiting on the event queue.
  78. * Once an event has been dequeued, however, it is guaranteed to be dispatched. This guarantee contributes to not being
  79. * able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the dequeued
  80. * event, and (2) during dispatch of the dequeued event there is no way to control the time occupied by handler code
  81. * execution. The guaranteed time of exit is therefore the allotted time + amount of time required to dispatch
  82. * the last dequeued event.
  83. *
  84. * In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is
  85. * normal behavior.
  86. *
  87. * @param[in] event_loop event loop to dispatch posted events from, must not be NULL
  88. * @param[in] ticks_to_run number of ticks to run the loop
  89. *
  90. * @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error.
  91. *
  92. * @return
  93. * - ESP_OK: Success
  94. * - Others: Fail
  95. */
  96. esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t ticks_to_run);
  97. /**
  98. * @brief Register an event handler to the system event loop (legacy).
  99. *
  100. * This function can be used to register a handler for either: (1) specific events,
  101. * (2) all events of a certain event base, or (3) all events known by the system event loop.
  102. *
  103. * - specific events: specify exact event_base and event_id
  104. * - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
  105. * - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
  106. *
  107. * Registering multiple handlers to events is possible. Registering a single handler to multiple events is
  108. * also possible. However, registering the same handler to the same event multiple times would cause the
  109. * previous registrations to be overwritten.
  110. *
  111. * @param[in] event_base the base ID of the event to register the handler for
  112. * @param[in] event_id the ID of the event to register the handler for
  113. * @param[in] event_handler the handler function which gets called when the event is dispatched
  114. * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
  115. *
  116. * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
  117. * ensure that event_handler_arg still points to a valid location by the time the handler gets called
  118. *
  119. * @return
  120. * - ESP_OK: Success
  121. * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
  122. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  123. * - Others: Fail
  124. */
  125. esp_err_t esp_event_handler_register(esp_event_base_t event_base,
  126. int32_t event_id,
  127. esp_event_handler_t event_handler,
  128. void *event_handler_arg);
  129. /**
  130. * @brief Register an event handler to a specific loop (legacy).
  131. *
  132. * This function behaves in the same manner as esp_event_handler_register, except the additional
  133. * specification of the event loop to register the handler to.
  134. *
  135. * @param[in] event_loop the event loop to register this handler function to, must not be NULL
  136. * @param[in] event_base the base ID of the event to register the handler for
  137. * @param[in] event_id the ID of the event to register the handler for
  138. * @param[in] event_handler the handler function which gets called when the event is dispatched
  139. * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
  140. *
  141. * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
  142. * ensure that event_handler_arg still points to a valid location by the time the handler gets called
  143. *
  144. * @return
  145. * - ESP_OK: Success
  146. * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
  147. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  148. * - Others: Fail
  149. */
  150. esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
  151. esp_event_base_t event_base,
  152. int32_t event_id,
  153. esp_event_handler_t event_handler,
  154. void *event_handler_arg);
  155. /**
  156. * @brief Register an instance of event handler to a specific loop.
  157. *
  158. * This function can be used to register a handler for either: (1) specific events,
  159. * (2) all events of a certain event base, or (3) all events known by the system event loop.
  160. *
  161. * - specific events: specify exact event_base and event_id
  162. * - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
  163. * - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
  164. *
  165. * Besides the error, the function returns an instance object as output parameter to identify each registration.
  166. * This is necessary to remove (unregister) the registration before the event loop is deleted.
  167. *
  168. * Registering multiple handlers to events, registering a single handler to multiple events as well as registering
  169. * the same handler to the same event multiple times is possible.
  170. * Each registration yields a distinct instance object which identifies it over the registration
  171. * lifetime.
  172. *
  173. * @param[in] event_loop the event loop to register this handler function to, must not be NULL
  174. * @param[in] event_base the base ID of the event to register the handler for
  175. * @param[in] event_id the ID of the event to register the handler for
  176. * @param[in] event_handler the handler function which gets called when the event is dispatched
  177. * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
  178. * @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL.
  179. * This needs to be kept if the specific callback instance should be unregistered before deleting the whole
  180. * event loop. Registering the same event handler multiple times is possible and yields distinct instance
  181. * objects. The data can be the same for all registrations.
  182. * If no unregistration is needed, but the handler should be deleted when the event loop is deleted,
  183. * instance can be NULL.
  184. *
  185. * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
  186. * ensure that event_handler_arg still points to a valid location by the time the handler gets called
  187. *
  188. * @return
  189. * - ESP_OK: Success
  190. * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
  191. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID or instance is NULL
  192. * - Others: Fail
  193. */
  194. esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handle_t event_loop,
  195. esp_event_base_t event_base,
  196. int32_t event_id,
  197. esp_event_handler_t event_handler,
  198. void *event_handler_arg,
  199. esp_event_handler_instance_t *instance);
  200. /**
  201. * @brief Register an instance of event handler to the default loop.
  202. *
  203. * This function does the same as esp_event_handler_instance_register_with, except that it registers the
  204. * handler to the default event loop.
  205. *
  206. * @param[in] event_base the base ID of the event to register the handler for
  207. * @param[in] event_id the ID of the event to register the handler for
  208. * @param[in] event_handler the handler function which gets called when the event is dispatched
  209. * @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
  210. * @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL.
  211. * This needs to be kept if the specific callback instance should be unregistered before deleting the whole
  212. * event loop. Registering the same event handler multiple times is possible and yields distinct instance
  213. * objects. The data can be the same for all registrations.
  214. * If no unregistration is needed, but the handler should be deleted when the event loop is deleted,
  215. * instance can be NULL.
  216. *
  217. * @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
  218. * ensure that event_handler_arg still points to a valid location by the time the handler gets called
  219. *
  220. * @return
  221. * - ESP_OK: Success
  222. * - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
  223. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID or instance is NULL
  224. * - Others: Fail
  225. */
  226. esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
  227. int32_t event_id,
  228. esp_event_handler_t event_handler,
  229. void *event_handler_arg,
  230. esp_event_handler_instance_t *instance);
  231. /**
  232. * @brief Unregister a handler with the system event loop (legacy).
  233. *
  234. * Unregisters a handler, so it will no longer be called during dispatch.
  235. * Handlers can be unregistered for any combination of event_base and event_id which were previously registered.
  236. * To unregister a handler, the event_base and event_id arguments must match exactly the arguments passed to
  237. * esp_event_handler_register() when that handler was registered. Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID
  238. * will only unregister handlers that were registered with the same wildcard arguments.
  239. *
  240. * @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be
  241. * unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be
  242. * unregistered. This avoids accidental unregistration of handlers registered by other users or components.
  243. *
  244. * @param[in] event_base the base of the event with which to unregister the handler
  245. * @param[in] event_id the ID of the event with which to unregister the handler
  246. * @param[in] event_handler the handler to unregister
  247. *
  248. * @return ESP_OK success
  249. * @return ESP_ERR_INVALID_ARG invalid combination of event base and event ID
  250. * @return others fail
  251. */
  252. esp_err_t esp_event_handler_unregister(esp_event_base_t event_base,
  253. int32_t event_id,
  254. esp_event_handler_t event_handler);
  255. /**
  256. * @brief Unregister a handler from a specific event loop (legacy).
  257. *
  258. * This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of
  259. * the event loop to unregister the handler with.
  260. *
  261. * @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
  262. * @param[in] event_base the base of the event with which to unregister the handler
  263. * @param[in] event_id the ID of the event with which to unregister the handler
  264. * @param[in] event_handler the handler to unregister
  265. *
  266. * @return
  267. * - ESP_OK: Success
  268. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  269. * - Others: Fail
  270. */
  271. esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
  272. esp_event_base_t event_base,
  273. int32_t event_id,
  274. esp_event_handler_t event_handler);
  275. /**
  276. * @brief Unregister a handler instance from a specific event loop.
  277. *
  278. * Unregisters a handler instance, so it will no longer be called during dispatch.
  279. * Handler instances can be unregistered for any combination of event_base and event_id which were previously
  280. * registered. To unregister a handler instance, the event_base and event_id arguments must match exactly the
  281. * arguments passed to esp_event_handler_instance_register() when that handler instance was registered.
  282. * Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID will only unregister handler instances that were registered
  283. * with the same wildcard arguments.
  284. *
  285. * @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be
  286. * unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be
  287. * unregistered. This avoids accidental unregistration of handlers registered by other users or components.
  288. *
  289. * @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
  290. * @param[in] event_base the base of the event with which to unregister the handler
  291. * @param[in] event_id the ID of the event with which to unregister the handler
  292. * @param[in] instance the instance object of the registration to be unregistered
  293. *
  294. * @return
  295. * - ESP_OK: Success
  296. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  297. * - Others: Fail
  298. */
  299. esp_err_t esp_event_handler_instance_unregister_with(esp_event_loop_handle_t event_loop,
  300. esp_event_base_t event_base,
  301. int32_t event_id,
  302. esp_event_handler_instance_t instance);
  303. /**
  304. * @brief Unregister a handler from the system event loop.
  305. *
  306. * This function does the same as esp_event_handler_instance_unregister_with, except that it unregisters the
  307. * handler instance from the default event loop.
  308. *
  309. * @param[in] event_base the base of the event with which to unregister the handler
  310. * @param[in] event_id the ID of the event with which to unregister the handler
  311. * @param[in] instance the instance object of the registration to be unregistered
  312. *
  313. * @return
  314. * - ESP_OK: Success
  315. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  316. * - Others: Fail
  317. */
  318. esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
  319. int32_t event_id,
  320. esp_event_handler_instance_t instance);
  321. /**
  322. * @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages
  323. * the copy's lifetime automatically (allocation + deletion); this ensures that the data the
  324. * handler receives is always valid.
  325. *
  326. * @param[in] event_base the event base that identifies the event
  327. * @param[in] event_id the event ID that identifies the event
  328. * @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
  329. * @param[in] event_data_size the size of the event data
  330. * @param[in] ticks_to_wait number of ticks to block on a full event queue
  331. *
  332. * @return
  333. * - ESP_OK: Success
  334. * - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
  335. * queue full when posting from ISR
  336. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  337. * - Others: Fail
  338. */
  339. esp_err_t esp_event_post(esp_event_base_t event_base,
  340. int32_t event_id,
  341. const void *event_data,
  342. size_t event_data_size,
  343. TickType_t ticks_to_wait);
  344. /**
  345. * @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages
  346. * the copy's lifetime automatically (allocation + deletion); this ensures that the data the
  347. * handler receives is always valid.
  348. *
  349. * This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop
  350. * to post the event to.
  351. *
  352. * @param[in] event_loop the event loop to post to, must not be NULL
  353. * @param[in] event_base the event base that identifies the event
  354. * @param[in] event_id the event ID that identifies the event
  355. * @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
  356. * @param[in] event_data_size the size of the event data
  357. * @param[in] ticks_to_wait number of ticks to block on a full event queue
  358. *
  359. * @return
  360. * - ESP_OK: Success
  361. * - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
  362. * queue full when posting from ISR
  363. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
  364. * - Others: Fail
  365. */
  366. esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
  367. esp_event_base_t event_base,
  368. int32_t event_id,
  369. const void *event_data,
  370. size_t event_data_size,
  371. TickType_t ticks_to_wait);
  372. #if CONFIG_ESP_EVENT_POST_FROM_ISR
  373. /**
  374. * @brief Special variant of esp_event_post for posting events from interrupt handlers.
  375. *
  376. * @param[in] event_base the event base that identifies the event
  377. * @param[in] event_id the event ID that identifies the event
  378. * @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
  379. * @param[in] event_data_size the size of the event data; max is 4 bytes
  380. * @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
  381. * higher priority than currently running task has been unblocked by the posted event;
  382. * a context switch should be requested before the interrupt is existed.
  383. *
  384. * @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled
  385. * @note when this function is called from an interrupt handler placed in IRAM, this function should
  386. * be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
  387. *
  388. * @return
  389. * - ESP_OK: Success
  390. * - ESP_FAIL: Event queue for the default event loop full
  391. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID,
  392. * data size of more than 4 bytes
  393. * - Others: Fail
  394. */
  395. esp_err_t esp_event_isr_post(esp_event_base_t event_base,
  396. int32_t event_id,
  397. const void *event_data,
  398. size_t event_data_size,
  399. BaseType_t *task_unblocked);
  400. /**
  401. * @brief Special variant of esp_event_post_to for posting events from interrupt handlers
  402. *
  403. * @param[in] event_loop the event loop to post to, must not be NULL
  404. * @param[in] event_base the event base that identifies the event
  405. * @param[in] event_id the event ID that identifies the event
  406. * @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
  407. * @param[in] event_data_size the size of the event data
  408. * @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
  409. * higher priority than currently running task has been unblocked by the posted event;
  410. * a context switch should be requested before the interrupt is existed.
  411. *
  412. * @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled
  413. * @note when this function is called from an interrupt handler placed in IRAM, this function should
  414. * be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
  415. *
  416. * @return
  417. * - ESP_OK: Success
  418. * - ESP_FAIL: Event queue for the loop full
  419. * - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID,
  420. * data size of more than 4 bytes
  421. * - Others: Fail
  422. */
  423. esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop,
  424. esp_event_base_t event_base,
  425. int32_t event_id,
  426. const void *event_data,
  427. size_t event_data_size,
  428. BaseType_t *task_unblocked);
  429. #endif
  430. /**
  431. * @brief Dumps statistics of all event loops.
  432. *
  433. * Dumps event loop info in the format:
  434. *
  435. @verbatim
  436. event loop
  437. handler
  438. handler
  439. ...
  440. event loop
  441. handler
  442. handler
  443. ...
  444. where:
  445. event loop
  446. format: address,name rx:total_received dr:total_dropped
  447. where:
  448. address - memory address of the event loop
  449. name - name of the event loop, 'none' if no dedicated task
  450. total_received - number of successfully posted events
  451. total_dropped - number of events unsuccessfully posted due to queue being full
  452. handler
  453. format: address ev:base,id inv:total_invoked run:total_runtime
  454. where:
  455. address - address of the handler function
  456. base,id - the event specified by event base and ID this handler executes
  457. total_invoked - number of times this handler has been invoked
  458. total_runtime - total amount of time used for invoking this handler
  459. @endverbatim
  460. *
  461. * @param[in] file the file stream to output to
  462. *
  463. * @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled
  464. *
  465. * @return
  466. * - ESP_OK: Success
  467. * - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
  468. * - Others: Fail
  469. */
  470. esp_err_t esp_event_dump(FILE *file);
  471. #ifdef __cplusplus
  472. } // extern "C"
  473. #endif
  474. #endif // #ifndef ESP_EVENT_H_