esp_app_trace_util.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. #include "esp_timer.h"
  14. /** Infinite waiting timeout */
  15. #define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1)
  16. /** Structure which holds data necessary for measuring time intervals.
  17. *
  18. * After initialization via esp_apptrace_tmo_init() user needs to call esp_apptrace_tmo_check()
  19. * periodically to check timeout for expiration.
  20. */
  21. typedef struct {
  22. int64_t start; ///< time interval start (in us)
  23. int64_t tmo; ///< timeout value (in us)
  24. int64_t elapsed; ///< elapsed time (in us)
  25. } esp_apptrace_tmo_t;
  26. /**
  27. * @brief Initializes timeout structure.
  28. *
  29. * @param tmo Pointer to timeout structure to be initialized.
  30. * @param user_tmo Timeout value (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
  31. */
  32. static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo)
  33. {
  34. tmo->start = esp_timer_get_time();
  35. tmo->tmo = user_tmo == ESP_APPTRACE_TMO_INFINITE ? (int64_t)-1 : (int64_t)user_tmo;
  36. tmo->elapsed = 0;
  37. }
  38. /**
  39. * @brief Checks timeout for expiration.
  40. *
  41. * @param tmo Pointer to timeout structure.
  42. *
  43. * @return number of remaining us till tmo.
  44. */
  45. esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo);
  46. static inline uint32_t esp_apptrace_tmo_remaining_us(esp_apptrace_tmo_t *tmo)
  47. {
  48. return tmo->tmo != (int64_t)-1 ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
  49. }
  50. /** Tracing module synchronization lock */
  51. typedef struct {
  52. spinlock_t mux;
  53. unsigned int_state;
  54. } esp_apptrace_lock_t;
  55. /**
  56. * @brief Initializes lock structure.
  57. *
  58. * @param lock Pointer to lock structure to be initialized.
  59. */
  60. static inline void esp_apptrace_lock_init(esp_apptrace_lock_t *lock)
  61. {
  62. portMUX_INITIALIZE(&lock->mux);
  63. lock->int_state = 0;
  64. }
  65. /**
  66. * @brief Tries to acquire lock in specified time period.
  67. *
  68. * @param lock Pointer to lock structure.
  69. * @param tmo Pointer to timeout struct.
  70. *
  71. * @return ESP_OK on success, otherwise \see esp_err_t
  72. */
  73. esp_err_t esp_apptrace_lock_take(esp_apptrace_lock_t *lock, esp_apptrace_tmo_t *tmo);
  74. /**
  75. * @brief Releases lock.
  76. *
  77. * @param lock Pointer to lock structure.
  78. *
  79. * @return ESP_OK on success, otherwise \see esp_err_t
  80. */
  81. esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock);
  82. /** Ring buffer control structure.
  83. *
  84. * @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped
  85. * current ring buffer size can be temporarily shrinked in order to provide buffer with requested size.
  86. */
  87. typedef struct {
  88. uint8_t *data; ///< pointer to data storage
  89. volatile uint32_t size; ///< size of data storage
  90. volatile uint32_t cur_size; ///< current size of data storage
  91. volatile uint32_t rd; ///< read pointer
  92. volatile uint32_t wr; ///< write pointer
  93. } esp_apptrace_rb_t;
  94. /**
  95. * @brief Initializes ring buffer control structure.
  96. *
  97. * @param rb Pointer to ring buffer structure to be initialized.
  98. * @param data Pointer to buffer to be used as ring buffer's data storage.
  99. * @param size Size of buffer to be used as ring buffer's data storage.
  100. */
  101. static inline void esp_apptrace_rb_init(esp_apptrace_rb_t *rb, uint8_t *data, uint32_t size)
  102. {
  103. rb->data = data;
  104. rb->size = rb->cur_size = size;
  105. rb->rd = 0;
  106. rb->wr = 0;
  107. }
  108. /**
  109. * @brief Allocates memory chunk in ring buffer.
  110. *
  111. * @param rb Pointer to ring buffer structure.
  112. * @param size Size of the memory to allocate.
  113. *
  114. * @return Pointer to the allocated memory or NULL in case of failure.
  115. */
  116. uint8_t *esp_apptrace_rb_produce(esp_apptrace_rb_t *rb, uint32_t size);
  117. /**
  118. * @brief Consumes memory chunk in ring buffer.
  119. *
  120. * @param rb Pointer to ring buffer structure.
  121. * @param size Size of the memory to consume.
  122. *
  123. * @return Pointer to consumed memory chunk or NULL in case of failure.
  124. */
  125. uint8_t *esp_apptrace_rb_consume(esp_apptrace_rb_t *rb, uint32_t size);
  126. /**
  127. * @brief Gets size of memory which can consumed with single call to esp_apptrace_rb_consume().
  128. *
  129. * @param rb Pointer to ring buffer structure.
  130. *
  131. * @return Size of memory which can consumed.
  132. *
  133. * @note Due to read pointer wrapping returned size can be less then the total size of available data.
  134. */
  135. uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb);
  136. /**
  137. * @brief Gets size of memory which can produced with single call to esp_apptrace_rb_produce().
  138. *
  139. * @param rb Pointer to ring buffer structure.
  140. *
  141. * @return Size of memory which can produced.
  142. *
  143. * @note Due to write pointer wrapping returned size can be less then the total size of available data.
  144. */
  145. uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb);
  146. int esp_apptrace_log_lock(void);
  147. void esp_apptrace_log_unlock(void);
  148. #define ESP_APPTRACE_LOG( format, ... ) \
  149. do { \
  150. esp_apptrace_log_lock(); \
  151. esp_rom_printf(format, ##__VA_ARGS__); \
  152. esp_apptrace_log_unlock(); \
  153. } while(0)
  154. #define ESP_APPTRACE_LOG_LEV( _L_, level, format, ... ) \
  155. do { \
  156. if (LOG_LOCAL_LEVEL >= level) { \
  157. ESP_APPTRACE_LOG(LOG_FORMAT(_L_, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); \
  158. } \
  159. } while(0)
  160. #define ESP_APPTRACE_LOGE( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_ERROR, format, ##__VA_ARGS__)
  161. #define ESP_APPTRACE_LOGW( format, ... ) ESP_APPTRACE_LOG_LEV(W, ESP_LOG_WARN, format, ##__VA_ARGS__)
  162. #define ESP_APPTRACE_LOGI( format, ... ) ESP_APPTRACE_LOG_LEV(I, ESP_LOG_INFO, format, ##__VA_ARGS__)
  163. #define ESP_APPTRACE_LOGD( format, ... ) ESP_APPTRACE_LOG_LEV(D, ESP_LOG_DEBUG, format, ##__VA_ARGS__)
  164. #define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__)
  165. #define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
  166. #ifdef __cplusplus
  167. }
  168. #endif
  169. #endif //ESP_APP_TRACE_UTIL_H_