XFusion API v1.3.0
载入中...
搜索中...
未找到
xf_utils_log_dump.c
浏览该文件的文档.
1
12/* ==================== [Includes] ========================================== */
13
14#include "xf_utils_log_config.h"
15
16#if XF_LOG_DUMP_IS_ENABLE
17
18#include "xf_utils_log.h"
19
20/* ==================== [Defines] =========================================== */
21
22/* 只输出 16 进制格式数据时,每行实际会输出的字节数 */
23#define XF_DUMP_HEX_BYTES_PER_LINE (53)
24/* 输出 16 进制格式数据和 ASCII 字符时,每行实际会输出的字节数 */
25#define XF_DUMP_HEX_ASCII_BYTES_PER_LINE (72)
26/* 输出 16 进制格式数据、 ASCII 字符、转义字符时,每行实际会输出的字节数 */
27#define XF_DUMP_HEX_ASCII_ESCAPE_BYTES_PER_LINE (104)
28/* 表头字节数,可能会多几个字节 */
29#define XF_DUMP_TABLE_HEADER_BYTES (332)
30
31/* ==================== [Typedefs] ========================================== */
32
33/* ==================== [Static Prototypes] ================================= */
34
35/* ==================== [Static Variables] ================================== */
36
37/* ==================== [Macros] ============================================ */
38
39/* ==================== [Global Functions] ================================== */
40
41xf_err_t xf_dump_mem(void *addr, size_t size, uint8_t flags_mask)
42{
43 if ((!addr) || (size == 0)) {
44 xf_log_dump_printf("Invalid memory block\n");
45 return XF_ERR_INVALID_ARG;
46 }
47
48 // 每行输出的内存字节数,不等于实际输出字节
49 const uint8_t bytes_mem_out_per_line = 16;
50
51 // 每行实际输出字节数
52 uint8_t bytes_actually_out_per_line = 0;
53 if (!BIT_GET(flags_mask, XF_DUMP_ASCII_BIT)) {
54 bytes_actually_out_per_line = XF_DUMP_HEX_BYTES_PER_LINE;
55 } else if (BIT_GET(flags_mask, XF_DUMP_ASCII_BIT)
56 && !BIT_GET(flags_mask, XF_DUMP_ESCAPE_BIT)) {
57 bytes_actually_out_per_line = XF_DUMP_HEX_ASCII_BYTES_PER_LINE;
58 } else if (BIT_GET(flags_mask, XF_DUMP_ASCII_BIT)
59 && BIT_GET(flags_mask, XF_DUMP_ESCAPE_BIT)) {
60 bytes_actually_out_per_line = XF_DUMP_HEX_ASCII_ESCAPE_BYTES_PER_LINE;
61 }
62
63 // 打印内存块的起始地址
64 xf_log_dump_printf("MEMORY START ADDRESS: %p, OUTPUT %d BYTES.\n", addr, (int)size);
65
66 // 打印表头
67 if (BIT_GET(flags_mask, XF_DUMP_HEAD_BIT)) {
68 for (uint8_t i = 0; i < bytes_actually_out_per_line; i++) {
70 }
72 xf_log_dump_printf(" OFS "); // 偏移 offset
73 for (uint8_t i = 0; i < bytes_mem_out_per_line; i++) {
74 xf_log_dump_printf("%2X ", i);
75 }
76 if (BIT_GET(flags_mask, XF_DUMP_ASCII_BIT)) {
77 xf_log_dump_printf("| ASCII");
78 }
80 for (uint8_t i = 0; i < bytes_actually_out_per_line; i++) {
82 }
84 }
85
86 uint8_t byte = 0; // 当前地址的字节的值
87 // 遍历内存块中
88 for (size_t i = 0; i < size; i++) {
89 byte = *((uint8_t *)addr + i);
90
91 if (i % bytes_mem_out_per_line == 0) {
92 // 每行的开头打印行号
93 xf_log_dump_printf("%04lu: ", (unsigned long)(i / bytes_mem_out_per_line));
94 }
95
96 xf_log_dump_printf("%02X ", byte); // 打印当前地址的字节的值的十六进制
97
98 // 如果达到每行显示的字节数,
99 // 或者已经是最后一个字节,就打印 ASCII 字符串
100 if (((i + 1) % bytes_mem_out_per_line == 0) || (i == size - 1)) {
101 // 如果不是每行显示的字节数,就补齐空格
102 if ((i + 1) % bytes_mem_out_per_line != 0) {
103 for (size_t j = 0;
104 j < (bytes_mem_out_per_line - (i + 1) % bytes_mem_out_per_line) * 3;
105 j++) {
107 }
108 }
109 // 遍历输出 ASCII
110 if (BIT_GET(flags_mask, XF_DUMP_ASCII_BIT)) {
111 xf_log_dump_printf("| ");
112 for (size_t j = i - i % bytes_mem_out_per_line; j <= i; j++) {
113 uint8_t b = *((uint8_t *)addr + j);
114 if (b >= ' ' && b <= '~') { // 可见字符
115 if (BIT_GET(flags_mask, XF_DUMP_ESCAPE_BIT)) {
117 }
118 xf_log_dump_printf("%c", b);
119 if (BIT_GET(flags_mask, XF_DUMP_ESCAPE_BIT)) {
121 }
122 } else if (BIT_GET(flags_mask, XF_DUMP_ESCAPE_BIT)) {
123 // 显示转义字符
124 switch (b) {
125 case '\0': xf_log_dump_printf("\\0 "); break; // 空字符
126 case '\a': xf_log_dump_printf("\\a "); break; // 响铃符
127 case '\b': xf_log_dump_printf("\\b "); break; // 退格符
128 case '\t': xf_log_dump_printf("\\t "); break; // 水平制表符
129 case '\n': xf_log_dump_printf("\\n "); break; // 换行符
130 case '\v': xf_log_dump_printf("\\v "); break; // 垂直制表符
131 case '\f': xf_log_dump_printf("\\f "); break; // 换页符
132 case '\r': xf_log_dump_printf("\\r "); break; // 回车符
133 // 其他不可打印字符,用十六进制表示
134 default: xf_log_dump_printf("%02x ", b); break;
135 }
136 } else {
137 // 转义字符外的不可见字符
139 if (BIT_GET(flags_mask, XF_DUMP_ESCAPE_BIT)) {
141 }
142 } /* else: 非转义字符 */
143 } /* for: 输出 ASCII */
144 } /* if: 需要输出 ASCII */
145 xf_log_dump_printf("\n");
146 } /* if: 需要输出 ASCII 或空格 */
147 } /* for: 0 ~ size */
148 /* 表尾 */
149 if (BIT_GET(flags_mask, XF_DUMP_TAIL_BIT)) {
150 for (uint8_t i = 0; i < bytes_actually_out_per_line; i++) {
152 }
153 xf_log_dump_printf("\n");
154 }
155 return XF_OK;
156}
157
158#endif // XF_LOG_DUMP_IS_ENABLE
159
160/* ==================== [Static Functions] ================================== */
161
#define BIT_GET(src, n)
获取 32 位源 src 的 bit_n。
int32_t xf_err_t
整形错误类型。 错误码具体值见 xf_err_code_t.
Definition xf_err.h:69
@ XF_ERR_INVALID_ARG
Definition xf_err.h:46
@ XF_OK
Definition xf_err.h:43
xf_err_t xf_dump_mem(void *addr, size_t size, uint8_t flags_mask)
输出内存信息。
#define XF_DUMP_ASCII_BIT
#define XF_DUMP_TAIL_BIT
#define XF_DUMP_ESCAPE_BIT
#define XF_DUMP_HEAD_BIT
xf_utils 的 log 封装。
xf_utils_log 配置。
#define xf_log_dump_printf(format,...)
#define XF_DUMP_HEX_ASCII_ESCAPE_BYTES_PER_LINE
#define XF_DUMP_HEX_BYTES_PER_LINE
#define XF_DUMP_HEX_ASCII_BYTES_PER_LINE