You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2015/11/10 09:00:33 UTC

[2/2] incubator-mynewt-larva git commit: add logging infrastructure, and write it to circular buffer memory

add logging infrastructure, and write it to circular buffer memory


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/05f17db2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/05f17db2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/05f17db2

Branch: refs/heads/master
Commit: 05f17db2ae3eae5cb539a0ce2393a8469e65be2f
Parents: 587dad2
Author: Sterling Hughes <st...@apache.org>
Authored: Tue Nov 10 00:00:10 2015 -0800
Committer: Sterling Hughes <st...@apache.org>
Committed: Tue Nov 10 00:00:23 2015 -0800

----------------------------------------------------------------------
 libs/util/include/util/cbmem.h |  61 +++++++++
 libs/util/include/util/log.h   |  64 +++++----
 libs/util/src/cbmem.c          | 265 ++++++++++++++++++++++++++++++++++++
 libs/util/src/log.c            | 229 ++++++++++++++++++-------------
 project/blinky/src/main.c      |  22 +--
 5 files changed, 500 insertions(+), 141 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05f17db2/libs/util/include/util/cbmem.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/cbmem.h b/libs/util/include/util/cbmem.h
new file mode 100644
index 0000000..e3347a5
--- /dev/null
+++ b/libs/util/include/util/cbmem.h
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __UTIL_CBMEM_H__ 
+#define __UTIL_CBMEM_H__
+
+#include <os/os.h>
+
+struct cbmem_entry_hdr {
+    uint16_t ceh_len;
+    uint16_t ceh_flags;
+};
+
+struct cbmem {
+    struct os_mutex c_lock;
+
+    struct cbmem_entry_hdr *c_entry_start;
+    struct cbmem_entry_hdr *c_entry_end;
+    uint8_t *c_buf;
+    uint8_t *c_buf_end;
+    uint8_t *c_buf_cur_end;
+};
+
+struct cbmem_iter {
+    struct cbmem_entry_hdr *ci_start;
+    struct cbmem_entry_hdr *ci_cur;
+    struct cbmem_entry_hdr *ci_end;
+};
+
+#define CBMEM_ENTRY_SIZE(__p) (sizeof(struct cbmem_entry_hdr) \
+        + ((struct cbmem_entry_hdr *) (__p))->ceh_len)
+#define CBMEM_ENTRY_NEXT(__p) ((struct cbmem_entry_hdr *) \
+        ((uint8_t *) (__p) + CBMEM_ENTRY_SIZE(__p)))
+
+typedef int (*cbmem_walk_func_t)(struct cbmem *, struct cbmem_entry_hdr *, 
+        void *arg);
+
+int cbmem_lock_acquire(struct cbmem *cbmem);
+int cbmem_lock_release(struct cbmem *cbmem);
+int cbmem_init(struct cbmem *cbmem, void *buf, uint32_t buf_len);
+int cbmem_append(struct cbmem *cbmem, void *data, uint16_t len);
+void cbmem_iter_start(struct cbmem *cbmem, struct cbmem_iter *iter);
+struct cbmem_entry_hdr *cbmem_iter_next(struct cbmem *cbmem, 
+        struct cbmem_iter *iter);
+int cbmem_read(struct cbmem *cbmem, struct cbmem_entry_hdr *hdr, void *buf, 
+        uint16_t off, uint16_t len);
+int cbmem_flush(struct cbmem *);
+
+#endif /* __UTIL_CBMEM_H__ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05f17db2/libs/util/include/util/log.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/log.h b/libs/util/include/util/log.h
index 1b4ca27..b1b64d7 100644
--- a/libs/util/include/util/log.h
+++ b/libs/util/include/util/log.h
@@ -16,48 +16,46 @@
 #ifndef __UTIL_LOG_H__ 
 #define __UTIL_LOG_H__
 
-typedef int32_t ul_off_t;
-
-/* Forward declare for function pointers */
-struct ul_storage;
-
-typedef int (*ul_storage_read_func_t)(struct ul_storage *, ul_off_t off, 
-        void *buf, int len);
-typedef int (*ul_storage_write_func_t)(struct ul_storage *, ul_off_t off, 
-        void *buf, int len);
-typedef int (*ul_storage_size_func_t)(struct ul_storage *uls, ul_off_t *size);
-
-struct uls_mem {
-    uint8_t *um_buf;
-    ul_off_t um_buf_size;
-};
-
-struct ul_storage {
-    ul_storage_read_func_t uls_read;
-    ul_storage_write_func_t uls_write;
-    ul_storage_size_func_t uls_size;
-    void *uls_arg;
+#include "util/cbmem.h"
+#include <os/queue.h>
+
+struct util_log;
+
+typedef int (*util_log_walk_func_t)(struct util_log *, void *arg, void *offset, 
+        uint16_t len);
+
+typedef int (*ulh_read_func_t)(struct util_log *, void *dptr, void *buf, 
+        uint16_t offset, uint16_t len);
+typedef int (*ulh_append_func_t)(struct util_log *, void *buf, int len);
+typedef int (*ulh_walk_func_t)(struct util_log *, 
+        util_log_walk_func_t walk_func, void *arg);
+typedef int (*ulh_flush_func_t)(struct util_log *);
+
+struct ul_handler {
+    ulh_read_func_t ulh_read;
+    ulh_append_func_t ulh_append;
+    ulh_walk_func_t ulh_walk;
+    ulh_flush_func_t ulh_flush;
+    void *ulh_arg;
 };
 
 struct ul_entry_hdr {
-    uint64_t ue_ts;
-    uint16_t ue_len;
-    uint16_t ue_flags;
+    int64_t ue_ts;
 }; 
-#define UL_ENTRY_SIZE(__ue) (sizeof(struct ul_entry_hdr) + (__ue)->ue_len)
 
 struct util_log {
     char *ul_name;
-    struct ul_storage *ul_uls;
-    ul_off_t ul_start_off;
-    ul_off_t ul_last_off;
-    ul_off_t ul_cur_end_off;
-    ul_off_t ul_end_off;
+    struct ul_handler *ul_ulh;
     STAILQ_ENTRY(util_log) ul_next;
 };
 
-int uls_mem_init(struct ul_storage *uls, struct uls_mem *umem);
-int util_log_register(char *name, struct util_log *log, struct ul_storage *uls);
-int util_log_write(struct util_log *log, uint8_t *data, uint16_t len);
+int util_log_cbmem_handler_init(struct ul_handler *, struct cbmem *);
+int util_log_register(char *name, struct util_log *log, struct ul_handler *);
+int util_log_append(struct util_log *log, uint8_t *data, uint16_t len);
+int util_log_read(struct util_log *log, void *dptr, void *buf, uint16_t off, 
+        uint16_t len);
+int util_log_walk(struct util_log *log, util_log_walk_func_t walk_func, 
+        void *arg);
+int util_log_flush(struct util_log *log);
 
 #endif /* __UTIL_LOG_H__ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05f17db2/libs/util/src/cbmem.c
----------------------------------------------------------------------
diff --git a/libs/util/src/cbmem.c b/libs/util/src/cbmem.c
new file mode 100644
index 0000000..945270e
--- /dev/null
+++ b/libs/util/src/cbmem.c
@@ -0,0 +1,265 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <os/os.h>
+#include <string.h>
+
+#include "util/cbmem.h" 
+
+
+int 
+cbmem_init(struct cbmem *cbmem, void *buf, uint32_t buf_len)
+{
+    os_mutex_init(&cbmem->c_lock);
+
+    memset(cbmem, 0, sizeof(*cbmem));
+    cbmem->c_buf = buf;
+    cbmem->c_buf_end = buf + buf_len;
+
+    return (0);
+}
+
+int 
+cbmem_lock_acquire(struct cbmem *cbmem) 
+{
+    int rc;
+
+    if (!os_started()) {
+        return (0);
+    }
+
+    rc = os_mutex_pend(&cbmem->c_lock, OS_WAIT_FOREVER);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int 
+cbmem_lock_release(struct cbmem *cbmem)
+{
+    int rc;
+
+    if (!os_started()) {
+        return (0);
+    }
+
+    rc = os_mutex_release(&cbmem->c_lock);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+
+int 
+cbmem_append(struct cbmem *cbmem, void *data, uint16_t len)
+{
+    struct cbmem_entry_hdr *dst;
+    uint8_t *start;
+    uint8_t *end;
+    int rc;
+
+    rc = cbmem_lock_acquire(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    if (cbmem->c_entry_end) {
+        dst = CBMEM_ENTRY_NEXT(cbmem->c_entry_end);
+    } else {
+        dst = (struct cbmem_entry_hdr *) cbmem->c_buf;
+    }
+    end = (uint8_t *) dst + len;
+
+    /* If this item would take us past the end of this buffer, then adjust 
+     * the item to the beginning of the buffer.
+     */
+    if (end > cbmem->c_buf_end) {
+        cbmem->c_buf_cur_end = (uint8_t *) dst;
+        dst = (struct cbmem_entry_hdr *) cbmem->c_buf;
+        end = (uint8_t *) dst + len;
+        if ((uint8_t *) cbmem->c_entry_start >= cbmem->c_buf_cur_end) {
+            cbmem->c_entry_start = (struct cbmem_entry_hdr *) cbmem->c_buf;
+        }
+    }
+
+    /* If the destination is prior to the start, and would overrwrite the 
+     * start of the buffer, move start forward until you don't overwrite it
+     * anymore.
+     */
+    start = (uint8_t *) cbmem->c_entry_start;
+    if (start && (uint8_t *) dst < start + CBMEM_ENTRY_SIZE(start) && 
+            end > start) {
+        while (start < end) {
+            start = (uint8_t *) CBMEM_ENTRY_NEXT(start);
+            if (start == cbmem->c_buf_cur_end) {
+                start = cbmem->c_buf;
+                break;
+            }
+        }
+        cbmem->c_entry_start = (struct cbmem_entry_hdr *) start;
+    }
+
+    /* Copy the entry into the log 
+     */
+    dst->ceh_len = len;
+    memcpy((uint8_t *) dst + sizeof(*dst), data, len);
+
+    cbmem->c_entry_end = dst;
+    if (!cbmem->c_entry_start) {
+        cbmem->c_entry_start = dst;
+    }
+
+    rc = cbmem_lock_release(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (-1);
+}
+
+void 
+cbmem_iter_start(struct cbmem *cbmem, struct cbmem_iter *iter)
+{
+    iter->ci_start = cbmem->c_entry_start;
+    iter->ci_cur = cbmem->c_entry_start;
+    iter->ci_end = cbmem->c_entry_end;
+}
+
+struct cbmem_entry_hdr *
+cbmem_iter_next(struct cbmem *cbmem, struct cbmem_iter *iter)
+{
+    struct cbmem_entry_hdr *hdr;
+
+    if (iter->ci_start > iter->ci_end) {
+        hdr = iter->ci_cur;
+        iter->ci_cur = CBMEM_ENTRY_NEXT(iter->ci_cur);
+
+        if ((uint8_t *) iter->ci_cur == cbmem->c_buf_cur_end) {
+            iter->ci_cur = (struct cbmem_entry_hdr *) cbmem->c_buf;
+            iter->ci_start = (struct cbmem_entry_hdr *) cbmem->c_buf;
+        }
+    } else {
+        hdr = iter->ci_cur;
+        if (hdr == CBMEM_ENTRY_NEXT(iter->ci_end)) {
+            hdr = NULL;
+        } else {
+            iter->ci_cur = CBMEM_ENTRY_NEXT(iter->ci_cur);
+        }
+    }
+
+    return (hdr);
+}
+
+int
+cbmem_flush(struct cbmem *cbmem)
+{
+    int rc;
+
+    rc = cbmem_lock_acquire(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    cbmem->c_entry_start = NULL;
+    cbmem->c_entry_end = NULL;
+    cbmem->c_buf_cur_end = NULL;
+
+    rc = cbmem_lock_release(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int 
+cbmem_read(struct cbmem *cbmem, struct cbmem_entry_hdr *hdr, void *buf, 
+        uint16_t off, uint16_t len)
+{
+    int rc;
+
+    rc = cbmem_lock_acquire(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    /* Only read the maximum number of bytes, if we exceed that, 
+     * truncate the read.
+     */
+    if (off + len > hdr->ceh_len) {
+        len = hdr->ceh_len - off;
+    }
+
+    memcpy(buf, (uint8_t *) hdr + sizeof(*hdr) + off, len);
+
+    rc = cbmem_lock_release(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (len);
+err:
+    return (-1);
+}
+
+
+int 
+cbmem_walk(struct cbmem *cbmem, cbmem_walk_func_t walk_func, 
+        void *arg)
+{
+    struct cbmem_entry_hdr *hdr;
+    struct cbmem_iter iter;
+    int rc;
+
+    rc = cbmem_lock_acquire(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    cbmem_iter_start(cbmem, &iter);
+    while (1) {
+        hdr = cbmem_iter_next(cbmem, &iter);
+        if (hdr == NULL) {
+            break;
+        }
+
+        rc = walk_func(cbmem, hdr, arg);
+        if (rc == 1) {
+            break;
+        }
+    }
+
+    rc = cbmem_lock_release(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05f17db2/libs/util/src/log.c
----------------------------------------------------------------------
diff --git a/libs/util/src/log.c b/libs/util/src/log.c
index 1e4ced9..a898e22 100644
--- a/libs/util/src/log.c
+++ b/libs/util/src/log.c
@@ -19,6 +19,9 @@
 #include <string.h>
 
 #include "util/log.h" 
+#include "util/cbmem.h" 
+
+#include <stdio.h>
 
 #ifdef SHELL_PRESENT
 
@@ -27,6 +30,7 @@
 
 struct shell_cmd shell_log_cmd;
 int shell_registered;
+
 #endif 
 
 static STAILQ_HEAD(, util_log) g_util_log_list = 
@@ -34,90 +38,126 @@ static STAILQ_HEAD(, util_log) g_util_log_list =
 
 
 #ifdef SHELL_PRESENT 
-static void 
-shell_dump_log(struct util_log *log)
+
+static int 
+shell_log_dump_entry(struct util_log *log, void *arg, void *dptr, uint16_t len) 
 {
-    struct ul_entry_hdr hdr; 
-    struct ul_storage *uls;
-    uint8_t bla[256];
-    ul_off_t cur_off;
+    struct ul_entry_hdr ueh;
+    char data[128];
+    int dlen;
     int rc;
 
-    uls = log->ul_uls;
-
-    cur_off = log->ul_start_off;
-
-    while (cur_off < log->ul_cur_end_off) {
-        rc = uls->uls_read(uls, cur_off, &hdr, sizeof(hdr));
-        if (rc != 0) {
-            goto err;
-        }
+    printf("Dumping shell!\n");
 
-        rc = uls->uls_read(uls, cur_off + sizeof(hdr), bla, 
-                hdr.ue_len);
-        if (rc != 0) {
-            goto err;
-        }
-        bla[hdr.ue_len] = 0;
+    rc = util_log_read(log, dptr, &ueh, 0, sizeof(ueh)); 
+    printf("rc = %d\n", rc);
+    if (rc != sizeof(ueh)) {
+        goto err;
+    }
 
-        console_printf("[%d] [%d] [%x] %s", hdr.ue_ts, hdr.ue_len, 
-                hdr.ue_flags, bla);
+    dlen = min(len-sizeof(ueh), 128);
+    printf("Reading %d bytes of data\n", dlen);
 
-        cur_off += UL_ENTRY_SIZE(&hdr);
+    rc = util_log_read(log, dptr, data, sizeof(ueh), dlen);
+    printf("rc2 = %d, dlen = %d\n", rc, dlen);
+    if (rc < 0) {
+        goto err;
     }
+    data[rc] = 0;
 
-    return;
+    console_printf("[%d] %s\n", (uint32_t) ueh.ue_ts, data);
+
+    return (0);
 err:
-    return;
+    return (rc);
 }
 
 static int 
 shell_log_dump_all(char **argv, int argc)
 {
     struct util_log *log;
+    int rc;
 
     STAILQ_FOREACH(log, &g_util_log_list, ul_next) {
-        shell_dump_log(log);
+        rc = util_log_walk(log, shell_log_dump_entry, NULL);
+        if (rc != 0) {
+            goto err;
+        }
     }
 
     return (0);
+err:
+    return (rc);
 }
+
 #endif 
 
 static int 
-uls_mem_read(struct ul_storage *uls, ul_off_t off, void *buf, int len)
+ulh_cbmem_append(struct util_log *log, void *buf, int len) 
 {
-    struct uls_mem *umem;
+    struct cbmem *cbmem;
     int rc;
 
-    umem = (struct uls_mem *) uls->uls_arg;
+    cbmem = (struct cbmem *) log->ul_ulh->ulh_arg;
 
-    if (off + len > umem->um_buf_size) {
-        rc = -1;
+    rc = cbmem_append(cbmem, buf, len);
+    if (rc != 0) {
         goto err;
     }
 
-    memcpy(buf, umem->um_buf + off, len);
-
     return (0);
 err:
     return (rc);
 }
 
 static int 
-uls_mem_write(struct ul_storage *uls, ul_off_t off, void *buf, int len)
+ulh_cbmem_read(struct util_log *log, void *dptr, void *buf, uint16_t offset, 
+        uint16_t len) 
 {
-    struct uls_mem *umem;
+    struct cbmem *cbmem;
+    struct cbmem_entry_hdr *hdr;
     int rc;
 
-    umem = (struct uls_mem *) uls->uls_arg;
+    cbmem = (struct cbmem *) log->ul_ulh->ulh_arg;
+    hdr = (struct cbmem_entry_hdr *) dptr;
+
+    rc = cbmem_read(cbmem, hdr, buf, offset, len);
+
+    return (rc);
+}
+
+static int 
+ulh_cbmem_walk(struct util_log *log, util_log_walk_func_t walk_func, void *arg)
+{
+    struct cbmem *cbmem;
+    struct cbmem_entry_hdr *hdr;
+    struct cbmem_iter iter;
+    int rc;
 
-    if (off + len > umem->um_buf_size) {
-        rc = -1;
+    cbmem = (struct cbmem *) log->ul_ulh->ulh_arg;
+
+    rc = cbmem_lock_acquire(cbmem);
+    if (rc != 0) {
         goto err;
     }
+    
+    cbmem_iter_start(cbmem, &iter);
+    while (1) {
+        hdr = cbmem_iter_next(cbmem, &iter);
+        if (!hdr) {
+            break;
+        }
 
-    memcpy(umem->um_buf + off, buf, len);
+        rc = walk_func(log, arg, (void *) hdr, hdr->ceh_len);
+        if (rc == 1) {
+            break;
+        }
+    }
+
+    rc = cbmem_lock_release(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
 
     return (0);
 err:
@@ -125,30 +165,38 @@ err:
 }
 
 static int 
-uls_mem_size(struct ul_storage *uls, ul_off_t *size)
+ulh_cbmem_flush(struct util_log *log)
 {
-    *size = ((struct uls_mem *) uls->uls_arg)->um_buf_size;
+    struct cbmem *cbmem;
+    int rc;
+
+    cbmem = (struct cbmem *) log->ul_ulh->ulh_arg;
+    
+    rc = cbmem_flush(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
 
     return (0);
+err:
+    return (rc);
 }
 
-
 int 
-uls_mem_init(struct ul_storage *uls, struct uls_mem *umem)
+util_log_cbmem_handler_init(struct ul_handler *handler, struct cbmem *cbmem)
 {
-    uls->uls_arg = umem;
-    uls->uls_read = uls_mem_read;
-    uls->uls_write = uls_mem_write;
-    uls->uls_size = uls_mem_size;
+    handler->ulh_read = ulh_cbmem_read;
+    handler->ulh_append = ulh_cbmem_append;
+    handler->ulh_walk = ulh_cbmem_walk;
+    handler->ulh_flush = ulh_cbmem_flush;
+    handler->ulh_arg = (void *) cbmem;
 
     return (0);
 }
 
 int 
-util_log_register(char *name, struct util_log *log, struct ul_storage *uls)
+util_log_register(char *name, struct util_log *log, struct ul_handler *ulh)
 {
-    int rc;
-
 #ifdef SHELL_PRESENT 
     if (!shell_registered) {
         /* register the shell */
@@ -159,84 +207,69 @@ util_log_register(char *name, struct util_log *log, struct ul_storage *uls)
 #endif
 
     log->ul_name = name;
-    log->ul_start_off = 0;
-    log->ul_last_off = -1;
-    log->ul_cur_end_off = -1;
-
-    log->ul_uls = uls;
-
-    rc = uls->uls_size(uls, &log->ul_end_off);
-    if (rc != 0) {
-        goto err;
-    }
+    log->ul_ulh = ulh;
 
     STAILQ_INSERT_TAIL(&g_util_log_list, log, ul_next);
 
     return (0);
-err:
-    return (rc);
 }
 
-
-static int
-ul_insert_next(struct util_log *log, struct ul_entry_hdr *ue, 
-        uint8_t *data)
+int
+util_log_append(struct util_log *log, uint8_t *data, uint16_t len)
 {
-    struct ul_storage *uls;
-    struct ul_entry_hdr last;
-    ul_off_t write_off;
+    struct ul_entry_hdr *ue;
     int rc;
 
-    uls = log->ul_uls;
-
-    if (log->ul_last_off != -1) {
-        rc = uls->uls_read(uls, log->ul_last_off, &last, sizeof(last));
-        if (rc != 0) {
-            goto err;
-        }
-
-        write_off = log->ul_last_off + UL_ENTRY_SIZE(&last);
-    } else {
-        write_off = 0;
-    }
+    ue = (struct ul_entry_hdr *) data;
+    ue->ue_ts = (int64_t) os_time_get();
 
-    rc = uls->uls_write(uls, write_off, ue, sizeof(*ue));
+    rc = log->ul_ulh->ulh_append(log, data, len + sizeof(*ue));
     if (rc != 0) {
         goto err;
     }
 
-    rc = uls->uls_write(uls, write_off + sizeof(*ue), 
-            data, ue->ue_len);
+    return (0);
+err:
+    return (rc);
+}
+
+int 
+util_log_walk(struct util_log *log, util_log_walk_func_t walk_func, void *arg)
+{
+    int rc;
+
+    rc = log->ul_ulh->ulh_walk(log, walk_func, arg);
     if (rc != 0) {
         goto err;
     }
 
-    log->ul_last_off = write_off;
-    log->ul_cur_end_off = write_off + UL_ENTRY_SIZE(ue);
-
     return (0);
 err:
     return (rc);
 }
 
-int
-util_log_write(struct util_log *log, uint8_t *data, uint16_t len)
+int 
+util_log_read(struct util_log *log, void *dptr, void *buf, uint16_t off, 
+        uint16_t len)
 {
-    struct ul_entry_hdr ue;
     int rc;
 
-    ue.ue_ts = os_time_get();
-    ue.ue_len = len;
-    ue.ue_flags = 0;
+    rc = log->ul_ulh->ulh_read(log, dptr, buf, off, len);
+
+    return (rc);
+}
 
-    rc = ul_insert_next(log, &ue, data);
+int 
+util_log_flush(struct util_log *log)
+{
+    int rc;
+
+    rc = log->ul_ulh->ulh_flush(log);
     if (rc != 0) {
         goto err;
-    }
+    } 
 
     return (0);
 err:
     return (rc);
 }
-
-

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05f17db2/project/blinky/src/main.c
----------------------------------------------------------------------
diff --git a/project/blinky/src/main.c b/project/blinky/src/main.c
index cfd9c42..70f9a52 100755
--- a/project/blinky/src/main.c
+++ b/project/blinky/src/main.c
@@ -43,9 +43,8 @@ os_stack_t stack2[TASK2_STACK_SIZE];
 #define SHELL_TASK_STACK_SIZE (OS_STACK_ALIGN(1024))
 os_stack_t shell_stack[SHELL_TASK_STACK_SIZE];
 
-
-struct uls_mem log_mem;
-struct ul_storage log_mem_storage;
+struct cbmem log_mem;
+struct ul_handler log_mem_handler;
 struct util_log my_log;
 uint8_t log_buf[64 * 1024];
 
@@ -137,16 +136,19 @@ init_tasks(void)
 int
 main(void)
 {
+    uint8_t entry[128];
     int rc;
 
-    log_mem.um_buf = log_buf;
-    log_mem.um_buf_size = 64 * 1024;
-
-    uls_mem_init(&log_mem_storage, &log_mem);
-    util_log_register("log", &my_log, &log_mem_storage);
+    cbmem_init(&log_mem, log_buf, 64 * 1024);
+    util_log_cbmem_handler_init(&log_mem_handler, &log_mem);
+    util_log_register("log", &my_log, &log_mem_handler);
 
-    util_log_write(&my_log, (uint8_t *) "bla", sizeof("bla")-1);
-    util_log_write(&my_log, (uint8_t *) "bab", sizeof("bab")-1);
+    memset(entry, 0xff, 128);
+    memcpy(entry + sizeof(struct ul_entry_hdr), "bla", sizeof("bla")-1);
+    util_log_append(&my_log, entry, sizeof("bla")-1);
+    memset(entry, 0xff, 128);
+    memcpy(entry + sizeof(struct ul_entry_hdr), "bab", sizeof("bab")-1);
+    util_log_append(&my_log, entry, sizeof("bab")-1);
 
     os_init();
 


Re: [2/2] incubator-mynewt-larva git commit: add logging infrastructure, and write it to circular buffer memory

Posted by Sterling Hughes <st...@apache.org>.
It's a personal preference thing, although, mine is pretty strong
towards using gotos for error handling.

It allows you to have two exit points from a function, success and
failure.  This is useful for:

- Setting breakpoints on function exit, and on error
- Counting statistics on error (in one place, vs multiple)
- Code readability (all of the error handling ends up being in a single place.)

It's somewhat of a poor man's exceptions.

In general, I don't really use goto's for anything else but error
handling.  Sometimes to quickly hack loop logic (i.e. to exhaust a
queue), but I generally end up replace it with a nested loop in that
case.

Sterling


On Tue, Nov 10, 2015 at 12:15 AM, Justin Mclean
<ju...@classsoftware.com> wrote:
> hi,
>
> Just curious re the use of "goto err” vs multiple returns in a function. Is there any reason the goto is preferred?
>
> Thanks,
> Justin

Re: [2/2] incubator-mynewt-larva git commit: add logging infrastructure, and write it to circular buffer memory

Posted by will sanfilippo <wi...@runtime.io>.
I dont think there is a preference; well, it is only a personal preference :-)

One thing that is nice about the goto is that there is only one return for the function. Sure, it is sort of cheating, but still… and of course if you want to execute a block of code on exit the goto is nice. But I dont think it really matters all that much one way or the other (imo).

Will

> On Nov 10, 2015, at 12:15 AM, Justin Mclean <ju...@classsoftware.com> wrote:
> 
> hi,
> 
> Just curious re the use of "goto err” vs multiple returns in a function. Is there any reason the goto is preferred?
> 
> Thanks,
> Justin


Re: [2/2] incubator-mynewt-larva git commit: add logging infrastructure, and write it to circular buffer memory

Posted by Justin Mclean <ju...@classsoftware.com>.
hi,

Just curious re the use of "goto err” vs multiple returns in a function. Is there any reason the goto is preferred?

Thanks,
Justin