esp_check.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include "esp_err.h"
  8. #include "esp_log.h"
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. /**
  13. * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns.
  14. */
  15. #if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT)
  16. #define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do { \
  17. (void)log_tag; \
  18. esp_err_t err_rc_ = (x); \
  19. if (unlikely(err_rc_ != ESP_OK)) { \
  20. return err_rc_; \
  21. } \
  22. } while(0)
  23. /**
  24. * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.
  25. */
  26. #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do { \
  27. (void)log_tag; \
  28. esp_err_t err_rc_ = (x); \
  29. if (unlikely(err_rc_ != ESP_OK)) { \
  30. return err_rc_; \
  31. } \
  32. } while(0)
  33. /**
  34. * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message,
  35. * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.
  36. */
  37. #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do { \
  38. (void)log_tag; \
  39. esp_err_t err_rc_ = (x); \
  40. if (unlikely(err_rc_ != ESP_OK)) { \
  41. ret = err_rc_; \
  42. goto goto_tag; \
  43. } \
  44. } while(0)
  45. /**
  46. * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.
  47. */
  48. #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do { \
  49. (void)log_tag; \
  50. esp_err_t err_rc_ = (x); \
  51. if (unlikely(err_rc_ != ESP_OK)) { \
  52. ret = err_rc_; \
  53. goto goto_tag; \
  54. } \
  55. } while(0)
  56. /**
  57. * Macro which can be used to check the condition. If the condition is not 'true', it prints the message
  58. * and returns with the supplied 'err_code'.
  59. */
  60. #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \
  61. (void)log_tag; \
  62. if (unlikely(!(a))) { \
  63. return err_code; \
  64. } \
  65. } while(0)
  66. /**
  67. * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.
  68. */
  69. #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do { \
  70. (void)log_tag; \
  71. if (unlikely(!(a))) { \
  72. return err_code; \
  73. } \
  74. } while(0)
  75. /**
  76. * Macro which can be used to check the condition. If the condition is not 'true', it prints the message,
  77. * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.
  78. */
  79. #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \
  80. (void)log_tag; \
  81. if (unlikely(!(a))) { \
  82. ret = err_code; \
  83. goto goto_tag; \
  84. } \
  85. } while (0)
  86. /**
  87. * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.
  88. */
  89. #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do { \
  90. (void)log_tag; \
  91. if (unlikely(!(a))) { \
  92. ret = err_code; \
  93. goto goto_tag; \
  94. } \
  95. } while (0)
  96. #else // !CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT
  97. /**
  98. * In the future, we want to switch to C++20. We also want to become compatible with clang.
  99. * Hence, we provide two versions of the following macros. The first one is using the GNU extension \#\#__VA_ARGS__.
  100. * The second one is using the C++20 feature __VA_OPT__(,). This allows users to compile their code with
  101. * standard C++20 enabled instead of the GNU extension. Below C++20, we haven't found any good alternative to
  102. * using \#\#__VA_ARGS__.
  103. */
  104. #if defined(__cplusplus) && (__cplusplus > 201703L)
  105. /**
  106. * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns.
  107. */
  108. #define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do { \
  109. esp_err_t err_rc_ = (x); \
  110. if (unlikely(err_rc_ != ESP_OK)) { \
  111. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  112. return err_rc_; \
  113. } \
  114. } while(0)
  115. /**
  116. * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.
  117. */
  118. #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do { \
  119. esp_err_t err_rc_ = (x); \
  120. if (unlikely(err_rc_ != ESP_OK)) { \
  121. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  122. return err_rc_; \
  123. } \
  124. } while(0)
  125. /**
  126. * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message,
  127. * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.
  128. */
  129. #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do { \
  130. esp_err_t err_rc_ = (x); \
  131. if (unlikely(err_rc_ != ESP_OK)) { \
  132. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  133. ret = err_rc_; \
  134. goto goto_tag; \
  135. } \
  136. } while(0)
  137. /**
  138. * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.
  139. */
  140. #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do { \
  141. esp_err_t err_rc_ = (x); \
  142. if (unlikely(err_rc_ != ESP_OK)) { \
  143. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  144. ret = err_rc_; \
  145. goto goto_tag; \
  146. } \
  147. } while(0)
  148. /**
  149. * Macro which can be used to check the condition. If the condition is not 'true', it prints the message
  150. * and returns with the supplied 'err_code'.
  151. */
  152. #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \
  153. if (unlikely(!(a))) { \
  154. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  155. return err_code; \
  156. } \
  157. } while(0)
  158. /**
  159. * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.
  160. */
  161. #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do { \
  162. if (unlikely(!(a))) { \
  163. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  164. return err_code; \
  165. } \
  166. } while(0)
  167. /**
  168. * Macro which can be used to check the condition. If the condition is not 'true', it prints the message,
  169. * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.
  170. */
  171. #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \
  172. if (unlikely(!(a))) { \
  173. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  174. ret = err_code; \
  175. goto goto_tag; \
  176. } \
  177. } while (0)
  178. /**
  179. * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.
  180. */
  181. #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do { \
  182. if (unlikely(!(a))) { \
  183. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
  184. ret = err_code; \
  185. goto goto_tag; \
  186. } \
  187. } while (0)
  188. #else // !(defined(__cplusplus) && (__cplusplus > 201703L))
  189. /**
  190. * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns.
  191. */
  192. #define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do { \
  193. esp_err_t err_rc_ = (x); \
  194. if (unlikely(err_rc_ != ESP_OK)) { \
  195. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  196. return err_rc_; \
  197. } \
  198. } while(0)
  199. /**
  200. * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR.
  201. */
  202. #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do { \
  203. esp_err_t err_rc_ = (x); \
  204. if (unlikely(err_rc_ != ESP_OK)) { \
  205. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  206. return err_rc_; \
  207. } \
  208. } while(0)
  209. /**
  210. * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message,
  211. * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'.
  212. */
  213. #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do { \
  214. esp_err_t err_rc_ = (x); \
  215. if (unlikely(err_rc_ != ESP_OK)) { \
  216. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  217. ret = err_rc_; \
  218. goto goto_tag; \
  219. } \
  220. } while(0)
  221. /**
  222. * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR.
  223. */
  224. #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do { \
  225. esp_err_t err_rc_ = (x); \
  226. if (unlikely(err_rc_ != ESP_OK)) { \
  227. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  228. ret = err_rc_; \
  229. goto goto_tag; \
  230. } \
  231. } while(0)
  232. /**
  233. * Macro which can be used to check the condition. If the condition is not 'true', it prints the message
  234. * and returns with the supplied 'err_code'.
  235. */
  236. #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \
  237. if (unlikely(!(a))) { \
  238. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  239. return err_code; \
  240. } \
  241. } while(0)
  242. /**
  243. * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR.
  244. */
  245. #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do { \
  246. if (unlikely(!(a))) { \
  247. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  248. return err_code; \
  249. } \
  250. } while(0)
  251. /**
  252. * Macro which can be used to check the condition. If the condition is not 'true', it prints the message,
  253. * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'.
  254. */
  255. #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \
  256. if (unlikely(!(a))) { \
  257. ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  258. ret = err_code; \
  259. goto goto_tag; \
  260. } \
  261. } while (0)
  262. /**
  263. * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR.
  264. */
  265. #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do { \
  266. if (unlikely(!(a))) { \
  267. ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  268. ret = err_code; \
  269. goto goto_tag; \
  270. } \
  271. } while (0)
  272. #endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
  273. #endif // !CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT
  274. #ifdef __cplusplus
  275. }
  276. #endif