1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: LOG BUFFER MODULE.
15 * Author:
16 * Create: 2018-10-15
17 */
18
19 #include "securec.h"
20 #include "non_os.h"
21 #include "panic.h"
22 #include "soc_osal.h"
23 #include "log_buffer.h"
24
25 /*
26 * Private definitions
27 */
28 #define index_in_cbuff(x) ((x) < g_log_buffer_size)
29
30 /*
31 * Private variables
32 */
33 static uint8_t *g_log_buffer_start;
34 static uint32_t g_log_buffer_size;
35 static volatile log_memory_section_control_t *g_log_section_control;
36
37 volatile massdata_memory_section_control_t *g_mass_section_control = NULL;
38
39 /**
40 * Read an index with overflow.
41 * @param index_in index in the limits of the circular buffer or up to buffer_size longer
42 * @return index in the circular buffer limits
43 */
circled_index(uint32_t index_in)44 static uint32_t circled_index(uint32_t index_in)
45 {
46 uint32_t index_out;
47
48 if (index_in < g_log_buffer_size) {
49 index_out = index_in;
50 } else {
51 index_out = index_in - g_log_buffer_size;
52 }
53 if (!index_in_cbuff(index_out)) {
54 panic(PANIC_LOG, __LINE__);
55 return 0;
56 }
57 return index_out;
58 }
59
log_buffer_get_used(uint32_t read_i,uint32_t write_i)60 static uint32_t log_buffer_get_used(uint32_t read_i, uint32_t write_i)
61 {
62 uint32_t in_use;
63 /* Check how much space is used. Use -1 to ensure the g_log_section_control->write ==
64 * g_log_section_control->read means the buffer is EMPTY.
65 * Without the -1, the g_log_section_control->write COULD wrap and catch up with g_log_section_control->read. */
66 if (read_i <= write_i) {
67 in_use = write_i - read_i;
68 } else {
69 /* g_log_section_control->write has wrapped, but g_log_section_control->read has not yet. */
70 in_use = (g_log_buffer_size - read_i) + write_i;
71 }
72 return in_use;
73 }
74
75 /**
76 * Get the available space in the buffer
77 * @param av if return is LOG_RET_OK the available data will be stored in the pointer given
78 * @return LOG_RET_OK or an error value
79 */
log_buffer_get_available(uint32_t * av)80 static inline log_ret_t log_buffer_get_available(uint32_t *av)
81 {
82 uint32_t l_read_i = g_log_section_control->read;
83 uint32_t l_write_i = g_log_section_control->write;
84
85 /* Check how much space is available. Use -1 to ensure the g_log_section_control->write ==
86 * g_log_section_control->read means the buffer is EMPTY.
87 * Without the -1, the g_log_section_control->write COULD wrap and catch up with g_log_section_control->read. */
88 if (!index_in_cbuff(l_read_i) || !index_in_cbuff(l_write_i)) { return LOG_RET_ERROR_CORRUPT_SHARED_MEMORY; }
89
90 if (l_read_i <= l_write_i) {
91 // l_read_i and l_write_i has been checked to be in safe boundaries.
92 *av = (g_log_buffer_size - 1u) - (l_write_i - l_read_i);
93 /* g_log_section_control->write has wrapped, but g_log_section_control->read has not yet. */
94 // l_read_i and l_write_i has been checked to be in safe boundaries.
95 } else { *av = (l_read_i - l_write_i) - 1u; }
96 return LOG_RET_OK;
97 }
98
99 /**
100 * Add data to the circular buffer with updating the write index.
101 * @param data buffer with the data to store
102 * @param data_len data length in bytes
103 */
log_buffer_helper_add(const uint8_t * data,const uint32_t data_len)104 static void log_buffer_helper_add(const uint8_t *data, const uint32_t data_len)
105 {
106 errno_t sec_ret;
107 uint32_t l_write = g_log_section_control->write;
108 size_t to_end = g_log_buffer_size - l_write;
109
110 if (to_end >= data_len) {
111 /* Entire message fits. */
112 sec_ret = memcpy_s((void *)(g_log_buffer_start + l_write), to_end, data, data_len);
113 } else {
114 /* Message needs to be segmented. Write to end of buffer and then the remainder from the beginning. */
115 sec_ret = memcpy_s((void *)(g_log_buffer_start + l_write), to_end, data, to_end);
116 if (sec_ret != EOK) {
117 return;
118 }
119 sec_ret = memcpy_s((void *)g_log_buffer_start, g_log_section_control->read, &data[to_end], data_len - to_end);
120 }
121 if (sec_ret != EOK) {
122 return;
123 }
124
125 g_log_section_control->write = circled_index(l_write + data_len);
126 }
127
128 /**
129 * Scatter gather write to log_buffer.
130 * @param length array of lengths for the different buffers, it admits 0 as a value of one of them
131 * @param buffer array of values containig the buffers to the data to save in the log buffer
132 * @param was_empty if a pointer != NULL is given it will store a return value
133 * indicating the buffer was empty when the write was done.
134 * @return LOG_RET_OK or an error value
135 */
log_buffer_write(const log_buffer_header_t * lb_header,const uint8_t * buffer,bool * was_empty)136 void log_buffer_write(const log_buffer_header_t *lb_header, const uint8_t *buffer, bool *was_empty)
137 {
138 uint32_t l_read_i;
139 uint32_t l_write_i;
140 // Add the header
141 log_buffer_helper_add((const uint8_t *)lb_header, sizeof(log_buffer_header_t));
142
143 // Add the buffer
144 log_buffer_helper_add(buffer, lb_header->length - sizeof(log_buffer_header_t));
145
146 l_read_i = g_log_section_control->read;
147 l_write_i = g_log_section_control->write;
148
149 *was_empty = (log_buffer_get_used(l_read_i, l_write_i) <= lb_header->length);
150 }
151 #ifdef FEATURE_PLT_LB_CHECK
152
153 uint8_t *g_p_log_buf_sdt_cur = NULL;
154 uint8_t *g_p_log_buf_sdt_beg = NULL;
155 uint8_t *g_p_log_buf_sdt_end = NULL;
156
log_buffer_check_rlw(uint8_t * beg,uint8_t * end)157 static uint8_t log_buffer_check_rlw(uint8_t *beg, uint8_t *end)
158 {
159 uint8_t *cur = NULL;
160 log_buffer_header_t *hdr = NULL;
161
162 if ((beg == NULL) || (end == NULL)) {
163 return 0xFF;
164 }
165
166 if (beg >= end) {
167 return 0xFE;
168 }
169
170 cur = beg;
171 while (cur < end) {
172 hdr = (log_buffer_header_t *)(cur);
173 if (!lb_magic_check(hdr)) {
174 g_p_log_buf_sdt_beg = beg;
175 g_p_log_buf_sdt_cur = cur;
176 g_p_log_buf_sdt_end = end;
177
178 return LOG_BUF_RLW_MAGIC_ERROR;
179 }
180
181 cur += hdr->length;
182 }
183
184 return LOG_BUF_RET_OK;
185 }
186
187 #define MAX_ONE_LOG_CPY_LENGTH 100
188 #define G_LB_BUF_LEN 200
189 static uint8_t g_lb_buf[G_LB_BUF_LEN] = { 0 };
190
log_buffer_check_last_one(uint8_t ** beg,uint8_t * end,uint8_t ** cur,log_buffer_header_t * hdr)191 static uint8_t log_buffer_check_last_one(uint8_t **beg, uint8_t *end, uint8_t **cur, log_buffer_header_t *hdr)
192 {
193 uint32_t last_len = end - (*cur);
194 uint8_t *buf = g_lb_buf;
195 memset_s(buf, sizeof(g_lb_buf), 0, G_LB_BUF_LEN);
196 if (memcpy_s(buf, sizeof(g_lb_buf), *cur, last_len) != EOK) {
197 return LOG_RET_MEMCPY_ERROR;
198 }
199 *beg = (uint8_t *)(g_log_buffer_start);
200 if (memcpy_s(buf + last_len, sizeof(g_lb_buf) - last_len, *beg, MAX_ONE_LOG_CPY_LENGTH) != EOK) {
201 return LOG_RET_MEMCPY_ERROR;
202 }
203 hdr = (log_buffer_header_t *)(buf);
204
205 /* magic check */
206 if (!lb_magic_check(hdr)) {
207 g_p_log_buf_sdt_beg = *beg;
208 g_p_log_buf_sdt_cur = *cur;
209 g_p_log_buf_sdt_end = end;
210 return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
211 }
212 *cur = (*beg) + ((log_buffer_header_t)(*hdr)).length - last_len;
213 return LOG_BUF_RET_OK;
214 }
215
log_buffer_check_rgw(uint8_t * ori_beg,uint8_t * ori_end)216 static uint8_t log_buffer_check_rgw(uint8_t *ori_beg, uint8_t *ori_end)
217 {
218 uint8_t *beg = ori_beg;
219 uint8_t *end = ori_end;
220 uint8_t *cur = NULL;
221 log_buffer_header_t *hdr = NULL;
222 uint8_t last_one = 0;
223
224 if ((beg == NULL) || (end == NULL)) { return 0xFF; }
225 if (beg <= end) { return 0xFE; }
226 cur = beg;
227 end = (uint8_t *)(g_log_buffer_start + g_log_buffer_size);
228 while (cur < end) {
229 if ((cur + sizeof(log_buffer_header_t)) >= end) { // judge last one
230 last_one = 1;
231 break;
232 }
233 hdr = (log_buffer_header_t *)(cur);
234 if ((cur + hdr->length) > end) {
235 last_one = 1;
236 break;
237 }
238 if (!lb_magic_check(hdr)) { // magic check
239 g_p_log_buf_sdt_beg = beg;
240 g_p_log_buf_sdt_cur = cur;
241 g_p_log_buf_sdt_end = end;
242 return LOG_RET_RGW_TOEND_MAGIC_ERROR;
243 }
244 if ((cur + hdr->length) == end) { // to end
245 cur = (uint8_t *)(g_log_buffer_start);
246 break;
247 }
248 cur += hdr->length;
249 }
250 if (last_one && log_buffer_check_last_one(&beg, end, &cur, hdr) == LOG_RET_RGW_LASTONE_MAGIC_ERROR) { // last one
251 return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
252 }
253 end = ori_end; // from head
254 while (cur < end) {
255 hdr = (log_buffer_header_t *)(cur);
256 if (!lb_magic_check(hdr)) { // magic check
257 g_p_log_buf_sdt_beg = beg;
258 g_p_log_buf_sdt_cur = cur;
259 g_p_log_buf_sdt_end = end;
260 return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
261 }
262 cur += hdr->length;
263 }
264 return LOG_BUF_RET_OK;
265 }
266
log_buffer_check(void)267 uint8_t log_buffer_check(void)
268 {
269 uint8_t *beg = (uint8_t *)(g_log_buffer_start + g_log_section_control->read);
270 uint8_t *end = (uint8_t *)(g_log_buffer_start + g_log_section_control->write);
271
272 if (beg == end) {
273 return 0;
274 } else if (beg < end) {
275 return log_buffer_check_rlw(beg, end);
276 } else {
277 return log_buffer_check_rgw(beg, end);
278 }
279 }
280 #endif
281
282 /*
283 * Public function definitions
284 */
log_buffer_init(log_memory_region_section_t logsec)285 void log_buffer_init(log_memory_region_section_t logsec)
286 {
287 /* Init the buffer limits */
288 log_memory_section_params_t ms_params;
289 log_memory_section_get(logsec, &ms_params);
290 if (pointer_in_log_memory_region((uintptr_t)ms_params.start) &&
291 pointer_in_log_memory_region((uint32_t)((uintptr_t)ms_params.start) + ms_params.length - 1)) {
292 g_log_buffer_start = ms_params.start; // first element
293 g_log_buffer_size = ms_params.length; // buffer size
294
295 g_log_section_control = log_memory_section_get_control(logsec);
296 } else {
297 panic(PANIC_LOG, __LINE__);
298 }
299 }
300
log_buffer_get_available_for_next_message(uint32_t * av)301 log_ret_t log_buffer_get_available_for_next_message(uint32_t *av)
302 {
303 log_ret_t ret_val;
304 uint32_t available = 0;
305
306 ret_val = log_buffer_get_available(&available);
307 if (ret_val == LOG_RET_OK) {
308 if (available <= sizeof(log_buffer_header_t)) {
309 *av = 0;
310 } else {
311 *av = available - (uint32_t)sizeof(log_buffer_header_t);
312 }
313 }
314 return ret_val;
315 }
316
317 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
318 #include "log_trigger.h"
319
compress_log_write(const uint8_t * data,uint32_t length)320 log_ret_t compress_log_write(const uint8_t *data, uint32_t length)
321 {
322 uint32_t available;
323 log_ret_t ret_val;
324 bool trigger_flag = false;
325
326 // Check the message length is as much the buffer size
327 if ((data == NULL) || (length > (g_log_buffer_size - 1))) {
328 return LOG_RET_ERROR_IN_PARAMETERS;
329 }
330
331 uint32_t irq = osal_irq_lock();
332 available = 0;
333 // if it fits in the buffer add it
334 ret_val = log_buffer_get_available(&available);
335 if (ret_val == LOG_RET_OK) {
336 if (available > length) {
337 // Get the read and write indexes
338 uint32_t l_read_i = g_log_section_control->read;
339 uint32_t l_write_i = g_log_section_control->write;
340
341 // Add the buffer & update g_log_section_control->write
342 log_buffer_helper_add(data, length);
343 // get the new write index
344 uint32_t new_write_index = g_log_section_control->write;
345 if (!((l_write_i < l_read_i) || ((new_write_index > l_write_i) || (new_write_index < l_read_i)))) {
346 osal_irq_restore(irq);
347 panic(PANIC_LOG, __LINE__);
348 return LOG_RET_ERROR_OVERFLOW;
349 }
350 if (!((l_write_i >= l_read_i) || (new_write_index < l_read_i))) {
351 osal_irq_restore(irq);
352 panic(PANIC_LOG, __LINE__);
353
354 return LOG_RET_ERROR_OVERFLOW;
355 }
356 if (available >= g_log_buffer_size) {
357 osal_irq_restore(irq);
358 panic(PANIC_LOG, __LINE__);
359 return LOG_RET_ERROR_OVERFLOW;
360 }
361 } else {
362 ret_val = LOG_RET_ERROR_NOT_ENOUGH_SPACE;
363 }
364 if ((g_log_buffer_size - available) > COMPRESS_LOG_TRIGGER_THRESHOLD) {
365 trigger_flag = true;
366 }
367 }
368 osal_irq_restore(irq);
369
370 if (trigger_flag) {
371 log_trigger();
372 }
373 return ret_val;
374 }
375 #endif /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES */
376
377 #ifdef BUILD_APPLICATION_STANDARD
378
379 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
380 static uint32_t g_mass_share_mem_size;
381 static uint32_t g_mass_share_mem_start;
382 #if (BTH_WITH_SMART_WEAR == NO) && defined(SUPPORT_IPC)
383 #include "ipc.h"
384 static uint32_t g_version_number;
mass_receive_remote_info(ipc_action_t message,const volatile ipc_payload * payload,cores_t src,uint32_t id)385 static bool mass_receive_remote_info(ipc_action_t message, const volatile ipc_payload *payload,
386 cores_t src, uint32_t id)
387 {
388 UNUSED(message);
389 UNUSED(src);
390 UNUSED(id);
391
392 if (payload != NULL) {
393 g_version_number = *(uint32_t *)(uintptr_t)payload;
394 }
395 return true;
396 }
397 #endif
398
mass_buffer_init(mass_data_memory_region_section_t sec)399 void mass_buffer_init(mass_data_memory_region_section_t sec)
400 {
401 if (sec != MASS_MEMORY_REGION_SECTION_0 && sec != MASS_MEMORY_REGION_SECTION_1) {
402 return;
403 }
404 massdata_memory_region_control_t *mass_ctrl = (massdata_memory_region_control_t *)(uintptr_t)MASSDATA_REGION_START;
405 g_mass_section_control = &(mass_ctrl->section_control[sec]);
406
407 g_mass_share_mem_start = g_mass_section_control->region_start;
408 g_mass_share_mem_size = g_mass_section_control->region_len;
409 g_mass_section_control->water_line = g_mass_share_mem_size / CHR_BUFFER_WL_RATIO;
410 #if (BTH_WITH_SMART_WEAR == NO)
411 ipc_register_handler(IPC_ACTION_MASS_DATA_INFORM, mass_receive_remote_info);
412 #endif
413 }
414 #endif
415
416 #if (BTH_WITH_SMART_WEAR == YES) && defined(SUPPORT_IPC)
417 #include "ipc.h"
418 #include "ipc_actions.h"
419
massdata_record_system_error(uint8_t event_id,uint8_t info1,uint8_t info2,uint8_t info3)420 void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint8_t info3)
421 {
422 #if (CORE == BT)
423 ipc_payload_mass_data_type chr_info;
424 chr_info.type = MASS_ERROR_POINT;
425 chr_info.event_id = event_id;
426 chr_info.info1 = info1;
427 chr_info.info2 = info2;
428 chr_info.info3 = info3;
429
430 (void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
431 IPC_ACTION_MASS_DATA_INFORM,
432 (ipc_payload *)((void *)&chr_info),
433 sizeof(chr_info),
434 IPC_PRIORITY_LOWEST,
435 false,
436 0);
437 #else
438 UNUSED(event_id);
439 UNUSED(info1);
440 UNUSED(info2);
441 UNUSED(info3);
442 #endif
443 }
444
massdata_record_system_event(uint8_t event_id,uint8_t info1,uint8_t info2,uint8_t info3)445 void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint8_t info3)
446 {
447 #if (CORE == BT)
448 ipc_payload_mass_data_type chr_info;
449 chr_info.type = MASS_EVENT_POINT;
450 chr_info.event_id = event_id;
451 chr_info.info1 = info1;
452 chr_info.info2 = info2;
453 chr_info.info3 = info3;
454
455 (void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
456 IPC_ACTION_MASS_DATA_INFORM,
457 (ipc_payload *)((void *)&chr_info),
458 sizeof(chr_info),
459 IPC_PRIORITY_LOWEST,
460 false,
461 0);
462 #else
463 UNUSED(event_id);
464 UNUSED(info1);
465 UNUSED(info2);
466 UNUSED(info3);
467 #endif
468 }
469
massdata_record_system_info_with_extend(chr_extend_data_t * extend_data)470 void massdata_record_system_info_with_extend(chr_extend_data_t *extend_data)
471 {
472 if ((extend_data == NULL) ||
473 (extend_data->type != MASS_EVENT_POINT_EXTEND && extend_data->type != MASS_ERROR_POINT_EXTEND)) {
474 panic(PANIC_LOG, MASS_EVENT_POINT_EXTEND);
475 return ;
476 }
477 ipc_payload_mass_data_extend_type chr_data = { 0 };
478 chr_data.mass_data.type = extend_data->type;
479 chr_data.mass_data.event_id = extend_data->event_id;
480 chr_data.mass_data.info1 = extend_data->info1;
481 chr_data.mass_data.info2 = extend_data->info2;
482 chr_data.mass_data.info3 = extend_data->info3;
483 chr_data.data_len = extend_data->data_len;
484 if (memcpy_s(chr_data.data, CHR_EXTEND_PARAM_MAX_LEN, extend_data->data, extend_data->data_len) != EOK) {
485 panic(PANIC_LOG, __LINE__);
486 return ;
487 }
488
489 (void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
490 IPC_ACTION_MASS_DATA_INFORM_WITH_EXTEND,
491 (ipc_payload *)((void *)&chr_data),
492 sizeof(ipc_payload_mass_data_extend_type),
493 IPC_PRIORITY_LOWEST,
494 false,
495 0);
496 }
497
498 #else
499 #include "log_trigger.h"
500 #include "systick.h"
501 #include "log_printf.h"
502
503 #define TWS_MASSDATA_MAGIC_NUMBER 0xAA
504
505 #if (CORE == APPS)
506 #if (ENABLE_MASSDATA_RECORD == YES)
507 static uint32_t g_version_number;
508 #endif
chr_record_ue(uint8_t eid,uint8_t sub_eid,uint8_t code,uint32_t sub_code)509 void chr_record_ue(uint8_t eid, uint8_t sub_eid, uint8_t code, uint32_t sub_code)
510 {
511 #if (ENABLE_MASSDATA_RECORD == YES)
512 #define MS_PER_SECOND 1000
513 uint32_t ret;
514 size_t size;
515 uint8_t eid_shift = 8;
516
517 system_event_s_t ue_point;
518 ue_point.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
519 ue_point.event_id = (0xFFFF & ((eid << eid_shift) | (sub_eid)));
520 ue_point.event_info = code;
521 ue_point.sub_event_info = sub_code;
522 ue_point.chr_up_type = CHR_UE_JSON;
523 ue_point.version = g_version_number;
524 ue_point.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
525
526 size = sizeof(system_event_s_t);
527 ret = mass_data_write_roll_buffer((uint8_t *)&ue_point, (uint32_t)size);
528 if ((ret == MASS_OVER_BUFFER_THD) || (ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE)) {
529 massdata_triger_queue((uint8_t *)&ue_point, MASS_EVENT_POINT);
530 }
531 #undef MS_PER_SECOND
532 #else
533 UNUSED(eid);
534 UNUSED(sub_eid);
535 UNUSED(code);
536 UNUSED(sub_code);
537 #endif
538 }
539
massdata_triger_queue(const uint8_t * pay_i,uint32_t type)540 uint32_t massdata_triger_queue(const uint8_t *pay_i, uint32_t type)
541 {
542 UNUSED(pay_i);
543 UNUSED(type);
544 return 0;
545 }
546
massdata_record_system_error(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)547 void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
548 {
549 #if (ENABLE_MASSDATA_RECORD == YES)
550 #define MS_PER_SECOND 1000
551 uint32_t ret;
552 size_t size;
553
554 system_error_s_t error_seg;
555 error_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
556 error_seg.event_id = get_event_id(event_id, info1);
557 error_seg.event_info = info2;
558 error_seg.sub_event_info = info3;
559 error_seg.chr_up_type = CHR_DFT;
560 error_seg.version = g_version_number;
561 error_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
562
563 size = sizeof(system_error_s_t);
564 ret = mass_data_write_roll_buffer((uint8_t *)&error_seg, (uint32_t)size);
565 if ((ret == MASS_OVER_BUFFER_THD) || (ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE)) {
566 massdata_triger_queue((uint8_t *)&error_seg, MASS_EVENT_POINT);
567 }
568 #undef MS_PER_SECOND
569 return;
570 #else
571 UNUSED(event_id);
572 UNUSED(info1);
573 UNUSED(info2);
574 UNUSED(info3);
575 #endif
576 }
577
578
massdata_record_system_event(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)579 void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
580 {
581 #if (ENABLE_MASSDATA_RECORD == YES)
582 #define MS_PER_SECOND 1000
583 uint32_t ret;
584 system_event_s_t event_seg;
585 size_t size;
586
587 event_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
588 event_seg.event_id = get_event_id(event_id, info1);
589 event_seg.event_info = info2;
590 event_seg.sub_event_info = info3;
591 event_seg.chr_up_type = CHR_DFT;
592 event_seg.version = g_version_number;
593 event_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
594
595 size = sizeof(system_event_s_t);
596
597 ret = mass_data_write_roll_buffer((uint8_t *)&event_seg, (uint32_t)size);
598 if (ret == MASS_OVER_BUFFER_THD || ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE) {
599 massdata_triger_queue((uint8_t *)&event_seg, MASS_EVENT_POINT);
600 }
601 #undef MS_PER_SECOND
602 return;
603 #else
604 UNUSED(event_id);
605 UNUSED(info1);
606 UNUSED(info2);
607 UNUSED(info3);
608 #endif
609 }
610
611 #elif (CORE == BT)
612 static uint8_t g_role_state;
613 static uint32_t g_mass_write_psn = 0;
614
massdata_set_role(uint8_t role)615 void massdata_set_role(uint8_t role)
616 {
617 g_role_state = role;
618 }
619
chr_record_ue(uint8_t eid,uint8_t sub_eid,uint8_t code,uint32_t sub_code)620 void chr_record_ue(uint8_t eid, uint8_t sub_eid, uint8_t code, uint32_t sub_code)
621 {
622 #define MS_PER_SECOND 1000
623 uint32_t ret;
624 uint32_t size;
625 uint8_t eid_shift = 8;
626
627 system_event_s_t ue_point;
628 ue_point.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
629 ue_point.event_id = (0xFFFF & ((eid << eid_shift) | (sub_eid)));
630 ue_point.event_info = code;
631 ue_point.sub_event_info = (uint32_t)sub_code;
632 ue_point.chr_up_type = CHR_UE_JSON;
633 ue_point.version = g_version_number;
634 ue_point.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
635 ue_point.role = g_role_state;
636
637 uint32_t irq = osal_irq_lock();
638 ue_point.psn = g_mass_write_psn++;
639 osal_irq_restore(irq);
640
641 size = sizeof(system_event_s_t);
642 ret = mass_data_write_roll_buffer((uint8_t *)&ue_point, size);
643 if (ret == MASS_OVER_BUFFER_THD) {
644 massdata_trigger((void *)&ue_point, CORE, MASS_EVENT_POINT);
645 }
646
647 #undef MS_PER_SECOND
648 }
649
massdata_record_system_error(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)650 void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
651 {
652 #define MS_PER_SECOND 1000
653 uint32_t ret;
654 uint32_t size;
655
656 system_error_s_t error_seg;
657 error_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
658 error_seg.event_id = get_event_id(event_id, info1);
659 error_seg.event_info = info2;
660 error_seg.sub_event_info = (uint32_t)info3;
661 error_seg.chr_up_type = CHR_DFT;
662 error_seg.version = g_version_number;
663 error_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
664 error_seg.role = g_role_state;
665
666 uint32_t irq = osal_irq_lock();
667 error_seg.psn = g_mass_write_psn++;
668 osal_irq_restore(irq);
669
670 size = sizeof(system_error_s_t);
671 ret = mass_data_write_roll_buffer((uint8_t *)&error_seg, size);
672 if (ret == MASS_OVER_BUFFER_THD) {
673 massdata_trigger((void *)&error_seg, CORE, MASS_EVENT_POINT);
674 }
675
676 #undef MS_PER_SECOND
677
678 return;
679 }
680
681
massdata_record_system_event(uint8_t event_id,uint8_t info1,uint8_t info2,uint32_t info3)682 void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
683 {
684 #define MS_PER_SECOND 1000
685 uint32_t ret;
686 uint16_t size;
687
688 system_event_s_t event_seg;
689 event_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
690 event_seg.event_id = get_event_id(event_id, info1);
691 event_seg.event_info = info2;
692 event_seg.sub_event_info = (uint32_t)info3;
693 event_seg.chr_up_type = CHR_DFT;
694 event_seg.version = g_version_number;
695 event_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
696 event_seg.role = g_role_state;
697
698 uint32_t irq = osal_irq_lock();
699 event_seg.psn = g_mass_write_psn++;
700 osal_irq_restore(irq);
701
702 size = sizeof(system_event_s_t);
703
704 ret = mass_data_write_roll_buffer((uint8_t *)&event_seg, size);
705 if (ret == MASS_OVER_BUFFER_THD) {
706 massdata_trigger((void *)&event_seg, CORE, MASS_EVENT_POINT);
707 }
708
709 #undef MS_PER_SECOND
710 return;
711 }
712
713 #endif
714 #endif
715
716 // write mass data to share mem roll buffer, index by core type
717 #if (ENABLE_MASSDATA_RECORD == YES)
mass_data_write_roll_buffer(const uint8_t * data,uint32_t length)718 uint32_t mass_data_write_roll_buffer(const uint8_t *data, uint32_t length)
719 {
720 uint32_t remain_size, to_end, read, write, size, water_line;
721 errno_t ret;
722
723 // check the message length is as much the buffer size
724 if ((data == NULL) || (g_mass_section_control == NULL)) { return MASS_RET_ERROR_IN_PARAMETERS; }
725
726 uint32_t irq = osal_irq_lock();
727 read = g_mass_section_control->read;
728 write = g_mass_section_control->write;
729 size = g_mass_section_control->region_len;
730 to_end = size - write;
731
732 // check if mem overflow
733 if ((read > g_mass_share_mem_size) || (write > g_mass_share_mem_size) || (size > g_mass_share_mem_size) ||
734 (g_mass_section_control->region_start != g_mass_share_mem_start)) {
735 // recorvy mem offset
736 g_mass_section_control->read = 0;
737 g_mass_section_control->write = 0;
738 g_mass_section_control->region_start = g_mass_share_mem_start;
739 g_mass_section_control->region_len = g_mass_share_mem_size;
740 osal_irq_restore(irq);
741 return MASS_RET_ERROR_CORRUPT_SHARED_MEMORY;
742 }
743
744 remain_size = (read <= write) ? (size - (write - read + 1)) : (read - write - 1);
745 water_line = g_mass_section_control->water_line;
746
747 if (remain_size < length) {
748 osal_irq_restore(irq);
749 return MASS_RET_ERROR_NOT_ENOUGH_SPACE;
750 }
751
752 if (length <= to_end) {
753 ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start + write)), to_end, data, length);
754 if (ret != EOK) {
755 osal_irq_restore(irq);
756 return MASS_MEM_COPY_FAIL;
757 }
758 } else {
759 ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start + write)), to_end, data, to_end);
760 if (ret != EOK) {
761 osal_irq_restore(irq);
762 return MASS_MEM_COPY_FAIL;
763 }
764 ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start)),
765 length - to_end, data + to_end, length - to_end);
766 if (ret != EOK) {
767 osal_irq_restore(irq);
768 return MASS_MEM_COPY_FAIL;
769 }
770 }
771
772 write = (write + length) % size;
773
774 g_mass_section_control->write = write;
775
776 osal_irq_restore(irq);
777
778 if (remain_size < water_line) { return MASS_OVER_BUFFER_THD; }
779
780 return MASS_RET_OK;
781 }
782
log_buffer_record_system_event(uint32_t chr_event)783 void log_buffer_record_system_event(uint32_t chr_event)
784 {
785 if (chr_event == CHR_VALUE_NULL) {
786 return;
787 }
788
789 uint8_t event_id;
790 uint8_t info1;
791 uint8_t info2;
792 uint8_t info3;
793
794 event_id = (chr_event >> CHR_VALUE_SHFIT_24BIT) & CHR_VALUE_MASK;
795 info1 = (chr_event >> CHR_INFO1_SHFIT_16BIT) & CHR_VALUE_MASK;
796 info2 = (chr_event >> CHR_INFO2_SHFIT_8BIT) & CHR_VALUE_MASK;
797 info3 = chr_event & CHR_VALUE_MASK;
798
799 massdata_record_system_event(event_id, info1, info2, info3);
800 }
801
log_buffer_record_system_error(uint32_t chr_error)802 void log_buffer_record_system_error(uint32_t chr_error)
803 {
804 if (chr_error == CHR_VALUE_NULL) {
805 return;
806 }
807
808 uint8_t error_id;
809 uint8_t info1;
810 uint8_t info2;
811 uint8_t info3;
812
813 error_id = (chr_error >> CHR_VALUE_SHFIT_24BIT) & CHR_VALUE_MASK;
814 info1 = (chr_error >> CHR_INFO1_SHFIT_16BIT) & CHR_VALUE_MASK;
815 info2 = (chr_error >> CHR_INFO2_SHFIT_8BIT) & CHR_VALUE_MASK;
816 info3 = chr_error & CHR_VALUE_MASK;
817
818 massdata_record_system_error(error_id, info1, info2, info3);
819 }
820 #endif
821 #endif
822