esp_event.h 24 KB

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