diff --git a/LVGL.Simulator/.vscode/settings.json b/LVGL.Simulator/.vscode/settings.json
index 83b189b..86b7c01 100644
--- a/LVGL.Simulator/.vscode/settings.json
+++ b/LVGL.Simulator/.vscode/settings.json
@@ -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"
}
\ No newline at end of file
diff --git a/LVGL.Simulator/LVGL.Simulator.vcxproj b/LVGL.Simulator/LVGL.Simulator.vcxproj
index 5813950..cfa8168 100644
--- a/LVGL.Simulator/LVGL.Simulator.vcxproj
+++ b/LVGL.Simulator/LVGL.Simulator.vcxproj
@@ -54,8 +54,11 @@
+
+
+
-
+
diff --git a/LVGL.Simulator/LVGL.Simulator.vcxproj.filters b/LVGL.Simulator/LVGL.Simulator.vcxproj.filters
index 731b700..e051a05 100644
--- a/LVGL.Simulator/LVGL.Simulator.vcxproj.filters
+++ b/LVGL.Simulator/LVGL.Simulator.vcxproj.filters
@@ -45,7 +45,16 @@
lvgl_mydemo\lib
-
+
+ lvgl_mydemo\lib\data_struct
+
+
+ lvgl_mydemo\lib\data_struct
+
+
+ lvgl_mydemo\lib\data_struct
+
+
lvgl_mydemo\lib
@@ -83,5 +92,8 @@
{125c5bdc-13e9-45ed-bf0d-f844505c20ca}
+
+ {aff205ae-5bf7-43e9-af94-55de0a04480b}
+
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/data_struct/linklist_malloc.c b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/linklist_malloc.c
new file mode 100644
index 0000000..5fa5cf9
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/linklist_malloc.c
@@ -0,0 +1,310 @@
+
+#include "linklist_malloc.h"
+
+#if DEF_TEST_MALLOC_LINKLIST
+#include
+#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
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/data_struct/linklist_malloc.h b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/linklist_malloc.h
new file mode 100644
index 0000000..4a875c2
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/linklist_malloc.h
@@ -0,0 +1,46 @@
+
+
+#ifndef __LINKLIST_H__
+#define __LINKLIST_H__
+
+#include
+#include
+#include
+#include
+
+// 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
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/data_struct/queue_malloc.c b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/queue_malloc.c
new file mode 100644
index 0000000..b52eb34
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/queue_malloc.c
@@ -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
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/data_struct/queue_malloc.h b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/queue_malloc.h
new file mode 100644
index 0000000..7572a1a
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/queue_malloc.h
@@ -0,0 +1,37 @@
+
+
+#ifndef __QUEUE_MALLOC_H__
+#define __QUEUE_MALLOC_H__
+
+#include
+#include
+#include
+#include
+#include
+
+// 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
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/data_struct/stack_malloc.c b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/stack_malloc.c
new file mode 100644
index 0000000..edc0ef6
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/stack_malloc.c
@@ -0,0 +1,158 @@
+
+#include "stack_malloc.h"
+#if DEF_TEST_MALLOC_STACK
+#include
+#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
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/data_struct/stack_malloc.h b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/stack_malloc.h
new file mode 100644
index 0000000..0995ba8
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/data_struct/stack_malloc.h
@@ -0,0 +1,36 @@
+#ifndef __STATIC_MALLOC_H__
+#define __STATIC_MALLOC_H__
+
+#include
+#include
+#include
+#include
+
+// 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
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/lib_log.c b/LVGL.Simulator/lvgl_mydemo/lib/lib_log.c
deleted file mode 100644
index 7477598..0000000
--- a/LVGL.Simulator/lvgl_mydemo/lib/lib_log.c
+++ /dev/null
@@ -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;
- }
- }
- }
-}
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/lib_log.h b/LVGL.Simulator/lvgl_mydemo/lib/lib_log.h
deleted file mode 100644
index 608162e..0000000
--- a/LVGL.Simulator/lvgl_mydemo/lib/lib_log.h
+++ /dev/null
@@ -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
-#include
-#include
-#include
-#include
-
-/*********************************************************************************
- * 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
-#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__ */
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/lib_sys_log.c b/LVGL.Simulator/lvgl_mydemo/lib/lib_sys_log.c
new file mode 100644
index 0000000..0af80ca
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/lib_sys_log.c
@@ -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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lib/lib_sys_log.h b/LVGL.Simulator/lvgl_mydemo/lib/lib_sys_log.h
new file mode 100644
index 0000000..30f439d
--- /dev/null
+++ b/LVGL.Simulator/lvgl_mydemo/lib/lib_sys_log.h
@@ -0,0 +1,122 @@
+#ifndef __DEF_LIB_LOG_H__
+#define __DEF_LIB_LOG_H__
+
+/*********************************************************************************
+ * INCLUDES
+ * *******************************************************************************/
+#include
+#include
+#include
+#include
+#include
+
+/*********************************************************************************
+ * 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
+#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__ */
\ No newline at end of file
diff --git a/LVGL.Simulator/lvgl_mydemo/lvgl_app.c b/LVGL.Simulator/lvgl_mydemo/lvgl_app.c
index 724bb6e..d2ba906 100644
--- a/LVGL.Simulator/lvgl_mydemo/lvgl_app.c
+++ b/LVGL.Simulator/lvgl_mydemo/lvgl_app.c
@@ -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);
}
diff --git a/LVGL.Simulator/lvgl_mydemo/lvgl_app.h b/LVGL.Simulator/lvgl_mydemo/lvgl_app.h
index 2b19677..8e814e9 100644
--- a/LVGL.Simulator/lvgl_mydemo/lvgl_app.h
+++ b/LVGL.Simulator/lvgl_mydemo/lvgl_app.h
@@ -15,7 +15,7 @@
* *******************************************************************************/
#include "../lvgl/lvgl.h"
#include
-#include "lib/lib_log.h"
+#include "lib/lib_sys_log.h"
#include "data/dataModel.h"
#include "data/gui_scr_mgr.h"