guohui 1 год назад
Родитель
Сommit
0db11cec31

+ 1 - 1
f407/applications/cfg.h

@@ -2,7 +2,7 @@
 #define __CONFIG_Hx__
 
 
-#define VERSION                                 "V0.0.2"
+#define VERSION                                 "V1.0.0"
 
 
 

+ 852 - 0
f407/applications/list.c

@@ -0,0 +1,852 @@
+#include "list.h"
+#include <rtdbg.h>
+#include <pthread.h>
+
+
+#define MALLOC  rt_malloc
+#define FREE    rt_free
+
+#define LOGD    LOG_D
+#define LOGE    LOG_E
+#define LOGW    LOG_W
+
+
+#define MIN(a,b)  (((a)>(b))?(b):(a))
+#define MAX(a,b)  (((a)>(b))?(a):(b))
+
+
+typedef struct {
+    list_node_t         *head;
+    list_node_t         *tail;
+    int                 size;
+}dlist_t;
+
+
+typedef struct {
+    dlist_t             used;
+  
+    handle_t            lock;
+    list_cfg_t          cfg;
+    
+    dlist_t             free;
+}list_t;
+static list_node_t *node_get(list_t *l, int index);
+
+static void* lock_init(void)
+{
+    int r;
+    
+    pthread_mutex_t *m=(pthread_mutex_t*)MALLOC(sizeof(pthread_mutex_t));
+    if(!m) {
+        return NULL;
+    }
+	r = pthread_mutex_init(m, NULL);
+	if(r) {
+        FREE(m);
+        return NULL;
+	}
+
+	return m;
+}
+static int lock_free(void *h)
+{
+    if(!h) {
+        return -1;
+    }
+	pthread_mutex_destroy((pthread_mutex_t*)h);
+	FREE(h);
+	return 0;
+}
+static int lock_on(void *h)
+{
+    if(!h) {
+        return -1;
+    }
+
+	return pthread_mutex_lock((pthread_mutex_t*)h);
+}
+static int lock_off(void *h)
+{
+    if(!h) {
+        return -1;
+    }
+
+    return pthread_mutex_unlock((pthread_mutex_t*)h);
+}
+
+
+
+
+static list_node_t* node_from_free(list_t *l, int dlen)
+{
+    int i;
+    list_node_t *tmp=NULL;
+    dlist_t *dl=&l->free;
+    
+    tmp = dl->head;         //��ͷ����ʼ�������ʽڵ�
+    while(tmp) {
+        if(tmp->data.buf && tmp->data.blen>=dlen) {
+            
+            if(tmp==dl->head) {            //head
+                if(dl->size==1) {
+                    dl->head = NULL;
+                    dl->tail = NULL;
+                }
+                else {
+                    tmp->next->prev = NULL;
+                    dl->head = tmp->next;
+                }
+            }
+            else if(tmp==dl->tail) {
+                if(dl->size==1) {
+                    dl->head = NULL;
+                    dl->tail = NULL;
+                }
+                else {
+                    tmp->next->next = NULL;
+                    dl->tail = tmp->next;
+                }
+            }
+            else {
+                tmp->prev->next = tmp->next;
+                tmp->next->prev = tmp->prev;
+            }
+            
+            dl->size--;
+            
+            return tmp;
+        }
+        tmp = tmp->next;
+    }
+    
+    return NULL;
+}
+static int node_to_free(list_t *l, list_node_t *node)
+{
+    int r=-1;
+    list_node_t *tail=NULL;
+    dlist_t *dl=&l->free;
+    
+    tail = dl->tail;          //�½ڵ����free�б�β��
+    if(tail==NULL) {          //�޽ڵ�
+        node->prev = NULL;
+        node->next = NULL;
+        
+        dl->head = node;
+        dl->tail = node;
+    }
+    else {
+        
+        node->prev = tail;
+        node->next = NULL;
+        
+        tail->next = node;
+        dl->tail = node;
+        if(dl->head==NULL) {
+            dl->head = node;
+        }
+    }
+    dl->size++;
+    
+    return 0;
+}
+static list_node_t *node_new(list_t *l, node_t *n)
+{
+    list_node_t *node=NULL;
+    
+    node = node_from_free(l, n->dlen);
+    if(!node) {
+        node = MALLOC(sizeof(list_node_t));
+        if (!node) return NULL;
+        
+        node->prev = NULL;
+        node->next = NULL;
+        
+        node->data.buf = MALLOC(n->dlen);
+        if(!node->data.buf) {
+            FREE(node);
+            return NULL;
+        }
+        node->data.blen = n->dlen;
+    }
+    
+    memcpy(node->data.buf, n->buf, n->dlen);
+    node->data.dlen = n->dlen;
+    node->data.tp = n->tp;
+
+    return node;
+}
+static int node_free(list_t *l, list_node_t *node)
+{
+    FREE(node->data.buf);
+    FREE(node);
+    
+    return 0;
+}
+static int node_remove(list_t *l, list_node_t *node, int ds)
+{
+    int index;
+    list_node_t *tmp=node;
+    dlist_t *dl=&l->used;
+    
+    if(tmp==dl->head) {
+        if(dl->size==1) {
+            dl->head = NULL;
+            dl->tail = NULL;
+        }
+        else {
+            dl->head = tmp->next;
+            dl->head->prev = NULL;
+        }
+    }
+    else if(tmp==dl->tail) {
+        if(dl->size==1) {
+            dl->head = NULL;
+            dl->tail = NULL;
+        }
+        else {
+            dl->tail = tmp->prev;
+            if(dl->tail) {
+                dl->tail->next = NULL;
+            }
+        }
+    }
+    else {
+        tmp->prev->next = tmp->next;
+        tmp->next->prev = tmp->prev;
+    }
+    dl->size--;
+    
+    if(ds==1) {
+        node_to_free(l, tmp);
+    }
+    else if(ds==2) {
+        node_free(l, tmp);
+    }
+    
+    return 0;
+}
+static int node_insert(list_t *l, list_node_t *node, int index)
+{
+    list_node_t *xd=NULL,*tmp=node;
+    dlist_t *dl=&l->used;
+    
+    if(dl->size==0) {
+        tmp->prev = NULL;
+        tmp->next = NULL;
+        
+        dl->head = tmp;
+        dl->tail = tmp;
+    }
+    else {
+        if(index==0) {                                  //head
+            tmp->prev = NULL;
+            tmp->next = dl->head;
+            
+            xd->prev = tmp;
+            dl->head = tmp;
+        }
+        else if((index==(dl->size)) || (index==-1)) {   //tail
+            tmp->prev = dl->tail;
+            tmp->next = NULL;
+            
+            dl->tail->next = tmp;
+            dl->tail = tmp;
+        }
+        else {
+            xd = node_get(l, index);
+            
+            tmp->prev = xd->prev;
+            tmp->next = xd;
+            xd->prev->next = tmp;
+            xd->prev = tmp;
+        }
+    }
+    dl->size++;
+    
+    return 0;
+}
+
+static int node_set(list_t *l, list_node_t *node, node_t *nd)
+{
+    FREE(node->data.buf);
+    node->data.buf = MALLOC(nd->dlen);
+    if(!node->data.buf) {
+        return -1;
+    }
+    
+    memcpy(node->data.buf, nd->buf, nd->dlen);
+    node->data.blen = nd->dlen;
+    node->data.dlen = nd->dlen;
+    
+    return 0;
+}
+
+static list_node_t *node_get(list_t *l, int index)
+{
+    int idx=0;
+    dlist_t *dl=&l->used;
+    list_node_t *tmp=dl->head;
+    
+    if(index==0) {
+        return dl->head;
+    }
+    else if(index==dl->size-1) {
+        return dl->tail;
+    }
+    else {
+        while(tmp) {
+            if(idx==index) {
+                return tmp;
+            }
+            tmp = tmp->next;
+            idx++;
+        }
+    }
+    
+    return NULL;
+}
+static int node_swap(list_node_t *n1, list_node_t *n2)
+{
+    if(!n1 || !n2) {
+        return -1;;
+    }
+    
+    node_t x=n1->data;
+    n1->data = n2->data;
+    n2->data = x;
+    
+    return 0;
+}
+
+///////////////////////////////////////////////////////////
+handle_t list_init(list_cfg_t *cfg)
+{
+    list_t *l=NULL;
+    
+    if (!cfg)
+        return NULL;
+    
+    l = MALLOC(sizeof(list_t));
+    if (!l)
+        return NULL;
+    
+    l->used.head = NULL;
+    l->used.tail = NULL;
+    l->used.size = 0;
+    l->lock = lock_init();
+    l->cfg = *cfg;
+    
+    l->free.head = NULL;
+    l->free.tail = NULL;
+    l->free.size = 0;
+    
+    return l;
+}
+
+
+int list_free(handle_t l)
+{
+    int i;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_free lock failed\n");
+        return -1;
+    }
+    
+    xd = hl->used.head;
+    while(xd) {
+        node_free(hl, xd);
+        xd = xd->next;
+    }
+    
+    xd = hl->free.head;
+    while(xd) {
+        node_free(hl, xd);
+        xd = xd->next;
+    }
+    lock_off(hl->lock);
+    
+    lock_free(hl->lock);
+    free(hl->free.head);
+    free(hl);
+    
+    return 0;
+}
+
+
+int list_get_node(handle_t l, list_node_t **lnode, int index)
+{
+    int r=-1;
+    list_node_t *ln=NULL;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode || index<0) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_get lock failed\n");
+        return -1;
+    }
+    
+    if (hl->used.size<=0 || index>=hl->used.size) {
+        goto quit;
+    }
+    
+    ln = node_get(hl, index);
+    if(!ln) {
+        goto quit;
+    }
+    
+    *lnode = ln;
+    r = 0;
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int list_set_node(handle_t l, list_node_t *lnode, int index)
+{
+    int r=-1;
+    list_node_t *ln=NULL;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode || index<0) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_set lock failed\n");
+        return -1;
+    }
+    
+    if (hl->used.size<=0 || index>=hl->used.size) {
+        goto quit;
+    }
+    
+    ln = node_get(hl, index);
+    if(ln) {
+        r = node_set(hl, ln, &lnode->data);
+    }
+    
+quit:
+    lock_off(hl->lock);    
+    return r;
+}
+
+
+int list_take_node(handle_t l, list_node_t **lnode, int index)
+{
+    int r=-1;
+    list_node_t *ln=NULL;
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode || index<0) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_take_node lock failed\n");
+        return -1;
+    }
+    
+    if (hl->used.size<=0 || index>=hl->used.size) {
+       goto quit;
+    }
+    
+    ln = node_get(hl, index);
+    if(!ln) {
+        goto quit;
+    }
+    *lnode = ln;
+    r = node_remove(hl, ln, 0);
+
+quit:
+    lock_off(hl->lock);    
+    return r;
+}
+
+
+int list_back_node(handle_t l, list_node_t *lnode)
+{
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_back_node lock failed\n");
+        return -1;
+    }
+    
+    node_to_free(l, lnode);
+    lock_off(hl->lock);
+    
+    return 0;
+}
+
+
+int list_discard_node(handle_t l, list_node_t *lnode)
+{
+    list_t *hl=(list_t*)l;
+    
+    if(!hl || !lnode) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_discard_node lock failed\n");
+        return -1;
+    }
+    node_free(l, lnode);
+    
+    lock_off(hl->lock);
+    return 0;
+}
+
+
+int list_insert(handle_t l, node_t *node, int index)
+{
+    int r=-1;
+    list_t *hl=(list_t*)l;
+    list_node_t *xd,*tmp;
+    
+    if(!hl || !node) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___list_insert lock failed\n");
+        return -1;
+    }
+    
+    if (index>hl->used.size) {
+        if (hl->cfg.log) LOGE("___list_insert, invalid index, size: %d, index: %d\n", hl->used.size, index);
+        goto quit;
+    }
+    
+    if (hl->cfg.max>0 && hl->used.size>=hl->cfg.max) {
+        //����װ��ʱ, ���ݲ��Զ�����
+        //���Ҫ�����λ��Ϊĩβ, ����
+        if(index<0 || index>=hl->used.size-1) {
+            if(hl->cfg.mode==LIST_FULL_FILO) { //����Ϊ��������ʱ
+                if (hl->cfg.log) {
+                    //LOGW("___list_insert, list full, discard the new data\n");
+                }
+                r = -2; goto quit;
+            }
+            
+            if (hl->cfg.log) {
+                //LOGW("___list_insert, list full, discard the old data\n");
+            }
+            
+            xd = node_get(hl, 0);              //�����ϵ����ݶ�
+            node_remove(hl, xd, 1);
+        }
+        else {  //�������λ��λ���м�, ���趪���һ������
+            if (hl->cfg.log) {
+                LOGW("___list_insert, insert to the middle, discard the last data\n");
+            }
+            
+            xd = node_get(hl, hl->used.size-1);
+            node_remove(hl, xd, 1);
+        }
+    }
+    
+    tmp = node_new(hl, node);
+    if(!tmp) {
+        if (hl->cfg.log) LOGE("___list_insert, malloc %d error, l: 0x%08x, used.size: %d, free.size: %d\n", node->dlen, (uint32_t)hl, hl->used.size, hl->free.size);
+        goto quit;
+    }
+    r = node_insert(l, tmp, index);
+
+quit:
+    lock_off(hl->lock);
+    
+    return r;
+}
+
+
+int list_insert_node(handle_t l, list_node_t *lnode, int index)
+{
+    int r=-1;
+    list_t *hl=(list_t*)l;
+    list_node_t *xd,*tmp=lnode;
+    
+    if(!hl || !lnode) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_addto lock failed\n");
+        return -1;
+    }
+    
+    if (index>hl->used.size) {
+        if (hl->cfg.log) LOGE("list_addto, invalid index, size: %d, index: %d\n", hl->used.size, index);
+        goto quit;
+    }
+    
+    if (hl->cfg.max>0 && hl->used.size>=hl->cfg.max) {
+        //����װ��ʱ, ���ݲ��Զ�����
+        //���Ҫ�����λ��Ϊĩβ, ����
+        if(index<0 || index>=hl->used.size-1) {
+            if(hl->cfg.mode==LIST_FULL_FILO) { //����Ϊ��������ʱ
+                r = 0; goto quit;
+            }
+            xd = node_get(hl, 0);              //�����ϵ����ݶ�
+            node_remove(hl, xd, 1);
+        }
+        else {  //�������λ��λ���м�, ���趪���һ������
+            xd = node_get(hl, hl->used.size-1);
+            node_remove(hl, xd, 1);
+        }
+    }
+    r = node_insert(l, lnode, index);
+
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int list_append(handle_t l, int tp, void *data, int len)
+{
+    node_t node={tp, data, len, len};
+    
+    return list_insert(l, &node, -1);
+}
+
+
+int list_append_node(handle_t l, list_node_t *lnode)
+{
+    return list_insert_node(l, lnode, -1);
+}
+
+
+int list_infront(handle_t l, int tp, void *data, int len)
+{
+    node_t node={tp, data, len, len};
+    
+    return list_insert(l, &node, 0);
+}
+
+
+int list_infront_node(handle_t l, list_node_t *lnode)
+{
+    return list_insert_node(l, lnode, 0);
+}
+
+
+int list_remove(handle_t l, int index)
+{
+    int r=-1;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_remove lock failed\n");
+        return -1;
+    }
+    
+    xd = node_get(l, index);
+    if(!xd) {
+        goto quit;
+    }
+    r = node_remove(hl, xd, 1);
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+
+int list_delete(handle_t l, int index)
+{
+    int r=-1;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_delete lock failed\n");
+        return -1;
+    }
+    
+    if(hl->used.size<=0 || index>=hl->used.size) {
+        goto quit;
+    }
+    
+    xd = node_get(l, index);
+    r = node_free(hl, xd);
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int list_sort(handle_t l, int order)
+{
+    int r=-1;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl || order>=LIST_SORT_MAX) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_sort lock failed\n");
+        return -1;
+    }
+    
+    if(hl->used.size<2) {
+        goto quit;
+    }
+    
+    {
+        int len,cmp;
+        dlist_t *dl=&hl->used;
+        list_node_t *p2,*p1=dl->head;
+        
+        while(p1) {
+            p2 = p1->next;
+            while(p2) {
+                len = MIN(p1->data.dlen, p2->data.dlen);
+                cmp = memcmp(p1->data.buf, p2->data.buf, len);
+                if(((cmp>0) && (order==LIST_SORT_ASCEND)) || ((cmp<0) && (order==LIST_SORT_DESCEND))) {
+                    node_swap(p1, p2);
+                }
+                
+                p2 = p2->next;
+            }
+            p1 = p1->next;
+        }  
+    }
+    r = 0;
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+int list_size(handle_t l)
+{
+    int size=0;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_size lock failed\n");
+        return -1;
+    }
+    
+    size = hl->used.size;
+    lock_off(hl->lock);
+    
+    return size;
+}
+
+
+int list_clear(handle_t l)
+{
+    int r=-1;
+    list_node_t *xd;
+    list_t *hl=(list_t*)l;
+    
+    if (!hl) {
+        return -1;
+    }
+    
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_clear lock failed\n");
+        return -1;
+    }
+    
+    if(hl->used.size<=0) {
+        goto quit;
+    }
+    
+    xd = hl->used.head;
+    while(xd) {
+        node_remove(hl, xd, 1);
+        xd = xd->next;
+    }
+    hl->used.size = 0;
+    hl->used.head = NULL;
+    hl->used.tail = NULL;
+    r = 0;
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+
+
+
+int list_iterator(handle_t l, node_t *node, list_callback_t callback, void *arg)
+{
+    int r=-1,act=0;
+    list_node_t *xd=NULL;
+    list_t *hl=(list_t*)l;
+    dlist_t *dl=NULL;
+
+    if (!hl) {
+        return -1;
+    }
+
+    if(lock_on(hl->lock)) {
+        if (hl->cfg.log) LOGE("___ list_iterator lock failed\n");
+        return -1;
+    }
+
+    dl = &hl->used;
+    if (dl->size<=0) {
+        goto quit;
+    }
+
+    xd = dl->head;
+    while (xd) {
+        if (callback) {
+            act = LIST_ACT_NONE;
+            r = callback(hl, node, &xd->data, arg, &act);
+            if(act==LIST_ACT_STOP) {
+                break;
+            }
+            else if(act==LIST_ACT_REMOVE) {
+                node_remove(l, xd, 1);
+            }
+            else if(act==LIST_ACT_DELETE) {
+                node_remove(l, xd, 2);
+            }
+        }
+        xd = xd->next;
+    }
+    
+quit:
+    lock_off(hl->lock);
+    return r;
+}
+

+ 93 - 0
f407/applications/list.h

@@ -0,0 +1,93 @@
+#ifndef __LIST_Hx__
+#define __LIST_Hx__
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* handle_t;
+
+enum {
+    LIST_FULL_FIFO=0,
+    LIST_FULL_FILO,
+};
+
+enum {
+    LIST_SORT_ASCEND=0,
+    LIST_SORT_DESCEND,
+    
+    LIST_SORT_MAX
+};
+
+enum {
+    LIST_ACT_NONE=0,
+    LIST_ACT_STOP,
+    LIST_ACT_REMOVE,
+    LIST_ACT_DELETE,
+};
+
+typedef struct {
+    int  tp;            //type
+    void *buf;
+    int  dlen;          //data len
+    int  blen;          //buf len
+}node_t;
+
+
+typedef struct list_node {
+    node_t              data;
+    struct list_node    *prev;
+    struct list_node    *next;
+}list_node_t;
+
+typedef struct {
+    int         log;        //0:disable  1: enable
+    int         mode;
+    int         max;        //the max count
+}list_cfg_t;
+
+
+
+//该函数返回负值是表示结束,将退出迭代循环
+//该函数返回值>=0将继续迭代至结束
+typedef int (*list_callback_t)(handle_t l, node_t *node, node_t *xd, void *arg, int *act);
+
+
+handle_t list_init(list_cfg_t *cfg);
+int list_free(handle_t l);
+int list_get_node(handle_t l, list_node_t **lnode, int index);
+int list_set_node(handle_t l, list_node_t  *lnode, int index);
+
+int list_take_node(handle_t l, list_node_t **lnode, int index);
+int list_back_node(handle_t l, list_node_t *lnode);
+int list_discard_node(handle_t l, list_node_t *lnode);
+
+int list_insert(handle_t l, node_t *node, int index);
+int list_insert_node(handle_t l, list_node_t *lnode, int index);
+
+int list_append(handle_t l, int tp, void *data, int len);
+int list_append_node(handle_t l, list_node_t *lnode);
+
+int list_infront(handle_t l, int tp, void *data, int len);
+int list_infront_node(handle_t l, list_node_t *lnode);
+
+int list_remove(handle_t l, int index);
+int list_delete(handle_t l, int index);
+
+int list_sort(handle_t l, int order);
+int list_size(handle_t l);
+int list_clear(handle_t l);
+int list_iterator(handle_t l, node_t *node, list_callback_t callback, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+

+ 147 - 2
f407/applications/mb.c

@@ -1,16 +1,161 @@
 #include "mb.h"
+#include "list.h"
+#include "modbus.h"
 
+typedef struct {
+    mb_inst_t  *hinst;
+    uint8_t    type;
+    uint8_t    mode;
+    uint8_t    quit;
+    
+    rt_thread_t tid;
+    handle_t   rx;
+    handle_t   tx;
+    
+}mb_handle_t;
+static mb_handle_t mbHandle={0};
 
-int mb_init(void)
+typedef void (*thread_fn_t)(void *arg);
+
+
+static void mb_thread(void *arg)
 {
-    return 0;
+    mb_handle_t *h=(mb_handle_t*)arg;
+    while(h->quit==0) {
+        if(h->mode==MB_MODE_MASTER) {
+            
+        }
+        else {
+            mb_slave_fsm(h->hinst);
+        }
+    }
+    mb_destory(h->hinst);
+    
+    h->quit = 2;
+}
+
+static void mb_start(mb_handle_t *h, int flag)
+{
+    if(flag) {
+        h->tid = rt_thread_create(NULL, mb_thread, h, 2048, 5, 20);
+        if(h->tid==NULL) {
+            //LOG_E("___ thread create failed\n");
+        }
+        
+        h->quit = 0;
+        rt_thread_startup(h->tid);
+    }
+    else {
+        h->quit = 1;
+        while(h->quit!=2);
+        rt_thread_delete(h->tid);
+    }
+}
+
+
+void* mb_init(char *dev, int type, int mode)
+{
+    list_cfg_t lc={0,LIST_FULL_FIFO,10};
+    mb_handle_t *h=(mb_handle_t*)rt_malloc(sizeof(mb_handle_t));
+    
+    if(h) {
+        h->type = (type==MB_TYPE_RTU)?MB_BACKEND_TYPE_RTU:MB_BACKEND_TYPE_TCP;
+        h->mode = mode;
+        
+        mb_backend_param_t param = {
+            .rtu.dev = "uart2",
+            .rtu.baudrate = 9600,
+            .rtu.parity = 0,
+            .rtu.pin = -1,
+            .rtu.lvl = 0
+        };
+        h->rx = list_init(&lc);
+        h->tx = list_init(&lc);
+        
+        h->hinst = mb_create(h->type, &param);
+        if(h->mode==MB_MODE_MASTER) {
+            
+        }
+        else {
+            
+        }
+        
+        mb_start(h, 1);
+    }
+    
+    return h;
 }
 
 
+int mb_deinit(void *h)
+{
+    mb_handle_t *mh=(mb_handle_t*)h;
+    if(!mh) {
+        return -1;
+    }
+    mb_start(mh, 0);
+    list_free(mh->rx);
+    list_free(mh->tx);
+    rt_free(mh);
+    
+    return 0;
+}
 
 
+//
+
+int mb_read(void *h, void *data, int len, int timeout)
+{
+    int r=-1,sz=0;
+    mb_handle_t *mh=(mb_handle_t*)h;
+    
+    if(!mh || !data || len<=0) {
+        return -1;
+    }
+    
+    rt_tick_t end = rt_tick_get_millisecond()+timeout;
+    while(1) {
+        sz = list_size(mh->rx);
+        if(sz>0) {
+            break;
+        }
+        rt_thread_mdelay(1);
+        
+        if(timeout>0 && rt_tick_get_millisecond()>end) {
+            sz = list_size(mh->rx);
+            break;
+        }
+    }
+    
+    if(sz>0) {
+        list_node_t *ln=NULL;
+        r = list_take_node(mh->rx, &ln, 0);
+        if(r==0) {
+            node_t *nd=&ln->data;
+            
+            if(len>=nd->dlen) {
+                memcpy(data, nd->buf, nd->dlen);
+            }
+            else {
+                r = -1;
+            }
+            list_back_node(mh->rx, ln);
+        }
+    }
+    
+    return r;
+}
 
 
+int mb_write(void *h, void *data, int len)
+{
+    mb_handle_t *mh=(mb_handle_t*)h;
+    if(!mh) {
+        return -1;
+    }
+   
+    return list_append(mh->tx, 0, data, len);
+}
 
 
 

+ 20 - 3
f407/applications/mb.h

@@ -1,11 +1,28 @@
 #ifndef __MB_Hx__
 #define __MB_Hx__
 
-int mb_init(void);
-
-
+#include <stdint.h>
 
+enum {
+    MB_MODE_MASTER=0,
+    MB_MODE_SLAVE,
+};
+enum {
+    MB_TYPE_RTU=0,
+    MB_TYPE_TCP,
+};
+typedef struct {
+    char     dev[8];
+    uint8_t  type;
+    uint8_t  mode;
+    uint8_t  addr;
+    uint16_t port;
+}mb_para_t;
 
+void* mb_init(char *dev, int type, int mode);
+int mb_deinit(void *h);
+int mb_read(void *h, void *data, int len, int timeout);
+int mb_write(void *h, void *data, int len);
 
 #endif
 

+ 1 - 1
f407/applications/packages/qmodbus-latest/src/modbus.c

@@ -44,7 +44,7 @@ mb_inst_t * mb_create(mb_backend_type_t type, const mb_backend_param_t *param)
 
 
     hinst->saddr = MB_RTU_ADDR_DEF;
-    hinst->prot = type;
+    hinst->prot = (mb_prot_t)type;
     hinst->tid = 0;
     hinst->backend = backend;
     #ifdef MB_USING_SLAVE

+ 13 - 1
f407/applications/power.c

@@ -3,6 +3,15 @@
 #include "mongoose.h"
 
 
+
+
+
+
+
+
+
+
+
 static void *power_thread(void *arg)
 {
     thread_handle_t *th=(thread_handle_t*)arg;
@@ -18,9 +27,12 @@ static void *power_thread(void *arg)
 
 int power_init(void)
 {
-    thread_start();
+    //thread_start();
     return 0;
 }
 
 
 
+
+
+

+ 87 - 0
f407/applications/power.h

@@ -2,6 +2,93 @@
 #define __POWER_Hx__
 
 
+
+#define POWER_CHN_INFO                            0x0FA0          //获取继电器板类型通道
+#define POWER_AC_CUR_INFO_S                       0x0FAB          //单相小电流继电器信息,共8路继电器
+#define POWER_AC_STAT_INFO_S                      0x1071          //单相小电流继电器开关状态,共8路继电器
+#define POWER_AC_CUR_INFO_B                       0x1015          //单相大电流继电器信息,共4路继电器
+#define POWER_AC_STAT_INFO_B                      0x1083          //单相大电流继电器开关状态,共4路继电器
+#define POWER_AC_BRK_INFO                         0x10D6          //单相控制板开关检测信息
+#define POWER_AC_TOTAL_ALATRM                     0x10E0          //单相控制板总体报警信息 2024.11.12
+#define POWER_AC_START_DELAY_TIME_S               0x1194          //单相小电流继电器板开启延时
+#define POWER_AC_STOP_DELAY_TIME_S                0x11A6          //单相小电流继电器板关闭延时
+#define POWER_AC_START_DELAY_TIME_B               0x11B8          //单相大电流继电器板开启延时
+#define POWER_AC_STOP_DELAY_TIME_B                0x11C6          //单相大电流继电器板关闭延时
+#define POWER_AC_CHN_STAT_S                       0x11EA          //设置单相小电流通道开关状态
+#define POWER_AC_CHN_STAT_B                       0x11FC          //设置单相大电流通道开关状态
+#define POWER_AC_THRESHOLD_S                      0x1215          //设置单相小电流通道超限报警阈值
+#define POWER_AC_THRESHOLD_B                      0x129F          //设置单相大电流通道超限报警阈值X
+#define POWER_AC_KB_VAL_S                         0x1203          //设置单相小电流通道K、B值
+#define POWER_AC_KB_VAL_B                         0x124D          //设置单相大电流通道K、B值
+#define POWER_AC_RESET_CONSUMPTION                0x1400          //重置单相耗电量
+#define POWER_AC_ALARM_CTL                        0x13EC          //超限动作
+#define POWER_AC_TOTAL_THRESHOLD                  0x1450          //设置单相总超限报警阈值 2024.11.12
+#define POWER_AC_ALARM_TOTAL_CTL                  0x1482          //总体超限动作   2024.11.12       
+
+#define POWER_DC_STAT                             0x120A          //设置直流继电器开关状态
+#define POWER_DC_THRESHOLD                        0x12E9          //设置直流继电器超限报警X
+#define POWER_DC_KB_VAL                           0x136D          //设置直流通道K、B值
+#define POWER_DC_START_DELAY_TIME                 0x11D4          //直流继电器控制板开启延时
+#define POWER_DC_STOP_DELAY_TIME                  0x11DF          //直流继电器控制板关闭延时
+#define POWER_DC_OUT_INFO                         0x104F          //直流继电器电路控制板信息,采集一路输出
+#define POWER_DC_STAT_INFO                        0x1097          //直流继电器电路控制板开关状态,采集一路输出
+#define POWER_DC_IN_INFO                          0x105F          //直流总电流电压采集控制板,采集设备输入电压和输入电流
+
+#define POWER_DCP_TYPE_CHN_INFO                   0x1770          //获取直流PDU类型通道
+#define POWER_DCP_TOTAL_ALARM                     0x1776          //直流PDU总报警信息 2024.11.12
+#define POWER_DCP_OUT_INFO                        0x177A          //直流PDU输出
+#define POWER_DCP_STAT_INFO                       0x17E2          //直流PDU开关状
+#define POWER_DCP_WARNING                         0x179A          //直流PDU报警信息
+#define POWER_DCP_STAT_ERROR                      0x17E4          //直流PDU故障状态
+#define POWER_DCP_IN_INFO                         0x1772          //直流PDU采集输入电压与输入电
+#define POWER_DCP_START_DELAY_TIME                0x17E6          //直流PDU延时
+#define POWER_DCP_STOP_DELAY_TIME                 0x17F6          //直流PDU延时
+#define POWER_DCP_THRESHOLD_MAX_VOL               0x17A2          //max voltage threshold
+#define POWER_DCP_THRESHOLD_MIN_VOL               0x17B2          //min voltage threshold
+#define POWER_DCP_THRESHOLD_MAX_CUR               0x17C2          //max current threshold
+#define POWER_DCP_THRESHOLD_MIN_CUR               0x17D2          //max current threshold
+#define POWER_DCP_THRESHOLD_MAX_POWER             0x1810          //max power threshold
+#define POWER_DCP_THRESHOLD_MAX_POWERCON          0x181A          //max powercon threshold
+#define POWER_DCP_ALL_OPEN_INFO                   0x1806          //ALL OPEN直流PDU开关状
+#define POWER_DCP_ALL_CLOSE_INFO                  0x1807          //ALL OPEN直流PDU开关状
+#define POWER_DCP_ALARM_CTL                       0x182E          //超限动作
+#define POWER_DCP_RESET_CONSUMPTION   	          0x1838          //重置直流耗电量
+#define POWER_DCP_THRESHOLD_TOTAL_VOL_MAX         0x184C          //max total voltage threshold 2024.11.12
+#define POWER_DCP_THRESHOLD_TOTAL_VOL_MIN         0x184D          //min total voltage threshold 2024.11.12
+#define POWER_DCP_THRESHOLD_TOTAL_CUR_MAX         0x184E          //max total current threshold 2024.11.12
+#define POWER_DCP_THRESHOLD_TOTAL_PWR_MAX         0x184F          //max total power threshold 2024.11.12
+#define POWER_DCP_THRESHOLD_TOTAL_PWRCON_MAX      0x1850          //max total powercon threshold 2024.11.12
+#define POWER_DCP_ALARM_CTL_TOTAL                 0x1856          //总体超限动作   2024.11.12       
+
+#define POWER_AC3_TYPE_CHN_INFO                   0x1770          //获取三项类型通道
+#define POWER_AC3_IN_INFO                         0x1771          //三项交流输入
+#define POWER_AC3_OUT_INFO                        0x177D          //三项交流输出
+#define POWER_AC3_OUT_ENABLE                      0x182E          //三项交流输出按通道开关状态及控制使能
+#define POWER_AC3_NF_STATUS                       0x1837          //三项交流零线断路器状态
+#define POWER_AC3_CH_OUT_ENABLE                   0x183A          //三项交流输出按插头开关状态及控制使
+#define POWER_AC3_IN_ENABLE                       0x182D          //三项交流输入超限使能
+#define POWER_AC3_OUT_ERROR                       0x17DE          //三项交流输出故障状态
+#define POWER_AC3_IN_TOTAL_ERROR                  0x17CA          //三项交流总输入故障状态 2024.11.12 
+#define POWER_AC3_IN_ERROR                        0x17DD          //三项交流输入故障状态
+#define POWER_AC3_START_DELAY_TIME                0x1840          //三项交流延时
+#define POWER_AC3_STOP_DELAY_TIME                 0x184C          //三项交流延时
+#define POWER_AC3_THRESHOLD_IN                    0x17EA          //设置三项交流输入超限报警 
+#define POWER_AC3_THRESHOLD_OUT                   0x17EF          //设置三项交流输出超限报警
+#define POWER_AC3_ALL_OPEN_INFO                   0x182B          //ALL OPEN直流PDU开关状
+#define POWER_AC3_ALL_CLOSE_INFO                  0x182C          //ALL OPEN直流PDU开关状
+#define POWER_AC3_THRESHOLD_VOL_MAX               0x17EF          //max voltage threshold
+#define POWER_AC3_THRESHOLD_VOL_MIN               0x17FB          //min voltage threshold
+#define POWER_AC3_THRESHOLD_CUR_MAX               0x1807          //max current threshold
+#define POWER_AC3_THRESHOLD_PWR_MAX               0x1813          //max POWER threshold
+#define POWER_AC3_THRESHOLD_PWRCON_MAX            0x181F          //max PWRCON threshold
+#define POWER_AC3_ALARM_MISSING_PH                0x1856          //缺相报警
+#define POWER_AC3_TOTAL_ALARM_CTL                 0x185F          //总体超限动作 2024.11.12 
+#define POWER_AC3_ALARM_CTL                       0x1860          //超限动作
+#define POWER_AC3_RESET_CONSUMPTION_PH            0x189C          //重置PH耗电量
+#define POWER_AC3_RESET_CONSUMPTION               0x18A5          //重置all耗电量
+#define POWER_AC3_BREAKER_INFO                    0x17D4          //三相控制板开关检测信息
+
+
 int power_init(void);
 
 

+ 30 - 17
f407/applications/web.c

@@ -21,7 +21,8 @@ typedef struct {
 
 typedef struct {
     pthread_t       tid;
-
+    
+    struct mg_mgr   mgr;
 #ifdef USE_MG714
     mg_tls_t        tls;
 #else
@@ -53,17 +54,22 @@ static void http_fn(struct mg_connection *c, int ev, void *ev_data)
     if (ev == MG_EV_HTTP_REQUEST) {
         mg_serve_http(c, (struct http_message *)ev_data, h->opts);
     }
+    else if(ev == MG_EV_WEBSOCKET_FRAME) {
+        //
+        //
+    }
+    else {
+        //
+    }
 #endif
 }
 static void *web_thread(void *arg)
 {
-    thread_handle_t *th=(thread_handle_t*)arg;
-    
-    struct mg_mgr mgr;
     struct mg_connection *nc;
     const char *http_addr="http://[::]:80";
     const char *https_addr="https://[::]:443";
-    web_handle_t *h=&webHandle;
+    thread_handle_t *th=(thread_handle_t*)arg;
+    web_handle_t *h=(web_handle_t*)th->arg;
 
 #ifdef USE_MG714
     //mg_log_set(MG_LL_DEBUG);
@@ -86,21 +92,20 @@ static void *web_thread(void *arg)
     //mh->tls.key = mg_str(file_load2("/root/run/app/cert/server.key",0));
     //mh->tls.name = mg_url_host(https_addr);
 #else
-    mg_mgr_init(&mgr, NULL);
-    nc = mg_bind(&mgr, "80", http_fn);
+    mg_mgr_init(&h->mgr, NULL);
+    nc = mg_bind(&h->mgr, "80", http_fn);
 
     strcpy(h->rootDir, "/web");
     
     mg_set_protocol_http_websocket(nc);
     h->opts.document_root = h->rootDir;
     h->opts.enable_directory_listing = "yes";
-
-
 #endif
+    
     while(th->quit==0) {
-        mg_mgr_poll(&mgr, 200);
+        mg_mgr_poll(&h->mgr, 200);
     }
-    mg_mgr_free(&mgr);
+    mg_mgr_free(&h->mgr);
     
     pthread_exit(NULL);
 }
@@ -108,16 +113,24 @@ static void *web_thread(void *arg)
 
 int web_init(void)
 {
-    thread_start(THREAD_ID_WEB, web_thread, NULL);
+    web_handle_t *h=&webHandle;
+    
+    thread_start(THREAD_ID_WEB, web_thread, h);
     return 0;
 }
 
 
-
-
-
-
-
+int web_send(void *data, int len, int is_bin)
+{
+    struct mg_connection *c;
+    web_handle_t *h=&webHandle;
+    
+    for (c = mg_next(&h->mgr, NULL); c != NULL; c = mg_next(&h->mgr, c)) {
+        mg_send_websocket_frame(c, is_bin?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT, data, len);
+    }
+    
+    return 0;
+}
 
 
 

+ 1 - 1
f407/applications/web.h

@@ -2,7 +2,7 @@
 #define __WEB_Hx__
 
 int web_init(void);
-
+int web_send(void *data, int len, int is_bin);
 
 
 

+ 1 - 0
f407/project/all.uvmpw

@@ -15,6 +15,7 @@
 
   <project>
     <PathAndName>.\boot\boot.uvprojx</PathAndName>
+    <NodeIsExpanded>1</NodeIsExpanded>
   </project>
 
 </ProjectWorkspace>

Разница между файлами не показана из-за своего большого размера
+ 399 - 375
f407/project/app/app.uvoptx


+ 10 - 0
f407/project/app/app.uvprojx

@@ -434,6 +434,16 @@
               <FileType>5</FileType>
               <FilePath>..\..\applications\cfg.h</FilePath>
             </File>
+            <File>
+              <FileName>power.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\applications\power.c</FilePath>
+            </File>
+            <File>
+              <FileName>list.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\applications\list.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>