esp_check.h 19 KB

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