fun: Add common data structures and logging systems

This commit is contained in:
ShallowGreen123
2023-01-08 15:27:10 +08:00
parent 20843458b4
commit c824a039ef
15 changed files with 1171 additions and 609 deletions

View File

@@ -4,7 +4,8 @@
"gui_main_scr.h": "c",
"stdio.h": "c",
"gui_log.h": "c",
"lvgl.h": "c"
"lvgl.h": "c",
"lvgl_app.h": "c"
},
"C_Cpp.errorSquiggles": "Disabled"
}

View File

@@ -54,8 +54,11 @@
<ClCompile Include="LVGL.Simulator.cpp" />
<ClCompile Include="lvgl_mydemo\data\dataModel.c" />
<ClCompile Include="lvgl_mydemo\data\gui_scr_mgr.c" />
<ClCompile Include="lvgl_mydemo\lib\data_struct\linklist_malloc.c" />
<ClCompile Include="lvgl_mydemo\lib\data_struct\queue_malloc.c" />
<ClCompile Include="lvgl_mydemo\lib\data_struct\stack_malloc.c" />
<ClCompile Include="lvgl_mydemo\lib\drv_log.c" />
<ClCompile Include="lvgl_mydemo\lib\lib_log.c" />
<ClCompile Include="lvgl_mydemo\lib\lib_sys_log.c" />
<ClCompile Include="lvgl_mydemo\lvgl_app.c" />
<ClCompile Include="lvgl_mydemo\screen\gui_main_scr.c" />
<ClCompile Include="lvgl_mydemo\screen\gui_test1_scr.c" />

View File

@@ -45,7 +45,16 @@
<ClCompile Include="lvgl_mydemo\lib\drv_log.c">
<Filter>lvgl_mydemo\lib</Filter>
</ClCompile>
<ClCompile Include="lvgl_mydemo\lib\lib_log.c">
<ClCompile Include="lvgl_mydemo\lib\data_struct\linklist_malloc.c">
<Filter>lvgl_mydemo\lib\data_struct</Filter>
</ClCompile>
<ClCompile Include="lvgl_mydemo\lib\data_struct\queue_malloc.c">
<Filter>lvgl_mydemo\lib\data_struct</Filter>
</ClCompile>
<ClCompile Include="lvgl_mydemo\lib\data_struct\stack_malloc.c">
<Filter>lvgl_mydemo\lib\data_struct</Filter>
</ClCompile>
<ClCompile Include="lvgl_mydemo\lib\lib_sys_log.c">
<Filter>lvgl_mydemo\lib</Filter>
</ClCompile>
</ItemGroup>
@@ -83,5 +92,8 @@
<Filter Include="lvgl_mydemo\lib">
<UniqueIdentifier>{125c5bdc-13e9-45ed-bf0d-f844505c20ca}</UniqueIdentifier>
</Filter>
<Filter Include="lvgl_mydemo\lib\data_struct">
<UniqueIdentifier>{aff205ae-5bf7-43e9-af94-55de0a04480b}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,310 @@
#include "linklist_malloc.h"
#if DEF_TEST_MALLOC_LINKLIST
#include <string.h>
#endif
// define
#define DEF_NODE_P_SIZE (sizeof(_node_p_ *) + sizeof(_node_p_ *))
#define DEF_PREV_NODE_OFFS(ll_p) (ll_p->size)
#define DEF_NEXT_NODE_OFFS(ll_p) (ll_p->size + sizeof(_node_p_ *))
static void list_node_p_set_prev(linklist2_t *p, _node_p_ *act, _node_p_ *prev);
static void list_node_p_set_next(linklist2_t *p, _node_p_ *act, _node_p_ *next);
// doubel linklist code
void list_init_2(linklist2_t *p, uint32_t size) {
#ifdef DEF_BYTE_ALIGN_8
size = (size + 7) & (~0x7);
#else
size = (size + 3) & (~0x3);
#endif
p->head = NULL;
p->tail = NULL;
p->size = size;
}
void *list_ins_head_2(linklist2_t *list) {
_node_p_ *new_node = DEF_MALLOC(list->size + DEF_NODE_P_SIZE);
if (new_node == NULL) return NULL;
list_node_p_set_prev(list, new_node, NULL);
list_node_p_set_next(list, new_node, list->head);
if (list->head != NULL) {
list_node_p_set_prev(list, list->head, new_node);
}
list->head = new_node;
if (list->tail == NULL) {
list->tail = new_node;
}
return new_node;
}
void *list_ins_prev_2(linklist2_t *list, void *act) {
_node_p_ *new_node;
if (list == NULL || act == NULL) return NULL;
if (list_get_head_2(list) == act) {
new_node = list_ins_head_2(list);
if (new_node == NULL) return NULL;
} else {
new_node = DEF_MALLOC(list->size + DEF_NODE_P_SIZE);
if (new_node == NULL) return NULL;
_node_p_ *prev;
prev = list_get_prev_2(list, act);
list_node_p_set_next(list, prev, new_node);
list_node_p_set_prev(list, new_node, prev);
list_node_p_set_prev(list, act, new_node);
list_node_p_set_next(list, new_node, act);
}
return new_node;
}
void *list_ins_tail_2(linklist2_t *list) {
_node_p_ *new_node;
new_node = DEF_MALLOC(list->size + DEF_NODE_P_SIZE);
if (new_node == NULL) return NULL;
list_node_p_set_next(list, new_node, NULL);
list_node_p_set_prev(list, new_node, list->tail);
if (list->tail != NULL) {
list_node_p_set_next(list, list->tail, new_node);
}
list->tail = new_node;
if (list->head == NULL) {
list->head = new_node;
}
return new_node;
}
void list_remove_node_2(linklist2_t *list, void *node) {
if (node == NULL) return;
if (list_get_head_2(list) == node) {
list->head = list_get_next_2(list, node);
if (list->head == NULL) {
list->tail = NULL;
} else {
list_node_p_set_prev(list, list->head, NULL);
}
} else if (list_get_tail_2(list) == node) {
list->tail = list_get_prev_2(list, node);
if (list->tail == NULL) {
list->head = NULL;
} else {
list_node_p_set_next(list, list->tail, NULL);
}
} else {
_node_p_ *prev = list_get_prev_2(list, node);
_node_p_ *next = list_get_next_2(list, node);
list_node_p_set_next(list, prev, next);
list_node_p_set_prev(list, next, prev);
}
}
void list_clear_2(linklist2_t *list) {
void *i;
void *i_next;
i = list_get_head_2(list);
i_next = NULL;
while (i != NULL) {
i_next = list_get_next_2(list, i);
list_remove_node_2(list, i);
DEF_FREE(i);
i = i_next;
}
}
void list_chg_list_2(linklist2_t *ll_ori_p, linklist2_t *ll_new_p, void *node, bool head) {
list_remove_node_2(ll_ori_p, node);
if (head) {
list_node_p_set_prev(ll_new_p, node, NULL);
list_node_p_set_next(ll_new_p, node, ll_new_p->head);
if (ll_new_p != NULL) {
list_node_p_set_prev(ll_new_p, ll_new_p->head, node);
}
ll_new_p->head = node;
if (ll_new_p->tail == NULL) {
ll_new_p->tail = node;
}
} else {
// set node as tail
list_node_p_set_next(ll_new_p, node, NULL);
list_node_p_set_prev(ll_new_p, node, ll_new_p->tail);
if (ll_new_p->tail != NULL) {
list_node_p_set_next(ll_new_p, ll_new_p->tail, node);
}
ll_new_p->tail = node;
if (ll_new_p->head == NULL) {
ll_new_p->head = node;
}
}
}
void *list_get_head_2(const linklist2_t *list) {
if (list == NULL) return NULL;
return list->head;
}
void *list_get_tail_2(const linklist2_t *list) {
if (list == NULL) return NULL;
return list->tail;
}
void *list_get_next_2(const linklist2_t *list, const void *n_act) {
if (list == NULL || n_act == NULL) return NULL;
const _node_p_ *next_n = n_act;
next_n += DEF_NEXT_NODE_OFFS(list);
return *((_node_p_ **)next_n);
}
void *list_get_prev_2(const linklist2_t *list, const void *n_act) {
if (list == NULL || n_act == NULL) return NULL;
const _node_p_ *prev_n = n_act;
prev_n += DEF_PREV_NODE_OFFS(list);
return *((_node_p_ **)prev_n);
}
uint32_t list_get_len_2(const linklist2_t *list) {
uint32_t len = 0;
void *node;
for (node = list_get_head_2; node != NULL; node = list_get_next_2(list, node)) {
len++;
}
return len;
}
bool list_is_empty_2(linklist2_t *list) {
if (list == NULL) return true;
if (list->head == NULL && list->tail == NULL) return true;
return false;
}
/* staic */
static void list_node_p_set_prev(linklist2_t *p, _node_p_ *act, _node_p_ *prev) {
if (act == NULL) return;
uint8_t *act8 = (uint8_t *)act;
act8 += DEF_PREV_NODE_OFFS(p);
_node_p_ **act_node_p_p = (_node_p_ **)act8;
_node_p_ **prev_node_p_p = (_node_p_ **)&prev;
*act_node_p_p = *prev_node_p_p;
}
static void list_node_p_set_next(linklist2_t *p, _node_p_ *act, _node_p_ *next) {
if (act == NULL) return;
uint8_t *act8 = (uint8_t *)act;
act8 += DEF_NEXT_NODE_OFFS(p);
_node_p_ **act_node_p_p = (_node_p_ **)act8;
_node_p_ **next_node_p_p = (_node_p_ **)&next;
*act_node_p_p = *next_node_p_p;
}
/***************************** test ******************************************/
#if DEF_TEST_MALLOC_LINKLIST
// test
typedef struct info {
int id;
int age;
char name[16];
float soc;
} INFO;
typedef struct image {
int id;
int w;
int h;
struct pos {
int x;
int y;
};
} IMAGE;
linklist2_t list_info;
linklist2_t list_image;
//
int main() {
list_init_2(&list_info, sizeof(struct info));
list_init_2(&list_image, sizeof(struct image));
// info
INFO *info1 = list_ins_head_2(&list_info);
INFO *info2 = list_ins_head_2(&list_info);
if (info1 != NULL) {
info1->id = 0;
info1->age = 23;
strcpy(info1->name, "ZhangSan");
info1->soc = 19.3;
}
if (info2 != NULL) {
info2->id = 1;
info2->age = 25;
strcpy(info2->name, "LiSi");
info2->soc = 56.2;
}
INFO *i;
_LV_LL_READ(&list_info, i) {
printf("id=%d, age=%d, name=%s, soc=%.2f\n", i->id, i->age, i->name, i->soc);
}
// image
IMAGE *img1 = list_ins_head_2(&list_image);
IMAGE *img2 = list_ins_head_2(&list_image);
if (img1 != NULL) {
img1->id = 0;
img1->w = 100;
img1->h = 101;
img1->x = 50;
img1->y = 51;
}
if (img2 != NULL) {
img2->id = 1;
img2->w = 200;
img2->h = 201;
img2->x = 250;
img2->y = 251;
}
IMAGE *m;
_LV_LL_READ_BACK(&list_image, m) {
printf("id=%d, w=%d, h=%d, x=%d, y=%d\n", m->id, m->w, m->h, m->x, m->y);
}
return 0;
}
#endif

View File

@@ -0,0 +1,46 @@
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
// define
#define DEF_BYTE_ALIGN_8 0
#define DEF_BYTE_ALIGN_4 1
// config
#define DEF_LIST_ALIGN_MODE DEF_BYTE_ALIGN_8
#define DEF_MALLOC(s) malloc(s)
#define DEF_FREE(s) free(s)
#define DEF_TEST_MALLOC_LINKLIST 0
//
typedef uint8_t _node_p_;
typedef struct _linklist2 {
uint32_t size;
_node_p_ *head;
_node_p_ *tail;
} linklist2_t;
void list_init_2(linklist2_t *p, uint32_t size);
void *list_ins_head_2(linklist2_t *list);
void *list_ins_prev_2(linklist2_t *list, void *act);
void *list_ins_tail_2(linklist2_t *list);
void list_remove_node_2(linklist2_t *list, void *node);
void list_clear_2(linklist2_t *list);
void list_chg_list_2(linklist2_t *ll_ori_p, linklist2_t *ll_new_p, void *node, bool head);
void *list_get_head_2(const linklist2_t *list);
void *list_get_tail_2(const linklist2_t *list);
void *list_get_next_2(const linklist2_t *list, const void *n_act);
void *list_get_prev_2(const linklist2_t *list, const void *n_act);
uint32_t list_get_len_2(const linklist2_t *list);
bool list_is_empty_2(linklist2_t *list);
#define _LV_LL_READ(list, i) for (i = list_get_head_2(list); i != NULL; i = list_get_next_2(list, i))
#define _LV_LL_READ_BACK(list, i) for (i = list_get_tail_2(list); i != NULL; i = list_get_prev_2(list, i))
#endif

View File

@@ -0,0 +1,209 @@
#include "queue_malloc.h"
#define DEF_QUEUE_VAL_LEN_INVAILD 0xFFFF // 队列元素的长度为 0XFFFF 时,为无效值
#define DEF_QUEUE_RESERVE_SIZE(q) (q->bufSize - q->usedSize)
#define DEF_QUEUE_GET_VAL_SIZE(q, pos) ((0xFF & q->buf[pos]) | ((0xFF & q->buf[pos + 1]) << 8))
#define DEF_QUEUE_SET_VAL_SIZE(q, pos, val) \
do { \
q->buf[pos++] = 0xFF & val; \
q->buf[pos++] = (0xFF00 & val) >> 8; \
} while (0)
void QueueMallocInit(queue_t *q, uint8_t *buf, uint32_t buf_size)
{
if (q != NULL) {
q->init = true;
q->buf = buf;
q->bufSize = buf_size;
q->front = 0;
q->tail = 0;
q->elemCnt = 0;
q->usedSize = 0;
memset(q->buf, 0, q->bufSize);
}
}
void *QueueMallocInput(queue_t *q, void *val, val_size valSize)
{
uint32_t bufPos = 0;
uint32_t needSize = valSize + sizeof(val_size);
if (q->init == false || val == NULL || valSize == 0) {
return NULL;
}
if (DEF_QUEUE_RESERVE_SIZE(q) < valSize) { // 没有足够的空间保存这个数据
return NULL;
}
if (q->elemCnt > 0) {
bufPos = q->tail + DEF_QUEUE_GET_VAL_SIZE(q, q->tail);
if (q->tail >= q->front) { // tail 在 front 后面,队列还没有循环
if (((q->bufSize - bufPos) < needSize) && (q->front < needSize)) {
return NULL; // 空间虽然足够,但是一部分在头,一部分在末尾,不连续
}
if (q->bufSize - bufPos < needSize) {
DEF_QUEUE_SET_VAL_SIZE(q, bufPos, DEF_QUEUE_VAL_LEN_INVAILD);
bufPos = 0;
}
} else { // front 在 tail 后面,队列已经循环
if (q->front - bufPos < needSize) {
return NULL; // 没有空间
}
}
}
q->tail = bufPos;
DEF_QUEUE_SET_VAL_SIZE(q, bufPos, needSize); // bufPos 会 +2偏移 sizeof(valSize)
memcpy((void *)&q->buf[bufPos], val, valSize); // 保存数据 val
q->usedSize += needSize;
q->elemCnt++;
return (void *)&q->buf[bufPos];
}
void *QueueMallocOutput(queue_t *q, val_size *size)
{
void *value;
uint32_t dataSize;
if (q->init == false || q->elemCnt == 0) {
return NULL;
}
if (size) {
*size = DEF_QUEUE_GET_VAL_SIZE(q, q->front);
}
dataSize = DEF_QUEUE_GET_VAL_SIZE(q, q->front) + sizeof(val_size);
value = &q->buf[q->front + sizeof(val_size)];
q->front += dataSize;
if (DEF_QUEUE_GET_VAL_SIZE(q, q->front) == DEF_QUEUE_VAL_LEN_INVAILD) {
q->front = 0;
}
q->usedSize -= dataSize;
q->elemCnt--;
return value;
}
bool QueueMallocSpaceChk(queue_t *q, val_size size)
{
uint32_t bufPos = 0;
uint32_t needSize = size + sizeof(val_size);
if (q->init == false || (DEF_QUEUE_RESERVE_SIZE(q) < needSize)) {
return false;
}
if (q->elemCnt > 0) {
if (q->tail >= q->front) {
bufPos = q->tail + DEF_QUEUE_GET_VAL_SIZE(q, q->tail);
if ((q->bufSize - bufPos < needSize) && (q->front < needSize)) {
return false;
}
} else {
if (q->front - bufPos < needSize) {
return false;
}
}
}
return true;
}
void *QueueMallocPeek(queue_t *q, val_size *size)
{
if (q->init == false || q->elemCnt == 0) {
return NULL;
}
if (size) {
*size = DEF_QUEUE_GET_VAL_SIZE(q, q->front);
}
return (void *)&q->buf[q->front + sizeof(val_size)];
}
void *QueueMallocPeekAfter(queue_t *q, void *cur_item, val_size *size)
{
uint32_t bufPos = (uint8_t *)cur_item - q->buf - sizeof(val_size);
uint32_t itemSize;
if (q->init == false || q->elemCnt == 0 || q->tail == bufPos) {
return NULL;
}
bufPos = bufPos + DEF_QUEUE_GET_VAL_SIZE(q, bufPos);
itemSize = DEF_QUEUE_GET_VAL_SIZE(q, bufPos);
if (itemSize == DEF_QUEUE_VAL_LEN_INVAILD) {
bufPos = 0;
itemSize = DEF_QUEUE_GET_VAL_SIZE(q, bufPos);
}
if (size) {
*size = itemSize;
}
return (void *)&q->buf[bufPos + sizeof(val_size)];
}
void QueueMallocClear(queue_t *q)
{
q->front = 0;
q->tail = 0;
q->elemCnt = 0;
q->usedSize = 0;
}
uint32_t QueueMallocGetCnt(queue_t *q)
{
return q->elemCnt;
}
/****************************** test ***************************************/
#if DEF_TEST_MALLOC_QUEUE
// test
queue_t que1;
//
int main()
{
int v = 100;
int *p;
char str[12] = "hello!";
char *sp;
// init
QueueMallocInit(&que1);
// push
sp = QueueMallocInput(&que1, str, strlen(str) + 1);
printf("str = %s, used=%d/%d, tail=%d\n", sp, que1.usedSize, que1.bufSize, que1.tail);
p = QueueMallocInput(&que1, &v, sizeof(int));
if (p)
printf("v = %d, used=%d/%d, tail=%d\n", *p, que1.usedSize, que1.bufSize, que1.tail);
v = 200;
if (QueueMallocSpaceChk(&que1, sizeof(int))) {
p = QueueMallocInput(&que1, &v, sizeof(int));
printf("v = %d, used=%d/%d, tail=%d\n", *p, que1.usedSize, que1.bufSize, que1.tail);
}
printf("******* pop *****\n");
// pop
uint16_t size;
sp = QueueMallocOutput(&que1, &size);
printf("size=%d, str=%s, cnt=%d\n", size, sp, QueueMallocGetCnt(&que1));
size = 0;
QueueMallocPeek(&que1, &size);
printf("size=%d, cnt=%d\n", size, QueueMallocGetCnt(&que1));
return 0;
}
#endif

View File

@@ -0,0 +1,37 @@

#ifndef __QUEUE_MALLOC_H__
#define __QUEUE_MALLOC_H__
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
// config
#define DEF_TEST_MALLOC_QUEUE 0
//
typedef uint16_t val_size; // 两个字节记录数据长度
typedef struct _queue_ {
bool init;
uint8_t *buf;
uint32_t bufSize;
uint32_t front;
uint32_t tail;
uint32_t elemCnt;
uint32_t usedSize;
} queue_t;
void QueueMallocInit(queue_t *q, uint8_t *buf, uint32_t buf_size);
void *QueueMallocInput(queue_t *q, void *val, val_size valSize);
void *QueueMallocOutput(queue_t *q, val_size *size);
bool QueueMallocSpaceChk(queue_t *q, val_size size);
void *QueueMallocPeek(queue_t *q, val_size *size);
void *QueueMallocPeekAfter(queue_t *q, void *cur_item, val_size *size);
void QueueMallocClear(queue_t *q);
uint32_t QueueMallocGetCnt(queue_t *q);
#endif

View File

@@ -0,0 +1,158 @@
#include "stack_malloc.h"
#if DEF_TEST_MALLOC_STACK
#include <string.h>
#endif
#define DEF_STACK_NODE_NEXT_OFFS(s) (s->size)
#define DEF_STACK_NODE_P_SIZE (sizeof(stack_node_p *))
#define DEF_STACK_NODE_SIZE(s) (s->size + sizeof(stack_node_p *))
static void StackMallocSetNext(stack_t *s, stack_node *act, stack_node *next) {
uint8_t *act8 = (uint8_t *)act;
act8 += DEF_STACK_NODE_NEXT_OFFS(s);
stack_node_p **act_node_next = (stack_node_p **)act8;
stack_node_p **next_node_p = (stack_node_p **)&next;
*act_node_next = *next_node_p;
}
void StackMallocInit(stack_t *s, uint32_t size) {
if (s == NULL) return;
#ifdef DEF_BYTE_ALIGN_8
size = (size + 7) & (~0x7);
#else
size = (size + 3) & (~0x3);
#endif
s->size = size;
if (s != NULL) {
s->head = DEF_STACK_MALLOC(DEF_STACK_NODE_SIZE(s));
s->tail = s->head;
if (s->head != NULL) {
StackMallocSetNext(s, s->head, NULL);
}
}
}
void *StackMallocGetNext(stack_t *s) {
const stack_node_p *head = (stack_node_p *)s->head;
head += DEF_STACK_NODE_NEXT_OFFS(s);
return *((stack_node_p **)head);
}
void *StackMallocPush(stack_t *s) {
stack_node *new_node;
new_node = DEF_STACK_MALLOC(s->size + DEF_STACK_NODE_P_SIZE);
if (new_node != NULL) {
StackMallocSetNext(s, new_node, s->head);
s->head = new_node;
}
return new_node;
}
bool StackMallocEmpty(stack_t *s) {
if (s->head == s->tail) {
return true;
} else {
return false;
}
}
void StackMallocPop(stack_t *s, void *data) {
stack_node *next_node;
stack_node *old_node;
if (StackMallocEmpty(s)) {
return;
}
old_node = s->head;
s->head = StackMallocGetNext(s);
if (data != NULL) {
memcpy(data, old_node, DEF_STACK_NODE_SIZE(s));
}
DEF_STACK_FREE(old_node);
}
/****************************** test ***************************************/
#if DEF_TEST_MALLOC_STACK
typedef struct info {
int id;
int age;
char name[16];
float soc;
} INFO;
typedef struct image {
int id;
int w;
int h;
struct pos {
int x;
int y;
};
} IMAGE;
stack_t stack_info;
stack_t stack_image;
//
int main() {
StackMallocInit(&stack_info, sizeof(INFO));
StackMallocInit(&stack_image, sizeof(IMAGE));
// info
INFO *info1 = StackMallocPush(&stack_info);
INFO *info2 = StackMallocPush(&stack_info);
if (info1 != NULL) {
info1->id = 0;
info1->age = 23;
strcpy(info1->name, "ZhangSan");
info1->soc = 19.3;
}
if (info2 != NULL) {
info2->id = 1;
info2->age = 25;
strcpy(info2->name, "LiSi");
info2->soc = 56.2;
}
while (!StackMallocEmpty(&stack_info)) {
INFO i;
StackMallocPop(&stack_info, &i);
printf("id=%d, age=%d, name=%s, soc=%.2f\n", i.id, i.age, i.name, i.soc);
}
// image
IMAGE *img1 = StackMallocPush(&stack_image);
IMAGE *img2 = StackMallocPush(&stack_image);
if (img1 != NULL) {
img1->id = 0;
img1->w = 100;
img1->h = 101;
img1->x = 50;
img1->y = 51;
}
if (img2 != NULL) {
img2->id = 1;
img2->w = 200;
img2->h = 201;
img2->x = 250;
img2->y = 251;
}
while (!StackMallocEmpty(&stack_image)) {
IMAGE m;
StackMallocPop(&stack_image, &m);
printf("id=%d, w=%d, h=%d, x=%d, y=%d\n", m.id, m.w, m.h, m.x, m.y);
}
return 0;
}
#endif

View File

@@ -0,0 +1,36 @@
#ifndef __STATIC_MALLOC_H__
#define __STATIC_MALLOC_H__
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
// define
#define DEF_BYTE_ALIGN_8 0
#define DEF_BYTE_ALIGN_4 1
// config
#define DEF_LIST_ALIGN_MODE DEF_BYTE_ALIGN_8
#define DEF_STACK_MALLOC(size) malloc(size)
#define DEF_STACK_FREE(p) free(p)
#define DEF_TEST_MALLOC_STACK 0
//
typedef uint8_t stack_node_p;
typedef struct _stack_node_ {
stack_node_p *data;
stack_node_p *next;
} stack_node;
typedef struct _stack_ {
uint32_t size;
stack_node *head;
stack_node *tail;
} stack_t;
void StackMallocInit(stack_t *s, uint32_t size);
void *StackMallocPush(stack_t *s);
void StackMallocPop(stack_t *s, void *data);
#endif

View File

@@ -1,464 +0,0 @@
/************************************************************************
* FilePath : log.c
* Author : GX.Duan
* Date : 2022-09-18 20:31:59
* LastEditTime : 2022-09-18 20:33:48
* LastEditors : ShallowGreen123 2608653986@qq.com
* Copyright (c): 2022 by GX.Duan, All Rights Reserved.
* Github : https://github.com/ShallowGreen123/lvgl_mydemo
************************************************************************/
#define DEF_LIB_TRACE_MODULE
/*********************************************************************************
* INCLUDES
* *******************************************************************************/
#include "lib_log.h"
#include "drv_log.h"
#include "../../lvgl/lvgl.h"
/*********************************************************************************
* DEFINES
* *******************************************************************************/
#define DEF_LIB_TRACE_CIRCULAR_Q_REM_SIZE(q) (q->QBufSize - q->UsedSize)
#define DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, pos) ((0xFF & q->QBuf[pos]) | ((0xFF & q->QBuf[pos + 1]) << 8))
#define DEF_LIB_TRACE_MSG_Q_SIZE 4096
#define DEF_LIB_TRACE_MAX_WRITER_NBR 5
// #define DEF_LIB_TRACE_TIME_HANDLE &hlptim5
// #define DEF_LIB_TRACE_TIME_PERIOD 65535U
// #define DEF_LIB_TRACE_TIME_MS(x) (((x)*25000) / 128)
// #define DEF_LIB_TRACE_MAX_TIMEOUT_MS 335
// #define DEF_LIB_TRACE_USED_OS false
/*********************************************************************************
* MACROS
* *******************************************************************************/
/*********************************************************************************
* TYPEDEFS
* *******************************************************************************/
typedef struct lib_log_circular_q_handle_t {
uint8_t *QBuf;
uint32_t QBufSize;
uint32_t FirstElement;
uint32_t LastElement;
uint32_t ElementCnt;
uint32_t UsedSize;
} LIB_TRACE_CIRCULAR_Q_HANDLE_T;
typedef struct lib_log_writer_handle_t {
uint8_t *LastLogElement;
uint32_t LastSeqNbr;
Lib_LogWr_Fn Wr;
bool PerifRdy;
} LIB_TRACE_WRITER_HANDLE_T;
typedef struct lib_log_handle_t {
bool InitDone;
uint32_t RdSeqNbr;
uint32_t WrSeqNbr;
LIB_TRACE_CIRCULAR_Q_HANDLE_T Q;
uint8_t WorkBuf[DEF_LIB_TRACE_MAX_MSG_SIZE];
LIB_TRACE_WRITER_HANDLE_T WriterArray[DEF_LIB_TRACE_MAX_WRITER_NBR];
} LIB_TRACE_HANDLE_T;
//
static uint8_t Lib_LogQBuf[DEF_LIB_TRACE_MSG_Q_SIZE];
static uint32_t Lib_LogSeqNbr = 0;
static LIB_TRACE_HANDLE_T Lib_LogHdl;
static volatile bool Lib_LogProcReq = false;
/*********************************************************************************
* STATIC FUNCTION
* *******************************************************************************/
static int32_t Lib_LogCircularQInit(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint8_t *q_buf, uint32_t q_buf_size);
static bool Lib_LogCircularQChkSpace(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint16_t need_size);
static uint8_t *Lib_LogCircularQPush(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint8_t *element, uint16_t element_size);
static uint8_t *Lib_LogCircularQPop(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint16_t *element_size);
static uint8_t *Lib_LogCircularQPeek(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint16_t *element_size);
static uint8_t *Lib_LogCircularQPeekAfterElement(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint8_t *element, uint16_t *element_size);
static int32_t Lib_LogCircularQClear(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q);
static uint32_t Lib_LogCircularQGetElementNbr(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q);
static int32_t Lib_LogCircularQInit(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint8_t *q_buf, uint32_t q_buf_size)
{
q->QBuf = q_buf;
q->QBufSize = q_buf_size;
q->FirstElement = 0;
q->LastElement = 0;
q->ElementCnt = 0;
q->UsedSize = 0;
return 0;
}
static bool Lib_LogCircularQChkSpace(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint16_t need_size)
{
uint16_t sto_size = need_size + sizeof(uint16_t);
uint32_t last_element_sto_size = 0;
uint32_t buf_pos = 0;
if (DEF_LIB_TRACE_CIRCULAR_Q_REM_SIZE(q) < sto_size) {
return false;
}
if (q->ElementCnt > 0) {
last_element_sto_size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, q->LastElement) + sizeof(uint16_t);
buf_pos = q->LastElement + last_element_sto_size;
if (q->LastElement >= q->FirstElement) {
if ((q->QBufSize - buf_pos < sto_size) && (q->FirstElement < sto_size)) {
return false;
}
} else if (q->FirstElement - buf_pos < sto_size) {
return false;
}
}
return true;
}
static uint8_t *Lib_LogCircularQPush(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint8_t *element, uint16_t element_size)
{
uint16_t sto_size = element_size + sizeof(uint16_t);
uint32_t last_element_sto_size = 0;
uint32_t buf_pos = 0;
if (element == NULL || element_size == 0) {
return NULL;
}
if (DEF_LIB_TRACE_CIRCULAR_Q_REM_SIZE(q) < sto_size) {
// No enough space to store this element
return NULL;
}
if (q->ElementCnt > 0) {
last_element_sto_size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, q->LastElement) + sizeof(uint16_t);
buf_pos = q->LastElement + last_element_sto_size;
if (q->LastElement >= q->FirstElement) {
if ((q->QBufSize - buf_pos < sto_size) && (q->FirstElement < sto_size)) {
// No enough space to store this element
return NULL;
}
if (q->QBufSize - buf_pos < sto_size) {
// Mark eof as unused
q->QBuf[buf_pos] = 0xFF;
q->QBuf[buf_pos + 1] = 0xFF;
buf_pos = 0;
}
} else if (q->FirstElement - buf_pos < sto_size) {
// No enough space to store this element
return NULL;
}
}
q->LastElement = buf_pos;
// Store size
q->QBuf[buf_pos++] = 0xFF & element_size;
q->QBuf[buf_pos++] = (0xFF00 & element_size) >> 8;
// Store data
memcpy((void *)&q->QBuf[buf_pos], element, element_size);
q->UsedSize += sto_size;
q->ElementCnt++;
return element;
}
static uint8_t *Lib_LogCircularQPop(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint16_t *element_size)
{
uint8_t *data;
uint16_t sto_size;
if (q->ElementCnt == 0) {
return NULL;
}
*element_size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, q->FirstElement);
sto_size = *element_size + sizeof(uint16_t);
data = &q->QBuf[q->FirstElement + sizeof(uint16_t)];
q->FirstElement += sto_size;
if (DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, q->FirstElement) == 0xFFFF) {
// Eof mark
q->FirstElement = 0;
}
q->UsedSize -= sto_size;
q->ElementCnt--;
return data;
}
static uint8_t *Lib_LogCircularQPeek(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint16_t *element_size)
{
if (q->ElementCnt == 0) {
return NULL;
}
*element_size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, q->FirstElement);
return &q->QBuf[q->FirstElement + sizeof(uint16_t)];
}
static uint8_t *Lib_LogCircularQPeekAfterElement(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q, uint8_t *element, uint16_t *element_size)
{
uint16_t size;
uint32_t offset = element - q->QBuf - 2;
if ((q->ElementCnt == 0) || (q->LastElement == offset)) {
return NULL;
}
size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, offset);
offset += (size + sizeof(uint16_t));
size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, offset);
if (size == 0xFFFF) {
offset = 0;
size = DEF_LIB_TRACE_CIRCULAR_Q_ELEMENT_SIZE(q, offset);
}
*element_size = size;
return &q->QBuf[offset + sizeof(uint16_t)];
}
static int32_t Lib_LogCircularQClear(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q)
{
q->FirstElement = 0;
q->LastElement = 0;
q->ElementCnt = 0;
q->UsedSize = 0;
return 0;
}
static uint32_t Lib_LogCircularQGetElementNbr(LIB_TRACE_CIRCULAR_Q_HANDLE_T *q)
{
return q->ElementCnt;
}
static inline void Lib_LogIntLock(void)
{
// IntLockFun();
}
static inline void Lib_LogIntUnlock(void)
{
// UnlockFun();
}
static inline uint32_t Lib_LogGetTs(void)
{
// return GetTick();
return lv_tick_get();
}
static void Lib_LogStartProcReq(void)
{
Lib_LogProcReq = true;
}
/*********************************************************************************
* GLOBAL FUNCTION
* *******************************************************************************/
void Lib_LogInit(void)
{
memset((void *)&Lib_LogHdl, 0, sizeof(Lib_LogHdl));
Lib_LogCircularQInit(&Lib_LogHdl.Q, Lib_LogQBuf, sizeof(Lib_LogQBuf));
Lib_LogHdl.InitDone = true;
#if !(DEF_LIB_TRACE_FORCE_PRINTF)
Drv_LogSetupPrintf();
#endif
}
LIB_TRACE_WRITER_HDLR_T Lib_LogRegistWriter(Lib_LogWr_Fn wr_fnct)
{
uint32_t i;
Lib_LogIntLock();
for (i = 0; i < DEF_LIB_TRACE_MAX_WRITER_NBR; i++) {
if (Lib_LogHdl.WriterArray[i].Wr == NULL) {
Lib_LogHdl.WriterArray[i].Wr = wr_fnct;
Lib_LogHdl.WriterArray[i].LastSeqNbr = Lib_LogHdl.RdSeqNbr;
Lib_LogHdl.WriterArray[i].PerifRdy = true;
Lib_LogIntUnlock();
return (LIB_TRACE_WRITER_HDLR_T)(&Lib_LogHdl.WriterArray[i]);
}
}
Lib_LogIntUnlock();
return NULL;
}
bool Lib_LogUnregistWriter(LIB_TRACE_WRITER_HDLR_T writer_hdl)
{
uint32_t i;
Lib_LogIntLock();
for (i = 0; i < DEF_LIB_TRACE_MAX_WRITER_NBR; i++) {
if (&Lib_LogHdl.WriterArray[i] == writer_hdl) {
Lib_LogHdl.WriterArray[i].Wr = NULL;
Lib_LogHdl.WriterArray[i].LastSeqNbr = 0;
Lib_LogHdl.WriterArray[i].PerifRdy = false;
Lib_LogIntUnlock();
return true;
}
}
Lib_LogIntUnlock();
return false;
}
void Lib_LogWrDone(LIB_TRACE_WRITER_HDLR_T writer_hdl)
{
if (writer_hdl == NULL) {
return;
}
Lib_LogIntLock();
((LIB_TRACE_WRITER_HANDLE_T *)writer_hdl)->PerifRdy = true;
Lib_LogIntUnlock();
Lib_LogStartProcReq();
}
void Lib_LogPrintf(uint8_t lv, const char *fmt, ...)
{
LIB_TRACE_ITEM_HANDLE_T *log_element;
LIB_TRACE_CIRCULAR_Q_HANDLE_T *queue = &Lib_LogHdl.Q;
char *prefix;
va_list args;
int32_t ret;
uint32_t ts;
uint16_t element_size;
uint16_t tmp_size;
if (!Lib_LogHdl.InitDone) {
return;
}
switch (lv) {
case TRACE_LV_V:
prefix = "[V]";
break;
case TRACE_LV_DBG:
prefix = "[D]";
break;
case TRACE_LV_INFO:
prefix = "[I]";
break;
case TRACE_LV_WARN:
prefix = "[W]";
break;
case TRACE_LV_ERR:
prefix = "[E]";
break;
default:
prefix = "[X]";
break;
}
Lib_LogIntLock();
log_element = (LIB_TRACE_ITEM_HANDLE_T *)Lib_LogHdl.WorkBuf;
va_start(args, fmt);
ts = Lib_LogGetTs();
ret = snprintf((char *)log_element->Buf, DEF_LIB_TRACE_MAX_MSG_SIZE, "(%u) %s ", ts, prefix);
ret += vsnprintf((char *)log_element->Buf + ret, DEF_LIB_TRACE_MAX_MSG_SIZE - ret, fmt, args);
ret++; /* for terminating null character */
va_end(args);
if (ret > 0) {
log_element->Lv = lv;
log_element->Len = ret;
log_element->Ts = ts;
log_element->SeqNbr = Lib_LogSeqNbr++;
element_size = ret + sizeof(LIB_TRACE_ITEM_HANDLE_T);
while (!Lib_LogCircularQChkSpace(queue, element_size)) {
Lib_LogCircularQPop(queue, &tmp_size);
Lib_LogHdl.RdSeqNbr++;
}
Lib_LogCircularQPush(queue, (uint8_t *)log_element, element_size);
Lib_LogHdl.WrSeqNbr = log_element->SeqNbr;
Lib_LogStartProcReq();
}
Lib_LogIntUnlock();
#if DEF_LIB_TRACE_FORCE_PRINTF
#endif
#if DEF_LOG_COLOR_PRINT_EN
Drv_LogColorPrintf(log_element->Buf, prefix);
#else
Drv_LogPrintf(log_element->Buf);
#endif
}
void Lib_LogHexArray(uint8_t *data, uint32_t len)
{
uint8_t buf[DEF_LIB_TRACE_HEX_ARRAY_LINE_LEN * DEF_LIB_TRACE_HEX_ARRAY_ITEM_LEN + 1];
uint8_t remain = len;
uint8_t *p = data;
uint8_t dump_len;
uint8_t i;
while (remain > 0) {
if (remain > DEF_LIB_TRACE_HEX_ARRAY_LINE_LEN) {
dump_len = DEF_LIB_TRACE_HEX_ARRAY_LINE_LEN;
} else {
dump_len = remain;
}
for (i = 0; i < dump_len; i++) {
snprintf((char *)buf + i * DEF_LIB_TRACE_HEX_ARRAY_ITEM_LEN, sizeof(buf) - i * DEF_LIB_TRACE_HEX_ARRAY_ITEM_LEN, "%02X, ", *p++);
}
TRACE_I("%s\n", buf);
remain -= dump_len;
}
}
void Lib_LogProc(void)
{
LIB_TRACE_WRITER_HANDLE_T *writer;
uint8_t *element;
uint16_t element_size;
uint32_t i;
if (!Lib_LogProcReq) {
return;
}
Lib_LogProcReq = false;
for (i = 0; i < DEF_LIB_TRACE_MAX_WRITER_NBR; i++) {
Lib_LogIntLock();
writer = &Lib_LogHdl.WriterArray[i];
if ((writer->Wr == NULL) || (!writer->PerifRdy)) {
Lib_LogIntUnlock();
continue;
}
if ((!writer->LastLogElement) || (writer->LastSeqNbr < Lib_LogHdl.RdSeqNbr)) {
writer->LastSeqNbr = Lib_LogHdl.RdSeqNbr;
element = Lib_LogCircularQPeek(&Lib_LogHdl.Q, &element_size);
Lib_LogIntUnlock();
if (element) {
writer->PerifRdy = false;
if (writer->Wr((LIB_TRACE_ITEM_HANDLE_T *)element)) {
writer->LastLogElement = element;
} else {
writer->PerifRdy = true;
}
Lib_LogProcReq = true;
}
} else {
element = Lib_LogCircularQPeekAfterElement(&Lib_LogHdl.Q, writer->LastLogElement, &element_size);
Lib_LogIntUnlock();
if (element) {
writer->PerifRdy = false;
if (writer->Wr((LIB_TRACE_ITEM_HANDLE_T *)element)) {
writer->LastSeqNbr++;
writer->LastLogElement = element;
} else {
writer->PerifRdy = true;
}
Lib_LogProcReq = true;
}
}
}
}

View File

@@ -1,130 +0,0 @@
/************************************************************************
* FilePath : log.h
* Author : GX.Duan
* Date : 2022-09-18 17:49:09
* LastEditTime : 2022-09-21 21:55:55
* LastEditors : ShallowGreen123 2608653986@qq.com
* Copyright (c): 2022 by GX.Duan, All Rights Reserved.
* Github : https://github.com/ShallowGreen123/lvgl_mydemo
************************************************************************/
#ifndef __LIB_TRACE_H__
#define __LIB_TRACE_H__
/*********************************************************************************
* INCLUDES
* *******************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
/*********************************************************************************
* DEFINES
* *******************************************************************************/
#ifdef DEF_LIB_TRACE_MODULE
# define DEF_LIB_TRACE_EXT
#else
# define DEF_LIB_TRACE_EXT extern
#endif
#if defined(_WIN32)
# ifndef __packed
# define __packed
# endif
# ifndef __aligned
# define __aligned(x) __declspec(align(x))
# endif
#else /* _WIN32 */
# include <sys/cdefs.h>
#endif /* _WIN32 */
/*********************************************************************************
* MACROS
* *******************************************************************************/
#define TRACE_LV_NONE 0
#define TRACE_LV_ERR 1
#define TRACE_LV_WARN 2
#define TRACE_LV_INFO 3
#define TRACE_LV_DBG 4
#define TRACE_LV_V 5
#define DEF_DBG_LV TRACE_LV_DBG
#define DEF_LIB_TRACE_FORCE_PRINTF 1
#define DEF_LOG_COLOR_PRINT_EN 1
#define DEF_LIB_TRACE_MAX_MSG_SIZE 256
#define DEF_LIB_TRACE_HEX_ARRAY_LINE_LEN 32
#define DEF_LIB_TRACE_HEX_ARRAY_ITEM_LEN 4
//////////////////////////
#if (DEF_DBG_LV >= TRACE_LV_V)
# define TRACE_V(FMT, ...) Lib_LogPrintf(TRACE_LV_V, FMT, ##__VA_ARGS__)
#else
# define TRACE_V(FMT, ...)
#endif
#if (DEF_DBG_LV >= TRACE_LV_DBG)
# define TRACE_D(FMT, ...) Lib_LogPrintf(TRACE_LV_DBG, FMT, ##__VA_ARGS__)
#else
# define TRACE_D(FMT, ...)
#endif
#if (DEF_DBG_LV >= TRACE_LV_INFO)
# define TRACE_I(FMT, ...) Lib_LogPrintf(TRACE_LV_INFO, FMT, ##__VA_ARGS__)
#else
# define TRACE_I(FMT, ...)
#endif
#if (DEF_DBG_LV >= TRACE_LV_WARN)
# define TRACE_W(FMT, ...) Lib_LogPrintf(TRACE_LV_WARN, FMT, ##__VA_ARGS__)
#else
# define TRACE_W(FMT, ...)
#endif
#if (DEF_DBG_LV >= TRACE_LV_ERR)
# define TRACE_E(FMT, ...) Lib_LogPrintf(TRACE_LV_ERR, FMT, ##__VA_ARGS__)
#else
# define TRACE_E(FMT, ...)
#endif
#if (DEF_DBG_LV >= TRACE_LV_INFO)
# define TRACE_HEX_ARRAY(data, data_len) Lib_LogHexArray((uint8_t *)(data), (uint32_t)(data_len))
#endif
/*********************************************************************************
* TYPEDEFS
* *******************************************************************************/
typedef struct lib_log_item_handle_t {
uint8_t Lv;
uint16_t Len;
uint32_t Ts;
uint32_t SeqNbr;
uint8_t Buf[0];
} __packed LIB_TRACE_ITEM_HANDLE_T;
typedef bool (*Lib_LogWr_Fn)(LIB_TRACE_ITEM_HANDLE_T *item);
typedef void *LIB_TRACE_WRITER_HDLR_T;
/*********************************************************************************
* GLOBAL PROTOTYPES
* *******************************************************************************/
DEF_LIB_TRACE_EXT void Lib_LogInit(void);
DEF_LIB_TRACE_EXT LIB_TRACE_WRITER_HDLR_T Lib_LogRegistWriter(Lib_LogWr_Fn wr_fnct);
DEF_LIB_TRACE_EXT bool Lib_LogUnregistWriter(LIB_TRACE_WRITER_HDLR_T writer_hdl);
DEF_LIB_TRACE_EXT void Lib_LogWrDone(LIB_TRACE_WRITER_HDLR_T writer_hdl);
DEF_LIB_TRACE_EXT void Lib_LogPrintf(uint8_t lv, const char *fmt, ...);
DEF_LIB_TRACE_EXT void Lib_LogHexArray(uint8_t *data, uint32_t len);
DEF_LIB_TRACE_EXT void Lib_LogProc(void);
#endif /* __LIB_TRACE_H__ */

View File

@@ -0,0 +1,208 @@
#include "lib_sys_log.h"
#include "data_struct/queue_malloc.h"
typedef struct lib_log_writer_handle_t {
void *LastLogElement;
uint32_t LastSeqNbr;
Lib_LogWr_Fn Wr;
bool PerifRdy;
} LIB_LOG_WRITER_T;
typedef struct lib_log_handle_t {
bool InitDone;
uint32_t RdSeqNbr;
uint32_t WrSeqNbr;
queue_t Queue;
uint8_t WorkBuf[DEF_LIB_LOG_MAX_MSG_SIZE];
LIB_LOG_WRITER_T WriterArray[DEF_LIB_LOG_MAX_WRITER_NBR];
} LIB_LOG_HANDLE_T;
static LIB_LOG_HANDLE_T Lib_LogHdl;
static uint8_t Lib_LogBuff[DEF_LIB_LOG_MSG_Q_SIZE];
static uint32_t Lib_LogSeqNbr = 0;
static volatile bool Lib_LogProcReq = false;
/********** static ************/
static inline void Lib_LogLock(void)
{
// LockFun();
}
static inline void Lib_LogUnlock(void)
{
// UnlockFun();
}
static inline uint32_t Lib_LogGetTs(void)
{
// return GetTick();
return lv_tick_get();
}
static void Lib_LogStartProcReq(void)
{
Lib_LogProcReq = true;
}
//
void Lib_LogInit(void)
{
QueueMallocInit(&Lib_LogHdl.Queue, Lib_LogBuff, sizeof(Lib_LogBuff));
Lib_LogHdl.InitDone = true;
}
void Lib_LogPrintf(uint8_t level, const char *fmt, ...)
{
LIB_LOG_ITEM_T *log_item;
queue_t *que = &Lib_LogHdl.Queue;
char *prefix;
va_list args;
uint32_t ts;
int32_t ret;
uint32_t log_item_size;
if (!Lib_LogHdl.InitDone) {
return;
}
/* clang-format off */
switch (level) {
case DEF_LIB_LOG_NONE: prefix = "[N]"; break;
case DEF_LIB_LOG_ERR : prefix = "[E]"; break;
case DEF_LIB_LOG_WARN: prefix = "[W]"; break;
case DEF_LIB_LOG_INFO: prefix = "[I]"; break;
case DEF_LIB_LOG_DBG : prefix = "[D]"; break;
default: prefix = ""; break;
}
/* clang-format on */
Lib_LogLock();
log_item = (LIB_LOG_ITEM_T *)Lib_LogHdl.WorkBuf;
va_start(args, fmt);
ts = Lib_LogGetTs();
ret = snprintf((char *)log_item->Buf, DEF_LIB_LOG_MAX_MSG_SIZE, "(%u) %s", ts, prefix);
ret += vsnprintf((char *)log_item->Buf + ret, DEF_LIB_LOG_MAX_MSG_SIZE - ret, fmt, args);
ret++;
va_end(args);
if (ret > 0) {
log_item->Lv = level;
log_item->Len = ret;
log_item->Ts = ts;
log_item->SeqNbr = Lib_LogSeqNbr++;
log_item_size = ret + sizeof(LIB_LOG_ITEM_T);
while (!QueueMallocSpaceChk(que, log_item_size)) {
QueueMallocOutput(que, NULL);
Lib_LogHdl.RdSeqNbr++;
}
QueueMallocInput(que, log_item, log_item_size);
Lib_LogHdl.WrSeqNbr = log_item->SeqNbr;
Lib_LogNeedWr();
}
Lib_LogUnlock();
#if DEF_LIB_LOG_PRINTF
printf("%s\n", log_item->Buf);
#endif
}
void Lib_LogHexArray(uint8_t *data, uint32_t len)
{
}
LIB_LOG_WR_T Lib_LogRegistWriter(Lib_LogWr_Fn wr_fnct)
{
uint32_t i;
Lib_LogLock();
for (i = 0; i < DEF_LIB_LOG_MAX_WRITER_NBR; i++) {
if (Lib_LogHdl.WriterArray[i].Wr == NULL) {
Lib_LogHdl.WriterArray[i].Wr = wr_fnct;
Lib_LogHdl.WriterArray[i].PerifRdy = true;
Lib_LogHdl.WriterArray[i].LastSeqNbr = Lib_LogHdl.RdSeqNbr;
Lib_LogUnlock();
return (LIB_LOG_WR_T *)(&Lib_LogHdl.WriterArray[i]);
}
}
Lib_LogUnlock();
return NULL;
}
bool Lib_LogUnregistWriter(LIB_LOG_WR_T writer_hdl)
{
uint32_t i;
Lib_LogLock();
for (i = 0; i < DEF_LIB_LOG_MAX_WRITER_NBR; i++) {
if (Lib_LogHdl.WriterArray[i].Wr == writer_hdl) {
Lib_LogHdl.WriterArray[i].Wr = NULL;
Lib_LogHdl.WriterArray[i].PerifRdy = false;
Lib_LogHdl.WriterArray[i].LastSeqNbr = 0;
Lib_LogUnlock();
return true;
}
}
Lib_LogUnlock();
return false;
}
void Lib_LogNeedWr(void)
{
uint32_t i;
Lib_LogLock();
for (i = 0; i < DEF_LIB_LOG_MAX_WRITER_NBR; i++) {
if (Lib_LogHdl.WriterArray[i].Wr != NULL) {
Lib_LogHdl.WriterArray[i].PerifRdy = true;
}
}
Lib_LogUnlock();
Lib_LogStartProcReq();
}
void Lib_LogLoop(void)
{
uint32_t i;
LIB_LOG_WRITER_T *write;
LIB_LOG_ITEM_T *log_item;
if (!Lib_LogProcReq) {
return;
}
Lib_LogProcReq = false;
for (i = 0; i < DEF_LIB_LOG_MAX_WRITER_NBR; i++) {
Lib_LogLock();
write = &Lib_LogHdl.WriterArray[i];
if (write->Wr == NULL || write->PerifRdy == false) {
Lib_LogUnlock();
continue;
}
if (write->LastLogElement == NULL || write->LastSeqNbr < Lib_LogHdl.RdSeqNbr) { // 第一次写
write->LastSeqNbr = Lib_LogHdl.RdSeqNbr;
log_item = QueueMallocPeek(&Lib_LogHdl.Queue, NULL);
Lib_LogUnlock();
if (log_item) {
write->PerifRdy = false;
if (write->Wr(log_item)) {
write->LastLogElement = log_item;
} else {
write->PerifRdy = true;
}
Lib_LogProcReq = true;
}
} else {
log_item = QueueMallocPeekAfter(&Lib_LogHdl.Queue, write->LastLogElement, NULL);
Lib_LogUnlock();
if (log_item) {
write->PerifRdy = false;
if (write->Wr(log_item)) {
write->LastLogElement = log_item;
write->LastSeqNbr++;
} else {
write->PerifRdy = true;
}
Lib_LogProcReq = true;
}
}
}
}

View File

@@ -0,0 +1,122 @@
#ifndef __DEF_LIB_LOG_H__
#define __DEF_LIB_LOG_H__
/*********************************************************************************
* INCLUDES
* *******************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
/*********************************************************************************
* DEFINES
* *******************************************************************************/
#ifdef DEF_LIB_TRACE_MODULE
# define DEF_LIB_LOG_EXT
#else
# define DEF_LIB_LOG_EXT extern
#endif
#if defined(_WIN32)
# ifndef __packed
# define __packed
# endif
# ifndef __aligned
# define __aligned(x) __declspec(align(x))
# endif
#else /* _WIN32 */
# include <sys/cdefs.h>
#endif /* _WIN32 */
/*********************************************************************************
* MACROS
* *******************************************************************************/
#define DEF_LIB_LOG_NONE 0
#define DEF_LIB_LOG_ERR 1
#define DEF_LIB_LOG_WARN 2
#define DEF_LIB_LOG_INFO 3
#define DEF_LIB_LOG_DBG 4
#define DEF_LIB_LOG_V 5
// config
#define DEF_LIB_LOG_LEVEL DEF_LIB_LOG_DBG
#define DEF_LIB_LOG_PRINTF 0
#define DEF_LIB_LOG_COLOR_PRINT_EN 1
#define DEF_LIB_LOG_MSG_Q_SIZE 4096
#define DEF_LIB_LOG_MAX_MSG_SIZE 256
#define DEF_LIB_LOG_MAX_WRITER_NBR 5
#define DEF_LIB_LOG_HEX_ARRAY_LINE_LEN 32
#define DEF_LIB_LOG_HEX_ARRAY_ITEM_LEN 4
//////////////////////////
#if (DEF_LIB_LOG_LEVEL >= DEF_LIB_LOG_V)
# define TRACE_V(FMT, ...) Lib_LogPrintf(DEF_LIB_LOG_V, FMT, ##__VA_ARGS__)
#else
# define TRACE_V(FMT, ...)
#endif
#if (DEF_LIB_LOG_LEVEL >= DEF_LIB_LOG_DBG)
# define TRACE_D(FMT, ...) Lib_LogPrintf(DEF_LIB_LOG_DBG, FMT, ##__VA_ARGS__)
#else
# define TRACE_D(FMT, ...)
#endif
#if (DEF_LIB_LOG_LEVEL >= DEF_LIB_LOG_INFO)
# define TRACE_I(FMT, ...) Lib_LogPrintf(DEF_LIB_LOG_INFO, FMT, ##__VA_ARGS__)
#else
# define TRACE_I(FMT, ...)
#endif
#if (DEF_LIB_LOG_LEVEL >= DEF_LIB_LOG_WARN)
# define TRACE_W(FMT, ...) Lib_LogPrintf(DEF_LIB_LOG_WARN, FMT, ##__VA_ARGS__)
#else
# define TRACE_W(FMT, ...)
#endif
#if (DEF_LIB_LOG_LEVEL >= DEF_LIB_LOG_ERR)
# define TRACE_E(FMT, ...) Lib_LogPrintf(DEF_LIB_LOG_ERR, FMT, ##__VA_ARGS__)
#else
# define TRACE_E(FMT, ...)
#endif
#if (DEF_LIB_LOG_LEVEL >= DEF_LIB_LOG_INFO)
# define TRACE_HEX_ARRAY(data, data_len) Lib_LogHexArray((uint8_t *)(data), (uint32_t)(data_len))
#endif
/*********************************************************************************
* TYPEDEFS
* *******************************************************************************/
typedef struct lib_log_item_handle_t {
uint8_t Lv;
uint16_t Len;
uint32_t Ts;
uint32_t SeqNbr;
uint8_t Buf[0];
} __packed LIB_LOG_ITEM_T;
typedef bool (*Lib_LogWr_Fn)(LIB_LOG_ITEM_T *item);
typedef void *LIB_LOG_WR_T;
/*********************************************************************************
* GLOBAL PROTOTYPES
* *******************************************************************************/
DEF_LIB_LOG_EXT void Lib_LogInit(void);
DEF_LIB_LOG_EXT void Lib_LogPrintf(uint8_t lv, const char *fmt, ...);
DEF_LIB_LOG_EXT void Lib_LogHexArray(uint8_t *data, uint32_t len);
DEF_LIB_LOG_EXT LIB_LOG_WR_T Lib_LogRegistWriter(Lib_LogWr_Fn wr_fnct);
DEF_LIB_LOG_EXT bool Lib_LogUnregistWriter(LIB_LOG_WR_T writer_hdl);
DEF_LIB_LOG_EXT void Lib_LogNeedWr(void);
DEF_LIB_LOG_EXT void Lib_LogLoop(void);
#endif /* __DEF_LIB_LOG_H__ */

View File

@@ -33,20 +33,27 @@ static void log_write_timer_cb(lv_timer_t *t)
{
LV_UNUSED(t);
TRACE_V("Hello wrold!");
TRACE_D("Hello wrold!");
TRACE_I("Hello wrold!");
TRACE_E("Hello wrold!");
TRACE_W("Hello wrold!");
Lib_LogProc();
Lib_LogLoop();
}
static bool log_write_to_file(LIB_TRACE_ITEM_HANDLE_T *item)
static bool log_write_to_file(LIB_LOG_ITEM_T *item)
{
TRACE_D("item info = %s", item->Buf);
printf("File %s\n", item->Buf);
return true;
}
static bool log_write_to_flash(LIB_LOG_ITEM_T *item)
{
printf("Flash %s\n", item->Buf);
return true;
}
static bool log_write_to_sd(LIB_LOG_ITEM_T *item)
{
printf("Sd %s\n", item->Buf);
return true;
}
/*********************************************************************************
* GLOBAL FUNCTION
* *******************************************************************************/
@@ -54,12 +61,19 @@ static bool log_write_to_file(LIB_TRACE_ITEM_HANDLE_T *item)
void lvgl_app_init(void)
{
Lib_LogInit();
Lib_LogRegistWriter(log_write_to_file);
Lib_LogRegistWriter(log_write_to_file); // 模拟写日志到文件
Lib_LogRegistWriter(log_write_to_flash); // 模拟写日志到Flash
Lib_LogRegistWriter(log_write_to_sd); // 模拟写日志到SD卡
Lib_LogUnregistWriter(log_write_to_sd);
DataModelInit();
ScrMgrInit();
ScrMgrSwitchScr(GUI_MIAN_SCR_ID, true);
lv_timer_create(log_write_timer_cb, 3000, NULL);
TRACE_W("Hello wrold!");
lv_timer_create(log_write_timer_cb, 50, NULL);
}

View File

@@ -15,7 +15,7 @@
* *******************************************************************************/
#include "../lvgl/lvgl.h"
#include <stdio.h>
#include "lib/lib_log.h"
#include "lib/lib_sys_log.h"
#include "data/dataModel.h"
#include "data/gui_scr_mgr.h"