mcu_hi3321_watch/middleware/utils/dfx/log_buffer/log_buffer.c
2025-05-26 20:15:20 +08:00

802 lines
25 KiB
C

/*
* Copyright (c) @CompanyNameMagicTag 2018-2020. All rights reserved.
* Description: LOG BUFFER MODULE.
* Author: @CompanyNameTag
* Create: 2018-10-15
*/
#include "securec.h"
#include "non_os.h"
#include "panic.h"
#include "log_buffer.h"
/*
* Private definitions
*/
#define index_in_cbuff(x) ((x) < g_log_buffer_size)
/*
* Private variables
*/
static uint8_t *g_log_buffer_start;
static uint32_t g_log_buffer_size;
static volatile log_memory_section_control_t *g_log_section_control;
volatile massdata_memory_section_control_t *g_mass_section_control = NULL;
/**
* Read an index with overflow.
* @param index_in index in the limits of the circular buffer or up to buffer_size longer
* @return index in the circular buffer limits
*/
static uint32_t circled_index(uint32_t index_in)
{
uint32_t index_out;
if (index_in < g_log_buffer_size) {
index_out = index_in;
} else {
index_out = index_in - g_log_buffer_size;
}
if (!index_in_cbuff(index_out)) {
panic(PANIC_LOG, __LINE__);
return 0;
}
return index_out;
}
static uint32_t log_buffer_get_used(uint32_t read_i, uint32_t write_i)
{
uint32_t in_use;
/* Check how much space is used. Use -1 to ensure the g_log_section_control->write ==
* g_log_section_control->read means the buffer is EMPTY.
* Without the -1, the g_log_section_control->write COULD wrap and catch up with g_log_section_control->read. */
if (read_i <= write_i) {
in_use = write_i - read_i;
} else {
/* g_log_section_control->write has wrapped, but g_log_section_control->read has not yet. */
in_use = (g_log_buffer_size - read_i) + write_i;
}
return in_use;
}
/**
* Get the available space in the buffer
* @param av if return is LOG_RET_OK the available data will be stored in the pointer given
* @return LOG_RET_OK or an error value
*/
static inline log_ret_t log_buffer_get_available(uint32_t *av)
{
uint32_t l_read_i = g_log_section_control->read;
uint32_t l_write_i = g_log_section_control->write;
/* Check how much space is available. Use -1 to ensure the g_log_section_control->write ==
* g_log_section_control->read means the buffer is EMPTY.
* Without the -1, the g_log_section_control->write COULD wrap and catch up with g_log_section_control->read. */
if (!index_in_cbuff(l_read_i) || !index_in_cbuff(l_write_i)) { return LOG_RET_ERROR_CORRUPT_SHARED_MEMORY; }
if (l_read_i <= l_write_i) {
// l_read_i and l_write_i has been checked to be in safe boundaries.
*av = (g_log_buffer_size - 1u) - (l_write_i - l_read_i);
/* g_log_section_control->write has wrapped, but g_log_section_control->read has not yet. */
// l_read_i and l_write_i has been checked to be in safe boundaries.
} else { *av = (l_read_i - l_write_i) - 1u; }
return LOG_RET_OK;
}
/**
* Add data to the circular buffer with updating the write index.
* @param data buffer with the data to store
* @param data_len data length in bytes
*/
static void log_buffer_helper_add(const uint8_t *data, const uint32_t data_len)
{
errno_t sec_ret;
uint32_t l_write = g_log_section_control->write;
size_t to_end = g_log_buffer_size - l_write;
if (to_end >= data_len) {
/* Entire message fits. */
sec_ret = memcpy_s((void *)(g_log_buffer_start + l_write), to_end, data, data_len);
} else {
/* Message needs to be segmented. Write to end of buffer and then the remainder from the beginning. */
sec_ret = memcpy_s((void *)(g_log_buffer_start + l_write), to_end, data, to_end);
if (sec_ret != EOK) {
return;
}
sec_ret = memcpy_s((void *)g_log_buffer_start, g_log_section_control->read, &data[to_end], data_len - to_end);
}
if (sec_ret != EOK) {
return;
}
g_log_section_control->write = circled_index(l_write + data_len);
}
/**
* Scatter gather write to log_buffer.
* @param length array of lengths for the different buffers, it admits 0 as a value of one of them
* @param buffer array of values containig the buffers to the data to save in the log buffer
* @param was_empty if a pointer != NULL is given it will store a return value
* indicating the buffer was empty when the write was done.
* @return LOG_RET_OK or an error value
*/
void log_buffer_write(const log_buffer_header_t *lb_header, const uint8_t *buffer, bool *was_empty)
{
uint32_t l_read_i;
uint32_t l_write_i;
// Add the header
log_buffer_helper_add((const uint8_t *)lb_header, sizeof(log_buffer_header_t));
// Add the buffer
log_buffer_helper_add(buffer, lb_header->length - sizeof(log_buffer_header_t));
l_read_i = g_log_section_control->read;
l_write_i = g_log_section_control->write;
*was_empty = (log_buffer_get_used(l_read_i, l_write_i) <= lb_header->length);
}
#ifdef FEATURE_PLT_LB_CHECK
uint8_t *g_p_log_buf_sdt_cur = NULL;
uint8_t *g_p_log_buf_sdt_beg = NULL;
uint8_t *g_p_log_buf_sdt_end = NULL;
static uint8_t log_buffer_check_rlw(uint8_t *beg, uint8_t *end)
{
uint8_t *cur = NULL;
log_buffer_header_t *hdr = NULL;
if ((beg == NULL) || (end == NULL)) {
return 0xFF;
}
if (beg >= end) {
return 0xFE;
}
cur = beg;
while (cur < end) {
hdr = (log_buffer_header_t *)(cur);
if (!lb_magic_check(hdr)) {
g_p_log_buf_sdt_beg = beg;
g_p_log_buf_sdt_cur = cur;
g_p_log_buf_sdt_end = end;
return LOG_BUF_RLW_MAGIC_ERROR;
}
cur += hdr->length;
}
return LOG_BUF_RET_OK;
}
#define MAX_ONE_LOG_CPY_LENGTH 100
#define G_LB_BUF_LEN 200
static uint8_t g_lb_buf[G_LB_BUF_LEN] = { 0 };
static uint8_t log_buffer_check_last_one(uint8_t **beg, uint8_t *end, uint8_t **cur, log_buffer_header_t *hdr)
{
uint32_t last_len = end - (*cur);
uint8_t *buf = g_lb_buf;
memset_s(buf, sizeof(g_lb_buf), 0, G_LB_BUF_LEN);
if (memcpy_s(buf, sizeof(g_lb_buf), *cur, last_len) != EOK) {
return LOG_RET_MEMCPY_ERROR;
}
*beg = (uint8_t *)(g_log_buffer_start);
if (memcpy_s(buf + last_len, sizeof(g_lb_buf) - last_len, *beg, MAX_ONE_LOG_CPY_LENGTH) != EOK) {
return LOG_RET_MEMCPY_ERROR;
}
hdr = (log_buffer_header_t *)(buf);
/* magic check */
if (!lb_magic_check(hdr)) {
g_p_log_buf_sdt_beg = *beg;
g_p_log_buf_sdt_cur = *cur;
g_p_log_buf_sdt_end = end;
return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
}
*cur = (*beg) + ((log_buffer_header_t)(*hdr)).length - last_len;
return LOG_BUF_RET_OK;
}
static uint8_t log_buffer_check_rgw(uint8_t *ori_beg, uint8_t *ori_end)
{
uint8_t *beg = ori_beg;
uint8_t *end = ori_end;
uint8_t *cur = NULL;
log_buffer_header_t *hdr = NULL;
uint8_t last_one = 0;
if ((beg == NULL) || (end == NULL)) { return 0xFF; }
if (beg <= end) { return 0xFE; }
cur = beg;
end = (uint8_t *)(g_log_buffer_start + g_log_buffer_size);
while (cur < end) {
if ((cur + sizeof(log_buffer_header_t)) >= end) { // judge last one
last_one = 1;
break;
}
hdr = (log_buffer_header_t *)(cur);
if ((cur + hdr->length) > end) {
last_one = 1;
break;
}
if (!lb_magic_check(hdr)) { // magic check
g_p_log_buf_sdt_beg = beg;
g_p_log_buf_sdt_cur = cur;
g_p_log_buf_sdt_end = end;
return LOG_RET_RGW_TOEND_MAGIC_ERROR;
}
if ((cur + hdr->length) == end) { // to end
cur = (uint8_t *)(g_log_buffer_start);
break;
}
cur += hdr->length;
}
if (last_one && log_buffer_check_last_one(&beg, end, &cur, hdr) == LOG_RET_RGW_LASTONE_MAGIC_ERROR) { // last one
return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
}
end = ori_end; // from head
while (cur < end) {
hdr = (log_buffer_header_t *)(cur);
if (!lb_magic_check(hdr)) { // magic check
g_p_log_buf_sdt_beg = beg;
g_p_log_buf_sdt_cur = cur;
g_p_log_buf_sdt_end = end;
return LOG_RET_RGW_LASTONE_MAGIC_ERROR;
}
cur += hdr->length;
}
return LOG_BUF_RET_OK;
}
uint8_t log_buffer_check(void)
{
uint8_t *beg = (uint8_t *)(g_log_buffer_start + g_log_section_control->read);
uint8_t *end = (uint8_t *)(g_log_buffer_start + g_log_section_control->write);
if (beg == end) {
return 0;
} else if (beg < end) {
return log_buffer_check_rlw(beg, end);
} else {
return log_buffer_check_rgw(beg, end);
}
}
#endif
/*
* Public function definitions
*/
void log_buffer_init(log_memory_region_section_t logsec)
{
/* Init the buffer limits */
log_memory_section_params_t ms_params;
log_memory_section_get(logsec, &ms_params);
if (pointer_in_log_memory_region((uintptr_t)ms_params.start) &&
pointer_in_log_memory_region((uint32_t)((uintptr_t)ms_params.start) + ms_params.length - 1)) {
g_log_buffer_start = ms_params.start; // first element
g_log_buffer_size = ms_params.length; // buffer size
g_log_section_control = log_memory_section_get_control(logsec);
} else {
panic(PANIC_LOG, __LINE__);
}
}
log_ret_t log_buffer_get_available_for_next_message(uint32_t *av)
{
log_ret_t ret_val;
uint32_t available = 0;
ret_val = log_buffer_get_available(&available);
if (ret_val == LOG_RET_OK) {
if (available <= sizeof(log_buffer_header_t)) {
*av = 0;
} else {
*av = available - (uint32_t)sizeof(log_buffer_header_t);
}
}
return ret_val;
}
#if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
#include "log_trigger.h"
log_ret_t compress_log_write(const uint8_t *data, uint32_t length)
{
uint32_t available;
log_ret_t ret_val;
bool trigger_flag = false;
// Check the message length is as much the buffer size
if ((data == NULL) || (length > (g_log_buffer_size - 1))) {
return LOG_RET_ERROR_IN_PARAMETERS;
}
non_os_enter_critical();
available = 0;
// if it fits in the buffer add it
ret_val = log_buffer_get_available(&available);
if (ret_val == LOG_RET_OK) {
if (available > length) {
// Get the read and write indexes
uint32_t l_read_i = g_log_section_control->read;
uint32_t l_write_i = g_log_section_control->write;
// Add the buffer & update g_log_section_control->write
log_buffer_helper_add(data, length);
// get the new write index
uint32_t new_write_index = g_log_section_control->write;
if (!((l_write_i < l_read_i) || ((new_write_index > l_write_i) || (new_write_index < l_read_i)))) {
non_os_exit_critical();
panic(PANIC_LOG, __LINE__);
return LOG_RET_ERROR_OVERFLOW;
}
if (!((l_write_i >= l_read_i) || (new_write_index < l_read_i))) {
non_os_exit_critical();
panic(PANIC_LOG, __LINE__);
return LOG_RET_ERROR_OVERFLOW;
}
if (available >= g_log_buffer_size) {
non_os_exit_critical();
panic(PANIC_LOG, __LINE__);
return LOG_RET_ERROR_OVERFLOW;
}
} else {
ret_val = LOG_RET_ERROR_NOT_ENOUGH_SPACE;
}
if ((g_log_buffer_size - available) > COMPRESS_LOG_TRIGGER_THRESHOLD) {
trigger_flag = true;
}
}
non_os_exit_critical();
if (trigger_flag) {
log_trigger();
}
return ret_val;
}
#endif /* USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES */
#ifdef BUILD_APPLICATION_STANDARD
static uint32_t g_mass_share_mem_size;
static uint32_t g_mass_share_mem_start;
#if (BTH_WITH_SMART_WEAR == NO) && defined(SUPPORT_IPC)
#include "ipc.h"
static uint32_t g_version_number;
static bool mass_receive_remote_info(ipc_action_t message, const volatile ipc_payload *payload,
cores_t src, uint32_t id)
{
UNUSED(message);
UNUSED(src);
UNUSED(id);
if (payload != NULL) {
g_version_number = *(uint32_t *)(uintptr_t)payload;
}
return true;
}
#endif
#if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
void mass_buffer_init(mass_data_memory_region_section_t sec)
{
if (sec != MASS_MEMORY_REGION_SECTION_0 && sec != MASS_MEMORY_REGION_SECTION_1) {
return;
}
massdata_memory_region_control_t *mass_ctrl = (massdata_memory_region_control_t *)(uintptr_t)MASSDATA_REGION_START;
g_mass_section_control = &(mass_ctrl->section_control[sec]);
g_mass_share_mem_start = g_mass_section_control->region_start;
g_mass_share_mem_size = g_mass_section_control->region_len;
g_mass_section_control->water_line = g_mass_share_mem_size / CHR_BUFFER_WL_RATIO;
#if (BTH_WITH_SMART_WEAR == NO)
ipc_register_handler(IPC_ACTION_MASS_DATA_INFORM, mass_receive_remote_info);
#endif
}
#endif
#if (BTH_WITH_SMART_WEAR == YES) && defined(SUPPORT_IPC)
#include "ipc.h"
#include "ipc_actions.h"
void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint8_t info3)
{
#if (CORE == BT)
ipc_payload_mass_data_type chr_info;
chr_info.type = MASS_ERROR_POINT;
chr_info.event_id = event_id;
chr_info.info1 = info1;
chr_info.info2 = info2;
chr_info.info3 = info3;
(void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
IPC_ACTION_MASS_DATA_INFORM,
(ipc_payload *)((void *)&chr_info),
sizeof(chr_info),
IPC_PRIORITY_LOWEST,
false,
0);
#else
UNUSED(event_id);
UNUSED(info1);
UNUSED(info2);
UNUSED(info3);
#endif
}
void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint8_t info3)
{
#if (CORE == BT)
ipc_payload_mass_data_type chr_info;
chr_info.type = MASS_EVENT_POINT;
chr_info.event_id = event_id;
chr_info.info1 = info1;
chr_info.info2 = info2;
chr_info.info3 = info3;
(void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
IPC_ACTION_MASS_DATA_INFORM,
(ipc_payload *)((void *)&chr_info),
sizeof(chr_info),
IPC_PRIORITY_LOWEST,
false,
0);
#else
UNUSED(event_id);
UNUSED(info1);
UNUSED(info2);
UNUSED(info3);
#endif
}
void massdata_record_system_info_with_extend(chr_extend_data_t *extend_data)
{
if ((extend_data == NULL) ||
(extend_data->type != MASS_EVENT_POINT_EXTEND && extend_data->type != MASS_ERROR_POINT_EXTEND)) {
panic(PANIC_LOG, MASS_EVENT_POINT_EXTEND);
return ;
}
ipc_payload_mass_data_extend_type chr_data = { 0 };
chr_data.mass_data.type = extend_data->type;
chr_data.mass_data.event_id = extend_data->event_id;
chr_data.mass_data.info1 = extend_data->info1;
chr_data.mass_data.info2 = extend_data->info2;
chr_data.mass_data.info3 = extend_data->info3;
chr_data.data_len = extend_data->data_len;
if (memcpy_s(chr_data.data, CHR_EXTEND_PARAM_MAX_LEN, extend_data->data, extend_data->data_len) != EOK) {
panic(PANIC_LOG, __LINE__);
return ;
}
(void)ipc_spin_send_message_timeout(CORES_APPS_CORE,
IPC_ACTION_MASS_DATA_INFORM_WITH_EXTEND,
(ipc_payload *)((void *)&chr_data),
sizeof(ipc_payload_mass_data_extend_type),
IPC_PRIORITY_LOWEST,
false,
0);
}
#else
#include "log_trigger.h"
#include "systick.h"
#include "log_printf.h"
#define TWS_MASSDATA_MAGIC_NUMBER 0xAA
#if (CORE == APPS)
static uint32_t g_version_number;
void chr_record_ue(uint8_t eid, uint8_t sub_eid, uint8_t code, uint32_t sub_code)
{
#define MS_PER_SECOND 1000
uint32_t ret;
size_t size;
uint8_t eid_shift = 8;
system_event_s_t ue_point;
ue_point.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
ue_point.event_id = (0xFFFF & ((eid << eid_shift) | (sub_eid)));
ue_point.event_info = code;
ue_point.sub_event_info = sub_code;
ue_point.chr_up_type = CHR_UE_JSON;
ue_point.version = g_version_number;
ue_point.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
size = sizeof(system_event_s_t);
ret = mass_data_write_roll_buffer((uint8_t *)&ue_point, (uint32_t)size);
if ((ret == MASS_OVER_BUFFER_THD) || (ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE)) {
massdata_triger_queue((uint8_t *)&ue_point, MASS_EVENT_POINT);
}
#undef MS_PER_SECOND
}
uint32_t massdata_triger_queue(const uint8_t *pay_i, uint32_t type)
{
UNUSED(pay_i);
UNUSED(type);
return 0;
}
void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
{
#define MS_PER_SECOND 1000
uint32_t ret;
size_t size;
system_error_s_t error_seg;
error_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
error_seg.event_id = get_event_id(event_id, info1);
error_seg.event_info = info2;
error_seg.sub_event_info = info3;
error_seg.chr_up_type = CHR_DFT;
error_seg.version = g_version_number;
error_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
size = sizeof(system_error_s_t);
ret = mass_data_write_roll_buffer((uint8_t *)&error_seg, (uint32_t)size);
if ((ret == MASS_OVER_BUFFER_THD) || (ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE)) {
massdata_triger_queue((uint8_t *)&error_seg, MASS_EVENT_POINT);
}
#undef MS_PER_SECOND
return;
}
void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
{
#define MS_PER_SECOND 1000
uint32_t ret;
system_event_s_t event_seg;
size_t size;
event_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
event_seg.event_id = get_event_id(event_id, info1);
event_seg.event_info = info2;
event_seg.sub_event_info = info3;
event_seg.chr_up_type = CHR_DFT;
event_seg.version = g_version_number;
event_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
size = sizeof(system_event_s_t);
ret = mass_data_write_roll_buffer((uint8_t *)&event_seg, (uint32_t)size);
if (ret == MASS_OVER_BUFFER_THD || ret == MASS_RET_ERROR_NOT_ENOUGH_SPACE) {
massdata_triger_queue((uint8_t *)&event_seg, MASS_EVENT_POINT);
}
#undef MS_PER_SECOND
return;
}
#elif (CORE == BT)
static uint8_t g_role_state;
static uint32_t g_mass_write_psn = 0;
void massdata_set_role(uint8_t role)
{
g_role_state = role;
}
void chr_record_ue(uint8_t eid, uint8_t sub_eid, uint8_t code, uint32_t sub_code)
{
#define MS_PER_SECOND 1000
uint32_t ret;
uint32_t size;
uint8_t eid_shift = 8;
system_event_s_t ue_point;
ue_point.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
ue_point.event_id = (0xFFFF & ((eid << eid_shift) | (sub_eid)));
ue_point.event_info = code;
ue_point.sub_event_info = (uint32_t)sub_code;
ue_point.chr_up_type = CHR_UE_JSON;
ue_point.version = g_version_number;
ue_point.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
ue_point.role = g_role_state;
non_os_enter_critical();
ue_point.psn = g_mass_write_psn++;
non_os_exit_critical();
size = sizeof(system_event_s_t);
ret = mass_data_write_roll_buffer((uint8_t *)&ue_point, size);
if (ret == MASS_OVER_BUFFER_THD) {
massdata_trigger((void *)&ue_point, CORE, MASS_EVENT_POINT);
}
#undef MS_PER_SECOND
}
void massdata_record_system_error(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
{
#define MS_PER_SECOND 1000
uint32_t ret;
uint32_t size;
system_error_s_t error_seg;
error_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
error_seg.event_id = get_event_id(event_id, info1);
error_seg.event_info = info2;
error_seg.sub_event_info = (uint32_t)info3;
error_seg.chr_up_type = CHR_DFT;
error_seg.version = g_version_number;
error_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
error_seg.role = g_role_state;
non_os_enter_critical();
error_seg.psn = g_mass_write_psn++;
non_os_exit_critical();
size = sizeof(system_error_s_t);
ret = mass_data_write_roll_buffer((uint8_t *)&error_seg, size);
if (ret == MASS_OVER_BUFFER_THD) {
massdata_trigger((void *)&error_seg, CORE, MASS_EVENT_POINT);
}
#undef MS_PER_SECOND
return;
}
void massdata_record_system_event(uint8_t event_id, uint8_t info1, uint8_t info2, uint32_t info3)
{
#define MS_PER_SECOND 1000
uint32_t ret;
uint16_t size;
system_event_s_t event_seg;
event_seg.time_stamp = (uint32_t)(uapi_systick_get_s() + get_chr_basegmt_s());
event_seg.event_id = get_event_id(event_id, info1);
event_seg.event_info = info2;
event_seg.sub_event_info = (uint32_t)info3;
event_seg.chr_up_type = CHR_DFT;
event_seg.version = g_version_number;
event_seg.magic_number = TWS_MASSDATA_MAGIC_NUMBER;
event_seg.role = g_role_state;
non_os_enter_critical();
event_seg.psn = g_mass_write_psn++;
non_os_exit_critical();
size = sizeof(system_event_s_t);
ret = mass_data_write_roll_buffer((uint8_t *)&event_seg, size);
if (ret == MASS_OVER_BUFFER_THD) {
massdata_trigger((void *)&event_seg, CORE, MASS_EVENT_POINT);
}
#undef MS_PER_SECOND
return;
}
#endif
#endif
// write mass data to share mem roll buffer, index by core type
uint32_t mass_data_write_roll_buffer(const uint8_t *data, uint32_t length)
{
uint32_t remain_size, to_end, read, write, size, water_line;
errno_t ret;
// check the message length is as much the buffer size
if ((data == NULL) || (g_mass_section_control == NULL)) { return MASS_RET_ERROR_IN_PARAMETERS; }
non_os_enter_critical();
read = g_mass_section_control->read;
write = g_mass_section_control->write;
size = g_mass_section_control->region_len;
to_end = size - write;
// check if mem overflow
if ((read > g_mass_share_mem_size) || (write > g_mass_share_mem_size) || (size > g_mass_share_mem_size) ||
(g_mass_section_control->region_start != g_mass_share_mem_start)) {
// recorvy mem offset
g_mass_section_control->read = 0;
g_mass_section_control->write = 0;
g_mass_section_control->region_start = g_mass_share_mem_start;
g_mass_section_control->region_len = g_mass_share_mem_size;
non_os_exit_critical();
return MASS_RET_ERROR_CORRUPT_SHARED_MEMORY;
}
remain_size = (read <= write) ? (size - (write - read + 1)) : (read - write - 1);
water_line = g_mass_section_control->water_line;
if (remain_size < length) {
non_os_exit_critical();
return MASS_RET_ERROR_NOT_ENOUGH_SPACE;
}
if (length <= to_end) {
ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start + write)), to_end, data, length);
if (ret != EOK) {
non_os_exit_critical();
return MASS_MEM_COPY_FAIL;
}
} else {
ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start + write)), to_end, data, to_end);
if (ret != EOK) {
non_os_exit_critical();
return MASS_MEM_COPY_FAIL;
}
ret = memcpy_s((void *)((uintptr_t)(g_mass_section_control->region_start)),
length - to_end, data + to_end, length - to_end);
if (ret != EOK) {
non_os_exit_critical();
return MASS_MEM_COPY_FAIL;
}
}
write = (write + length) % size;
g_mass_section_control->write = write;
non_os_exit_critical();
if (remain_size < water_line) { return MASS_OVER_BUFFER_THD; }
return MASS_RET_OK;
}
void log_buffer_record_system_event(uint32_t chr_event)
{
if (chr_event == CHR_VALUE_NULL) {
return;
}
uint8_t event_id;
uint8_t info1;
uint8_t info2;
uint8_t info3;
event_id = (chr_event >> CHR_VALUE_SHFIT_24BIT) & CHR_VALUE_MASK;
info1 = (chr_event >> CHR_INFO1_SHFIT_16BIT) & CHR_VALUE_MASK;
info2 = (chr_event >> CHR_INFO2_SHFIT_8BIT) & CHR_VALUE_MASK;
info3 = chr_event & CHR_VALUE_MASK;
#if (ENABLE_MASSDATA_RECORD == YES)
massdata_record_system_event(event_id, info1, info2, info3);
#else
UNUSED(event_id);
UNUSED(info1);
UNUSED(info2);
UNUSED(info3);
#endif
}
void log_buffer_record_system_error(uint32_t chr_error)
{
if (chr_error == CHR_VALUE_NULL) {
return;
}
uint8_t error_id;
uint8_t info1;
uint8_t info2;
uint8_t info3;
error_id = (chr_error >> CHR_VALUE_SHFIT_24BIT) & CHR_VALUE_MASK;
info1 = (chr_error >> CHR_INFO1_SHFIT_16BIT) & CHR_VALUE_MASK;
info2 = (chr_error >> CHR_INFO2_SHFIT_8BIT) & CHR_VALUE_MASK;
info3 = chr_error & CHR_VALUE_MASK;
#if (ENABLE_MASSDATA_RECORD == YES)
massdata_record_system_error(error_id, info1, info2, info3);
#else
UNUSED(error_id);
UNUSED(info1);
UNUSED(info2);
UNUSED(info3);
#endif
}
#endif