esp_app_trace_util.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef ESP_APP_TRACE_UTIL_H_
  7. #define ESP_APP_TRACE_UTIL_H_
  8. #ifdef __cplusplus
  9. extern "C" {
  10. #endif
  11. #include "freertos/FreeRTOS.h"
  12. #include "esp_err.h"
  13. /** Infinite waiting timeout */
  14. #define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1)
  15. /** Structure which holds data necessary for measuring time intervals.
  16. *
  17. * After initialization via esp_apptrace_tmo_init() user needs to call esp_apptrace_tmo_check()
  18. * periodically to check timeout for expiration.
  19. */
  20. typedef struct {
  21. uint32_t start; ///< time interval start (in CPU ticks)
  22. uint32_t tmo; ///< timeout value (in us)
  23. uint32_t elapsed; ///< elapsed time (in us)
  24. } esp_apptrace_tmo_t;
  25. /**
  26. * @brief Initializes timeout structure.
  27. *
  28. * @param tmo Pointer to timeout structure to be initialized.
  29. * @param user_tmo Timeout value (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
  30. */
  31. static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo)
  32. {
  33. tmo->start = portGET_RUN_TIME_COUNTER_VALUE();
  34. tmo->tmo = user_tmo;
  35. tmo->elapsed = 0;
  36. }
  37. /**
  38. * @brief Checks timeout for expiration.
  39. *
  40. * @param tmo Pointer to timeout structure to be initialized.
  41. *
  42. * @return ESP_OK on success, otherwise \see esp_err_t
  43. */
  44. esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo);
  45. static inline uint32_t esp_apptrace_tmo_remaining_us(esp_apptrace_tmo_t *tmo)
  46. {
  47. return tmo->tmo != ESP_APPTRACE_TMO_INFINITE ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
  48. }
  49. /** Tracing module synchronization lock */
  50. typedef struct {
  51. portMUX_TYPE mux;
  52. unsigned int_state;
  53. } esp_apptrace_lock_t;
  54. /**
  55. * @brief Initializes lock structure.
  56. *
  57. * @param lock Pointer to lock structure to be initialized.
  58. */
  59. static inline void esp_apptrace_lock_init(esp_apptrace_lock_t *lock)
  60. {
  61. vPortCPUInitializeMutex(&lock->mux);
  62. lock->int_state = 0;
  63. }
  64. /**
  65. * @brief Tries to acquire lock in specified time period.
  66. *
  67. * @param lock Pointer to lock structure.
  68. * @param tmo Pointer to timeout struct.
  69. *
  70. * @return ESP_OK on success, otherwise \see esp_err_t
  71. */
  72. esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *tmo);
  73. /**
  74. * @brief Releases lock.
  75. *
  76. * @param lock Pointer to lock structure.
  77. *
  78. * @return ESP_OK on success, otherwise \see esp_err_t
  79. */
  80. esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock);
  81. /** Ring buffer control structure.
  82. *
  83. * @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped
  84. * current ring buffer size can be temporarily shrinked in order to provide buffer with requested size.
  85. */
  86. typedef struct {
  87. uint8_t *data; ///< pointer to data storage
  88. volatile uint32_t size; ///< size of data storage
  89. volatile uint32_t cur_size; ///< current size of data storage
  90. volatile uint32_t rd; ///< read pointer
  91. volatile uint32_t wr; ///< write pointer
  92. } esp_apptrace_rb_t;
  93. /**
  94. * @brief Initializes ring buffer control structure.
  95. *
  96. * @param rb Pointer to ring buffer structure to be initialized.
  97. * @param data Pointer to buffer to be used as ring buffer's data storage.
  98. * @param size Size of buffer to be used as ring buffer's data storage.
  99. */
  100. static inline void esp_apptrace_rb_init(esp_apptrace_rb_t *rb, uint8_t *data, uint32_t size)
  101. {
  102. rb->data = data;
  103. rb->size = rb->cur_size = size;
  104. rb->rd = 0;
  105. rb->wr = 0;
  106. }
  107. /**
  108. * @brief Allocates memory chunk in ring buffer.
  109. *
  110. * @param rb Pointer to ring buffer structure.
  111. * @param size Size of the memory to allocate.
  112. *
  113. * @return Pointer to the allocated memory or NULL in case of failure.
  114. */
  115. uint8_t *esp_apptrace_rb_produce(esp_apptrace_rb_t *rb, uint32_t size);
  116. /**
  117. * @brief Consumes memory chunk in ring buffer.
  118. *
  119. * @param rb Pointer to ring buffer structure.
  120. * @param size Size of the memory to consume.
  121. *
  122. * @return Pointer to consumed memory chunk or NULL in case of failure.
  123. */
  124. uint8_t *esp_apptrace_rb_consume(esp_apptrace_rb_t *rb, uint32_t size);
  125. /**
  126. * @brief Gets size of memory which can consumed with single call to esp_apptrace_rb_consume().
  127. *
  128. * @param rb Pointer to ring buffer structure.
  129. *
  130. * @return Size of memory which can consumed.
  131. *
  132. * @note Due to read pointer wrapping returned size can be less then the total size of available data.
  133. */
  134. uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb);
  135. /**
  136. * @brief Gets size of memory which can produced with single call to esp_apptrace_rb_produce().
  137. *
  138. * @param rb Pointer to ring buffer structure.
  139. *
  140. * @return Size of memory which can produced.
  141. *
  142. * @note Due to write pointer wrapping returned size can be less then the total size of available data.
  143. */
  144. uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb);
  145. #ifdef __cplusplus
  146. }
  147. #endif
  148. #endif //ESP_APP_TRACE_UTIL_H_