Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Copyright (c) 2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-08-16 Rbb666 first version
  9. */
  10. #ifndef __COREDUMP_H__
  11. #define __COREDUMP_H__
  12. #include <stddef.h>
  13. #include "mcd_cfg.h"
  14. #include "arm/mcd_arm_define.h"
  15. #define MCD_SECTION(x) @ x
  16. #define MCD_USED __root
  17. /**
  18. * @brief Function pointer type for coredump data output
  19. *
  20. * This function pointer type defines the interface for writing coredump data
  21. * to different output destinations (memory, serial, filesystem, etc.).
  22. *
  23. * @param data Pointer to the data buffer to be written
  24. * @param len Length of the data buffer in bytes
  25. *
  26. * @note The implementation should handle the data appropriately based on the
  27. * chosen output mode and ensure data integrity.
  28. */
  29. typedef void (*mcd_writeout_func_t)(uint8_t *, int);
  30. /**
  31. * @brief Thread information operations structure
  32. *
  33. * This structure contains function pointers for retrieving thread information
  34. * in a RTOS environment. It's designed to avoid dynamic memory allocation
  35. * during fault handling, as malloc operations may fail during hard faults.
  36. *
  37. * The structure provides a generic interface for different RTOS systems
  38. * to supply thread information for multi-threaded coredump generation.
  39. */
  40. struct thread_info_ops
  41. {
  42. /**
  43. * @brief Get total number of threads in the system
  44. * @param ops Pointer to this operations structure
  45. * @return Total thread count
  46. */
  47. int32_t (*get_threads_count)(struct thread_info_ops *);
  48. /**
  49. * @brief Get current executing thread index
  50. * @param ops Pointer to this operations structure
  51. * @return Current thread index
  52. */
  53. int32_t (*get_current_thread_idx)(struct thread_info_ops *);
  54. /**
  55. * @brief Get register set for a specific thread
  56. * @param ops Pointer to this operations structure
  57. * @param thread_idx Thread index to get registers for
  58. * @param core_regset Pointer to store ARM core registers
  59. * @param fp_regset Pointer to store FPU registers
  60. */
  61. void (*get_thread_regset)(struct thread_info_ops *, int32_t,
  62. core_regset_type *core_regset,
  63. fp_regset_type *fp_regset);
  64. /**
  65. * @brief Get number of memory areas to dump
  66. * @param ops Pointer to this operations structure
  67. * @return Number of memory areas
  68. */
  69. int32_t (*get_memarea_count)(struct thread_info_ops *);
  70. /**
  71. * @brief Get memory area information
  72. * @param ops Pointer to this operations structure
  73. * @param area_idx Memory area index
  74. * @param addr Pointer to store memory area start address
  75. * @param size Pointer to store memory area size
  76. * @return 0 on success, negative on error
  77. */
  78. int32_t (*get_memarea)(struct thread_info_ops *, int32_t,
  79. uint32_t *, uint32_t *);
  80. // 打印字符串形式的coredump信息
  81. int (*print_info_string)(struct thread_info_ops *);
  82. /** Private data for RTOS-specific implementations */
  83. void *priv;
  84. };
  85. /**
  86. * @brief Initialize the mCoreDump system
  87. *
  88. * This function initializes the mCoreDump system with automatic FPU detection.
  89. * It must be called before any coredump generation operations.
  90. *
  91. * FPU support is automatically detected based on compiler definitions:
  92. * - Enabled if __VFP_FP__ is defined and __SOFTFP__ is not defined
  93. * - Disabled if no hardware FPU support is detected
  94. *
  95. * @param func Function pointer to write the coredump data out.
  96. * This callback will be called repeatedly with chunks of coredump data.
  97. *
  98. * @note The writeout function should handle data appropriately based on the
  99. * chosen output mode (memory, serial, filesystem).
  100. *
  101. * @warning This function should be called from a safe context, preferably
  102. * during system initialization or before fault occurs.
  103. *
  104. * @see mcd_writeout_func_t for callback function requirements
  105. */
  106. void mcd_init(mcd_writeout_func_t func);
  107. /**
  108. * @brief Generate coredump for current call chain only
  109. *
  110. * This function generates a minimal coredump containing only the current
  111. * execution context (single thread). It's faster and uses less memory
  112. * compared to multi-threaded coredump generation.
  113. *
  114. * Use this function when:
  115. * - Quick fault analysis is needed
  116. * - Memory is limited
  117. * - Only current thread context is relevant
  118. *
  119. * @note This function captures the current thread's register state and
  120. * stack information at the point of call.
  121. *
  122. * @warning Must call mcd_init() before using this function.
  123. *
  124. * @see mcd_multi_dump() for full system coredump
  125. */
  126. // 不更新当前寄存器到全局变量(在异常中断中已填充)
  127. void mcd_hard_fault_exception_dump(void);
  128. // 只保存当前线程或非线程(主栈):更新当前寄存器到全局变量
  129. void mcd_mini_dump(void);
  130. // 保存RTOS所有线程:更新当前寄存器到全局变量
  131. void mcd_multi_dump(void);
  132. // 打印一段内存
  133. void print_mem(uint32_t addr, uint32_t len);
  134. // 单独打印全局变量
  135. void print_variable(void *addr, int size);
  136. // 打印宏定义的所有全局变量
  137. int mcd_variable_dump(void);
  138. #define COREADUMP_PRINT_ITEM_SIZE 2
  139. // 打印一个变量
  140. #define COREADUMP_PRINT_VARIABLE_DEFINE(name) \
  141. MCD_USED const uint32_t __coreadump_rang_##name[COREADUMP_PRINT_ITEM_SIZE] MCD_SECTION(".coreadump_rang.1") = { (uint32_t)&name, sizeof(name) }
  142. // 打印一段内存
  143. #define COREADUMP_PRINT_RANGE_DEFINE(index, addr, size) \
  144. MCD_USED const uint32_t __coreadump_rang_##index[COREADUMP_PRINT_ITEM_SIZE] MCD_SECTION(".coreadump_rang.2") = { (uint32_t)addr, (uint32_t)size }
  145. #define COREADUMP_PRINT_RANGE_DYNAMIC_MAX_NUM 3
  146. // 运行时动态打印全局变量
  147. inline int COREADUMP_PRINT_RANGE_DYNAMIC(void *addr, int size)
  148. {
  149. extern void *sg_cd_variable_addr[COREADUMP_PRINT_RANGE_DYNAMIC_MAX_NUM];
  150. extern int sg_cd_variable_sizeof[COREADUMP_PRINT_RANGE_DYNAMIC_MAX_NUM];
  151. for (int i = 0; i < COREADUMP_PRINT_RANGE_DYNAMIC_MAX_NUM; i++)
  152. {
  153. if (NULL == sg_cd_variable_addr[i] && 0 == sg_cd_variable_sizeof[i])
  154. {
  155. sg_cd_variable_addr[i] = addr;
  156. sg_cd_variable_sizeof[i] = size;
  157. return 0;
  158. }
  159. }
  160. return -1;
  161. }
  162. /**
  163. * @brief Generate coredump with all threads information
  164. *
  165. * This function generates a comprehensive coredump containing information
  166. * about all threads in the system, including their register states,
  167. * stack contents, and memory areas.
  168. *
  169. * Use this function when:
  170. * - Complete system state analysis is needed
  171. * - Multi-threading issues need to be debugged
  172. * - Full context switch information is required
  173. *
  174. * @note This function may take longer to execute and use more memory
  175. * compared to mcd_mini_dump().
  176. *
  177. * @warning Must call mcd_init() before using this function.
  178. * Should be used carefully in interrupt context due to execution time.
  179. *
  180. * @see mcd_mini_dump() for single thread coredump
  181. */
  182. //void mcd_multi_dump(void);
  183. /**
  184. * @brief Generate coredump using provided thread operations
  185. *
  186. * This is the core coredump generation function that uses the provided
  187. * thread_info_ops structure to gather system information and generate
  188. * the ELF format coredump.
  189. *
  190. * @param ops Pointer to thread information operations structure.
  191. * Contains function pointers for retrieving thread and memory information.
  192. *
  193. * @note This is a low-level function typically called by mcd_mini_dump()
  194. * and mcd_multi_dump() after setting up appropriate ops structure.
  195. *
  196. * @warning The ops structure must be properly initialized with valid
  197. * function pointers before calling this function.
  198. */
  199. void mcd_gen_coredump(struct thread_info_ops *ops);
  200. /**
  201. * @brief Setup thread operations for RTOS environment
  202. *
  203. * This function initializes the thread_info_ops structure with function
  204. * pointers appropriate for the current RTOS environment (RT-Thread).
  205. *
  206. * @param ops Pointer to thread operations structure to be initialized
  207. *
  208. * @note This function is typically called internally by mcd_multi_dump()
  209. * to set up multi-threaded coredump generation.
  210. */
  211. void mcd_rtos_thread_ops(struct thread_info_ops *ops);
  212. /**
  213. * @brief Setup thread operations for single thread dump
  214. *
  215. * This function initializes the thread_info_ops structure for minimal
  216. * coredump generation (current thread only).
  217. *
  218. * @param ops Pointer to thread operations structure to be initialized
  219. *
  220. * @note This function is typically called internally by mcd_mini_dump()
  221. * to set up single-threaded coredump generation.
  222. */
  223. void mcd_mini_dump_ops(struct thread_info_ops *ops);
  224. /**
  225. * @brief Generate coredump and save to specified output.
  226. *
  227. * @param[in] output_mode Output mode (MCD_OUTPUT_SERIAL, MCD_OUTPUT_MEMORY, or MCD_OUTPUT_FILESYSTEM).
  228. *
  229. * @return Whether save operation success.
  230. * @retval MCD_OK success.
  231. * @retval MCD_ERROR failed.
  232. */
  233. int mcd_faultdump(mcd_output_mode_t output_mode);
  234. /**
  235. * @brief Print coredump memory information at startup
  236. *
  237. * This function should be called during system initialization
  238. */
  239. void mcd_print_memoryinfo(void);
  240. /**
  241. * @brief Get address of current core register set
  242. *
  243. * This function returns a pointer to the current thread's core register
  244. * set storage area. The register values are captured during fault handling.
  245. *
  246. * @return Pointer to core register set structure
  247. *
  248. * @note The returned pointer points to static storage that gets updated
  249. * each time a fault occurs or registers are captured.
  250. */
  251. core_regset_type *get_cur_core_regset_address(void);
  252. /**
  253. * @brief Get address of current floating-point register set
  254. *
  255. * This function returns a pointer to the current thread's floating-point
  256. * register set storage area. The register values are captured during fault handling.
  257. *
  258. * @return Pointer to floating-point register set structure
  259. *
  260. * @note The returned pointer points to static storage that gets updated
  261. * each time a fault occurs or registers are captured.
  262. * Returns valid data only if FPU is available and enabled.
  263. */
  264. fp_regset_type *get_cur_fp_regset_address(void);
  265. #endif /* __MCOREDUMP_H__ */