app_error.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. /** @file
  13. *
  14. * @defgroup app_error Common application error handler
  15. * @{
  16. * @ingroup app_common
  17. *
  18. * @brief Common application error handler and macros for utilizing a common error handler.
  19. */
  20. #ifndef APP_ERROR_H__
  21. #define APP_ERROR_H__
  22. #include <stdint.h>
  23. #include <stdio.h>
  24. #include <stdbool.h>
  25. #include "nrf.h"
  26. #include "sdk_errors.h"
  27. #include "nordic_common.h"
  28. #include "nrf_log.h"
  29. #include "app_error_weak.h"
  30. #define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */
  31. /**@defgroup APP_ERROR_FAULT_IDS Fault ID types
  32. * @{ */
  33. #define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
  34. #define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
  35. /**@} */
  36. /**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
  37. */
  38. typedef struct
  39. {
  40. uint16_t line_num; /**< The line number where the error occurred. */
  41. uint8_t const * p_file_name; /**< The file in which the error occurred. */
  42. uint32_t err_code; /**< The error code representing the error that occurred. */
  43. } error_info_t;
  44. /**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
  45. */
  46. typedef struct
  47. {
  48. uint16_t line_num; /**< The line number where the error occurred. */
  49. uint8_t const * p_file_name; /**< The file in which the error occurred. */
  50. } assert_info_t;
  51. /**@brief Function for error handling, which is called when an error has occurred.
  52. *
  53. * @param[in] error_code Error code supplied to the handler.
  54. * @param[in] line_num Line number where the handler is called.
  55. * @param[in] p_file_name Pointer to the file name.
  56. */
  57. void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
  58. /**@brief Function for error handling, which is called when an error has occurred.
  59. *
  60. * @param[in] error_code Error code supplied to the handler.
  61. */
  62. void app_error_handler_bare(ret_code_t error_code);
  63. /**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
  64. *
  65. * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
  66. * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
  67. * unavailable.
  68. * @param[in] info Optional additional information regarding the fault. Refer to each fault
  69. * identifier for details.
  70. */
  71. void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
  72. /**@brief Function for printing all error info (using nrf_log).
  73. *
  74. * @details Nrf_log library must be initialized using NRF_LOG_INIT macro before calling
  75. * this function.
  76. *
  77. * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
  78. * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
  79. * unavailable.
  80. * @param[in] info Optional additional information regarding the fault. Refer to each fault
  81. * identifier for details.
  82. */
  83. static __INLINE void app_error_log(uint32_t id, uint32_t pc, uint32_t info)
  84. {
  85. switch (id)
  86. {
  87. case NRF_FAULT_ID_SDK_ASSERT:
  88. NRF_LOG(NRF_LOG_COLOR_RED "\n*** ASSERTION FAILED ***\n");
  89. if (((assert_info_t *)(info))->p_file_name)
  90. {
  91. NRF_LOG_PRINTF(NRF_LOG_COLOR_WHITE "Line Number: %u\n", (unsigned int) ((assert_info_t *)(info))->line_num);
  92. NRF_LOG_PRINTF("File Name: %s\n", ((assert_info_t *)(info))->p_file_name);
  93. }
  94. NRF_LOG_PRINTF(NRF_LOG_COLOR_DEFAULT "\n");
  95. break;
  96. case NRF_FAULT_ID_SDK_ERROR:
  97. NRF_LOG(NRF_LOG_COLOR_RED "\n*** APPLICATION ERROR *** \n" NRF_LOG_COLOR_WHITE);
  98. if (((error_info_t *)(info))->p_file_name)
  99. {
  100. NRF_LOG_PRINTF("Line Number: %u\n", (unsigned int) ((error_info_t *)(info))->line_num);
  101. NRF_LOG_PRINTF("File Name: %s\n", ((error_info_t *)(info))->p_file_name);
  102. }
  103. NRF_LOG_PRINTF("Error Code: 0x%X\n" NRF_LOG_COLOR_DEFAULT "\n", (unsigned int) ((error_info_t *)(info))->err_code);
  104. break;
  105. }
  106. }
  107. /**@brief Function for printing all error info (using printf).
  108. *
  109. * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
  110. * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
  111. * unavailable.
  112. * @param[in] info Optional additional information regarding the fault. Refer to each fault
  113. * identifier for details.
  114. */
  115. //lint -save -e438
  116. static __INLINE void app_error_print(uint32_t id, uint32_t pc, uint32_t info)
  117. {
  118. unsigned int tmp = id;
  119. printf("app_error_print():\r\n");
  120. printf("Fault identifier: 0x%X\r\n", tmp);
  121. printf("Program counter: 0x%X\r\n", tmp = pc);
  122. printf("Fault information: 0x%X\r\n", tmp = info);
  123. switch (id)
  124. {
  125. case NRF_FAULT_ID_SDK_ASSERT:
  126. printf("Line Number: %u\r\n", tmp = ((assert_info_t *)(info))->line_num);
  127. printf("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name);
  128. break;
  129. case NRF_FAULT_ID_SDK_ERROR:
  130. printf("Line Number: %u\r\n", tmp = ((error_info_t *)(info))->line_num);
  131. printf("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name);
  132. printf("Error Code: 0x%X\r\n", tmp = ((error_info_t *)(info))->err_code);
  133. break;
  134. }
  135. }
  136. //lint -restore
  137. /**@brief Macro for calling error handler function.
  138. *
  139. * @param[in] ERR_CODE Error code supplied to the error handler.
  140. */
  141. #ifdef DEBUG
  142. #define APP_ERROR_HANDLER(ERR_CODE) \
  143. do \
  144. { \
  145. app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
  146. } while (0)
  147. #else
  148. #define APP_ERROR_HANDLER(ERR_CODE) \
  149. do \
  150. { \
  151. app_error_handler_bare((ERR_CODE)); \
  152. } while (0)
  153. #endif
  154. /**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
  155. *
  156. * @param[in] ERR_CODE Error code supplied to the error handler.
  157. */
  158. #define APP_ERROR_CHECK(ERR_CODE) \
  159. do \
  160. { \
  161. const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
  162. if (LOCAL_ERR_CODE != NRF_SUCCESS) \
  163. { \
  164. APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
  165. } \
  166. } while (0)
  167. /**@brief Macro for calling error handler function if supplied boolean value is false.
  168. *
  169. * @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
  170. */
  171. #define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
  172. do \
  173. { \
  174. const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
  175. if (!LOCAL_BOOLEAN_VALUE) \
  176. { \
  177. APP_ERROR_HANDLER(0); \
  178. } \
  179. } while (0)
  180. #endif // APP_ERROR_H__
  181. /** @} */