You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2015/11/30 21:56:24 UTC
[1/2] incubator-mynewt-tadpole git commit: Merge larva changes to
tadpole.
Repository: incubator-mynewt-tadpole
Updated Branches:
refs/heads/master ad160f542 -> 29ce5cdc6
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/os_mbuf.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_mbuf.c b/libs/os/src/os_mbuf.c
index 0b8bda1..b1be0fc 100644
--- a/libs/os/src/os_mbuf.c
+++ b/libs/os/src/os_mbuf.c
@@ -54,22 +54,84 @@
#include <string.h>
+int
+os_mqueue_init(struct os_mqueue *mq, void *arg)
+{
+ struct os_event *ev;
+
+ STAILQ_INIT(&mq->mq_head);
+
+ ev = &mq->mq_ev;
+ memset(ev, 0, sizeof(*ev));
+ ev->ev_arg = arg;
+ ev->ev_type = OS_EVENT_T_MQUEUE_DATA;
+
+ return (0);
+}
+
+
+struct os_mbuf *
+os_mqueue_get(struct os_mqueue *mq)
+{
+ struct os_mbuf_pkthdr *mp;
+ struct os_mbuf *m;
+ os_sr_t sr;
+
+ OS_ENTER_CRITICAL(sr);
+ mp = STAILQ_FIRST(&mq->mq_head);
+ if (mp) {
+ STAILQ_REMOVE_HEAD(&mq->mq_head, omp_next);
+ }
+ OS_EXIT_CRITICAL(sr);
+
+ m = OS_MBUF_PKTHDR_TO_MBUF(mp);
+
+ return (m);
+}
+
+int
+os_mqueue_put(struct os_mqueue *mq, struct os_eventq *evq, struct os_mbuf *m)
+{
+ struct os_mbuf_pkthdr *mp;
+ os_sr_t sr;
+ int rc;
+
+ if (!OS_MBUF_IS_PKTHDR(m)) {
+ rc = OS_EINVAL;
+ goto err;
+ }
+
+ mp = OS_MBUF_PKTHDR(m);
+
+ OS_ENTER_CRITICAL(sr);
+ STAILQ_INSERT_TAIL(&mq->mq_head, mp, omp_next);
+ OS_EXIT_CRITICAL(sr);
+
+ /* Only post an event to the queue if its specified */
+ if (evq) {
+ os_eventq_put(evq, &mq->mq_ev);
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+
/**
* Initialize a pool of mbufs.
*
* @param omp The mbuf pool to initialize
* @param mp The memory pool that will hold this mbuf pool
- * @param hdr_len The length of the header, in a header mbuf
* @param buf_len The length of the buffer itself.
* @param nbufs The number of buffers in the pool
*
* @return 0 on success, error code on failure.
*/
int
-os_mbuf_pool_init(struct os_mbuf_pool *omp, struct os_mempool *mp,
- uint16_t hdr_len, uint16_t buf_len, uint16_t nbufs)
+os_mbuf_pool_init(struct os_mbuf_pool *omp, struct os_mempool *mp, uint16_t buf_len,
+ uint16_t nbufs)
{
- omp->omp_hdr_len = hdr_len;
omp->omp_databuf_len = buf_len - sizeof(struct os_mbuf);
omp->omp_mbuf_count = nbufs;
omp->omp_pool = mp;
@@ -101,6 +163,7 @@ os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace)
om->om_flags = 0;
om->om_len = 0;
om->om_data = (&om->om_databuf[0] + leadingspace);
+ om->om_omp = omp;
return (om);
err:
@@ -109,14 +172,20 @@ err:
/* Allocate a new packet header mbuf out of the os_mbuf_pool */
struct os_mbuf *
-os_mbuf_get_pkthdr(struct os_mbuf_pool *omp)
+os_mbuf_get_pkthdr(struct os_mbuf_pool *omp, uint8_t extra_pkthdr_len)
{
+ struct os_mbuf_pkthdr *pkthdr;
struct os_mbuf *om;
om = os_mbuf_get(omp, 0);
if (om) {
- om->om_flags |= OS_MBUF_F_MASK(OS_MBUF_F_PKTHDR);
- om->om_data += omp->omp_hdr_len + sizeof(struct os_mbuf_pkthdr);
+ om->om_pkthdr_len = extra_pkthdr_len + sizeof(struct os_mbuf_pkthdr);
+ om->om_data += extra_pkthdr_len + sizeof(struct os_mbuf_pkthdr);
+
+ pkthdr = OS_MBUF_PKTHDR(om);
+ pkthdr->omp_len = 0;
+ pkthdr->omp_flags = 0;
+ STAILQ_NEXT(pkthdr, omp_next) = NULL;
}
return om;
@@ -131,11 +200,11 @@ os_mbuf_get_pkthdr(struct os_mbuf_pool *omp)
* @return 0 on success, -1 on failure
*/
int
-os_mbuf_free(struct os_mbuf_pool *omp, struct os_mbuf *om)
+os_mbuf_free(struct os_mbuf *om)
{
int rc;
- rc = os_memblock_put(omp->omp_pool, om);
+ rc = os_memblock_put(om->om_omp->omp_pool, om);
if (rc != 0) {
goto err;
}
@@ -154,7 +223,7 @@ err:
* @return 0 on success, -1 on failure
*/
int
-os_mbuf_free_chain(struct os_mbuf_pool *omp, struct os_mbuf *om)
+os_mbuf_free_chain(struct os_mbuf *om)
{
struct os_mbuf *next;
int rc;
@@ -162,7 +231,7 @@ os_mbuf_free_chain(struct os_mbuf_pool *omp, struct os_mbuf *om)
while (om != NULL) {
next = SLIST_NEXT(om, om_next);
- rc = os_mbuf_free(omp, om);
+ rc = os_mbuf_free(om);
if (rc != 0) {
goto err;
}
@@ -183,11 +252,10 @@ err:
* @param old_buf The old buffer to copy the packet header from
*/
static inline void
-_os_mbuf_copypkthdr(struct os_mbuf_pool *omp, struct os_mbuf *new_buf,
- struct os_mbuf *old_buf)
+_os_mbuf_copypkthdr(struct os_mbuf *new_buf, struct os_mbuf *old_buf)
{
memcpy(&new_buf->om_databuf[0], &old_buf->om_databuf[0],
- sizeof(struct os_mbuf_pkthdr) + omp->omp_hdr_len);
+ old_buf->om_pkthdr_len);
}
/**
@@ -201,20 +269,22 @@ _os_mbuf_copypkthdr(struct os_mbuf_pool *omp, struct os_mbuf *new_buf,
* @return 0 on success, and an error code on failure
*/
int
-os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *om, void *data,
- uint16_t len)
+os_mbuf_append(struct os_mbuf *om, const void *data, uint16_t len)
{
+ struct os_mbuf_pool *omp;
struct os_mbuf *last;
struct os_mbuf *new;
int remainder;
int space;
int rc;
- if (omp == NULL || om == NULL) {
+ if (om == NULL) {
rc = OS_EINVAL;
goto err;
}
+ omp = om->om_omp;
+
/* Scroll to last mbuf in the chain */
last = om;
while (SLIST_NEXT(last, om_next) != NULL) {
@@ -222,7 +292,7 @@ os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *om, void *data,
}
remainder = len;
- space = OS_MBUF_TRAILINGSPACE(omp, last);
+ space = OS_MBUF_TRAILINGSPACE(last);
/* If room in current mbuf, copy the first part of the data into the
* remaining space in that mbuf.
@@ -232,7 +302,7 @@ os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *om, void *data,
space = remainder;
}
- memcpy(OS_MBUF_DATA(last, void *), data, space);
+ memcpy(OS_MBUF_DATA(last, void *) + last->om_len , data, space);
last->om_len += space;
data += space;
@@ -243,7 +313,7 @@ os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *om, void *data,
* data into it, until data is exhausted.
*/
while (remainder > 0) {
- new = os_mbuf_get(omp, OS_MBUF_START_OFF(omp));
+ new = os_mbuf_get(omp, 0);
if (!new) {
break;
}
@@ -282,32 +352,35 @@ err:
* @return A pointer to the new chain of mbufs
*/
struct os_mbuf *
-os_mbuf_dup(struct os_mbuf_pool *omp, struct os_mbuf *om)
+os_mbuf_dup(struct os_mbuf *om)
{
+ struct os_mbuf_pool *omp;
struct os_mbuf *head;
struct os_mbuf *copy;
+ omp = om->om_omp;
+
head = NULL;
copy = NULL;
for (; om != NULL; om = SLIST_NEXT(om, om_next)) {
if (head) {
SLIST_NEXT(copy, om_next) = os_mbuf_get(omp,
- OS_MBUF_LEADINGSPACE(omp, om));
+ OS_MBUF_LEADINGSPACE(om));
if (!SLIST_NEXT(copy, om_next)) {
- os_mbuf_free_chain(omp, head);
+ os_mbuf_free_chain(head);
goto err;
}
copy = SLIST_NEXT(copy, om_next);
} else {
- head = os_mbuf_get(omp, OS_MBUF_LEADINGSPACE(omp, om));
+ head = os_mbuf_get(omp, OS_MBUF_LEADINGSPACE(om));
if (!head) {
goto err;
}
- if (om->om_flags & OS_MBUF_F_MASK(OS_MBUF_F_PKTHDR)) {
- _os_mbuf_copypkthdr(omp, head, om);
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ _os_mbuf_copypkthdr(head, om);
}
copy = head;
}
@@ -322,6 +395,440 @@ err:
return (NULL);
}
+/**
+ * Locates the specified absolute offset within an mbuf chain. The offset
+ * can be one past than the total length of the chain, but no greater.
+ *
+ * @param om The start of the mbuf chain to seek within.
+ * @param off The absolute address to find.
+ * @param out_off On success, this points to the relative offset
+ * within the returned mbuf.
+ *
+ * @return The mbuf containing the specified offset on
+ * success.
+ * NULL if the specified offset is out of bounds.
+ */
+struct os_mbuf *
+os_mbuf_off(struct os_mbuf *om, int off, int *out_off)
+{
+ struct os_mbuf *next;
+
+ while (1) {
+ if (om == NULL) {
+ return NULL;
+ }
+
+ next = SLIST_NEXT(om, om_next);
+
+ if (om->om_len > off ||
+ (om->om_len == off && next == NULL)) {
+
+ *out_off = off;
+ return om;
+ }
+
+ off -= om->om_len;
+ om = next;
+ }
+}
+
+/*
+ * Copy data from an mbuf chain starting "off" bytes from the beginning,
+ * continuing for "len" bytes, into the indicated buffer.
+ *
+ * @return 0 on success;
+ * -1 if the mbuf does not contain enough data.
+ */
+int
+os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst)
+{
+ unsigned int count;
+ uint8_t *udst;
+
+ udst = dst;
+
+ while (off > 0) {
+ if (!m) {
+ return (-1);
+ }
+
+ if (off < m->om_len)
+ break;
+ off -= m->om_len;
+ m = SLIST_NEXT(m, om_next);
+ }
+ while (len > 0 && m != NULL) {
+ count = min(m->om_len - off, len);
+ memcpy(udst, m->om_data + off, count);
+ len -= count;
+ udst += count;
+ off = 0;
+ m = SLIST_NEXT(m, om_next);
+ }
+
+ return (len > 0 ? -1 : 0);
+}
+
+void
+os_mbuf_adj(struct os_mbuf *mp, int req_len)
+{
+ int len = req_len;
+ struct os_mbuf *m;
+ int count;
+
+ if ((m = mp) == NULL)
+ return;
+ if (len >= 0) {
+ /*
+ * Trim from head.
+ */
+ while (m != NULL && len > 0) {
+ if (m->om_len <= len) {
+ len -= m->om_len;
+ m->om_len = 0;
+ m = SLIST_NEXT(m, om_next);
+ } else {
+ m->om_len -= len;
+ m->om_data += len;
+ len = 0;
+ }
+ }
+ if (OS_MBUF_IS_PKTHDR(mp))
+ OS_MBUF_PKTHDR(mp)->omp_len -= (req_len - len);
+ } else {
+ /*
+ * Trim from tail. Scan the mbuf chain,
+ * calculating its length and finding the last mbuf.
+ * If the adjustment only affects this mbuf, then just
+ * adjust and return. Otherwise, rescan and truncate
+ * after the remaining size.
+ */
+ len = -len;
+ count = 0;
+ for (;;) {
+ count += m->om_len;
+ if (SLIST_NEXT(m, om_next) == (struct os_mbuf *)0)
+ break;
+ m = SLIST_NEXT(m, om_next);
+ }
+ if (m->om_len >= len) {
+ m->om_len -= len;
+ if (OS_MBUF_IS_PKTHDR(mp))
+ OS_MBUF_PKTHDR(mp)->omp_len -= len;
+ return;
+ }
+ count -= len;
+ if (count < 0)
+ count = 0;
+ /*
+ * Correct length for chain is "count".
+ * Find the mbuf with last data, adjust its length,
+ * and toss data from remaining mbufs on chain.
+ */
+ m = mp;
+ if (OS_MBUF_IS_PKTHDR(m))
+ OS_MBUF_PKTHDR(m)->omp_len = count;
+ for (; m; m = SLIST_NEXT(m, om_next)) {
+ if (m->om_len >= count) {
+ m->om_len = count;
+ if (SLIST_NEXT(m, om_next) != NULL) {
+ os_mbuf_free_chain(SLIST_NEXT(m, om_next));
+ SLIST_NEXT(m, om_next) = NULL;
+ }
+ break;
+ }
+ count -= m->om_len;
+ }
+ }
+}
+
+/**
+ * Performs a memory compare of the specified region of an mbuf chain against a
+ * flat buffer.
+ *
+ * @param om The start of the mbuf chain to compare.
+ * @param off The offset within the mbuf chain to start the
+ * comparison.
+ * @param data The flat buffer to compare.
+ * @param len The length of the flat buffer.
+ *
+ * @return 0 if both memory regions are identical;
+ * A memcmp return code if there is a mismatch;
+ * -1 if the mbuf is too short.
+ */
+int
+os_mbuf_memcmp(const struct os_mbuf *om, int off, const void *data, int len)
+{
+ int chunk_sz;
+ int data_off;
+ int om_off;
+ int rc;
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ data_off = 0;
+ om = os_mbuf_off((struct os_mbuf *)om, off, &om_off);
+ while (1) {
+ if (om == NULL) {
+ return -1;
+ }
+
+ chunk_sz = min(om->om_len - om_off, len - data_off);
+ if (chunk_sz > 0) {
+ rc = memcmp(om->om_data + om_off, data + data_off, chunk_sz);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+
+ data_off += chunk_sz;
+ if (data_off == len) {
+ return 0;
+ }
+
+ om = SLIST_NEXT(om, om_next);
+ om_off = 0;
+
+ if (om == NULL) {
+ return -1;
+ }
+ }
+}
+
+/**
+ * Increases the length of an mbuf chain by adding data to the front. If there
+ * is insufficient room in the leading mbuf, additional mbufs are allocated and
+ * prepended as necessary. If this function fails to allocate an mbuf, the
+ * entire chain is freed.
+ *
+ * The specified mbuf chain does not need to contain a packet header.
+ *
+ * @param omp The mbuf pool to allocate from.
+ * @param om The head of the mbuf chain.
+ * @param len The number of bytes to prepend.
+ *
+ * @return The new head of the chain on success;
+ * NULL on failure.
+ */
+struct os_mbuf *
+os_mbuf_prepend(struct os_mbuf *om, int len)
+{
+ struct os_mbuf *p;
+ int leading;
+
+ while (1) {
+ /* Fill the available space at the front of the head of the chain, as
+ * needed.
+ */
+ leading = min(len, OS_MBUF_LEADINGSPACE(om));
+
+ om->om_data -= leading;
+ om->om_len += leading;
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ OS_MBUF_PKTHDR(om)->omp_len += leading;
+ }
+
+ len -= leading;
+ if (len == 0) {
+ break;
+ }
+
+ /* The current head didn't have enough space; allocate a new head. */
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ p = os_mbuf_get_pkthdr(om->om_omp,
+ om->om_pkthdr_len - sizeof (struct os_mbuf_pkthdr));
+ } else {
+ p = os_mbuf_get(om->om_omp, 0);
+ }
+ if (p == NULL) {
+ os_mbuf_free_chain(om);
+ om = NULL;
+ break;
+ }
+
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ _os_mbuf_copypkthdr(p, om);
+ om->om_pkthdr_len = 0;
+ }
+
+ /* Move the new head's data pointer to the end so that data can be
+ * prepended.
+ */
+ p->om_data += OS_MBUF_TRAILINGSPACE(p);
+
+ SLIST_NEXT(p, om_next) = om;
+ om = p;
+ }
+
+ return om;
+}
+
+/**
+ * Copies the contents of a flat buffer into an mbuf chain, starting at the
+ * specified destination offset. If the mbuf is too small for the source data,
+ * it is extended as necessary. If the destination mbuf contains a packet
+ * header, the header length is updated.
+ *
+ * @param omp The mbuf pool to allocate from.
+ * @param om The mbuf chain to copy into.
+ * @param off The offset within the chain to copy to.
+ * @param src The source buffer to copy from.
+ * @param len The number of bytes to copy.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int
+os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len)
+{
+ struct os_mbuf *next;
+ struct os_mbuf *cur;
+ const uint8_t *sptr;
+ int copylen;
+ int cur_off;
+ int rc;
+
+ /* Find the mbuf,offset pair for the start of the destination. */
+ cur = os_mbuf_off(om, off, &cur_off);
+ if (cur == NULL) {
+ return -1;
+ }
+
+ /* Overwrite existing data until we reach the end of the chain. */
+ sptr = src;
+ while (1) {
+ copylen = min(cur->om_len - cur_off, len);
+ if (copylen > 0) {
+ memcpy(cur->om_data + cur_off, sptr, copylen);
+ sptr += copylen;
+ len -= copylen;
+
+ copylen = 0;
+ }
+
+ if (len == 0) {
+ /* All the source data fit in the existing mbuf chain. */
+ return 0;
+ }
+
+ next = SLIST_NEXT(cur, om_next);
+ if (next == NULL) {
+ break;
+ }
+
+ cur = next;
+ }
+
+ /* Append the remaining data to the end of the chain. */
+ rc = os_mbuf_append(cur, sptr, len);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* Fix up the packet header, if one is present. */
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ OS_MBUF_PKTHDR(om)->omp_len =
+ max(OS_MBUF_PKTHDR(om)->omp_len, off + len);
+ }
+
+ return 0;
+}
+
+/**
+ * Attaches a second mbuf chain onto the end of the first. If the first chain
+ * contains a packet header, the header's length is updated. If the second
+ * chain has a packet header, its header is cleared.
+ *
+ * @param first The mbuf chain being attached to.
+ * @param second The mbuf chain that gets attached.
+ */
+void
+os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second)
+{
+ struct os_mbuf *next;
+ struct os_mbuf *cur;
+
+ /* Point 'cur' to the last buffer in the first chain. */
+ cur = first;
+ while (1) {
+ next = SLIST_NEXT(cur, om_next);
+ if (next == NULL) {
+ break;
+ }
+
+ cur = next;
+ }
+
+ /* Attach the second chain to the end of the first. */
+ SLIST_NEXT(cur, om_next) = second;
+
+ /* If the first chain has a packet header, calculate the length of the
+ * second chain and add it to the header length.
+ */
+ if (OS_MBUF_IS_PKTHDR(first)) {
+ if (OS_MBUF_IS_PKTHDR(second)) {
+ OS_MBUF_PKTHDR(first)->omp_len += OS_MBUF_PKTHDR(second)->omp_len;
+ } else {
+ for (cur = second; cur != NULL; cur = SLIST_NEXT(cur, om_next)) {
+ OS_MBUF_PKTHDR(first)->omp_len += cur->om_len;
+ }
+ }
+ }
+
+ second->om_pkthdr_len = 0;
+}
+
+/**
+ * Increases the length of an mbuf chain by the specified amount. If there is
+ * not sufficient room in the last buffer, a new buffer is allocated and
+ * appended to the chain. It is an error to request more data than can fit in
+ * a single buffer.
+ *
+ * @param omp
+ * @param om The head of the chain to extend.
+ * @param len The number of bytes to extend by.
+ *
+ * @return A pointer to the new data on success;
+ * NULL on failure.
+ */
+void *
+os_mbuf_extend(struct os_mbuf *om, uint16_t len)
+{
+ struct os_mbuf *newm;
+ struct os_mbuf *last;
+ void *data;
+
+ if (len > om->om_omp->omp_databuf_len) {
+ return NULL;
+ }
+
+ /* Scroll to last mbuf in the chain */
+ last = om;
+ while (SLIST_NEXT(last, om_next) != NULL) {
+ last = SLIST_NEXT(last, om_next);
+ }
+
+ if (OS_MBUF_TRAILINGSPACE(last) < len) {
+ newm = os_mbuf_get(om->om_omp, 0);
+ if (newm == NULL) {
+ return NULL;
+ }
+
+ SLIST_NEXT(last, om_next) = newm;
+ last = newm;
+ }
+
+ data = last->om_data + last->om_len;
+ last->om_len += len;
+
+ if (OS_MBUF_IS_PKTHDR(om)) {
+ OS_MBUF_PKTHDR(om)->omp_len += len;
+ }
+
+ return data;
+}
+
#if 0
/**
@@ -341,16 +848,19 @@ err:
* @return The contiguous mbuf chain on success, NULL on failure.
*/
struct os_mbuf *
-os_mbuf_pullup(struct os_mbuf_pool *omp, struct os_mbuf *om, uint16_t len)
+os_mbuf_pullup(struct os_mbuf *om, uint16_t len)
{
+ struct os_mbuf_pool *omp;
struct os_mbuf *newm;
+ omp = om->om_omp;
+
if (len > omp->omp_databuf_len) {
goto err;
}
/* Is 'n' bytes already contiguous? */
- if (((uint8_t *) &om->om_databuf[0] + OS_MBUF_END_OFF(omp)) -
+ if (((uint8_t *) &om->om_databuf[0] + omp->omp_databuf_len) -
OS_MBUF_DATA(om, uint8_t *) >= len) {
newm = om;
goto done;
@@ -359,7 +869,7 @@ os_mbuf_pullup(struct os_mbuf_pool *omp, struct os_mbuf *om, uint16_t len)
/* Nope, OK. Allocate a new buffer, and then go through and copy 'n'
* bytes into that buffer.
*/
- newm = os_mbuf_get(omp, OS_MBUF_START_OFF(omp));
+ newm = os_mbuf_get(omp, 0);
if (!newm) {
goto err;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/os_sched.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_sched.c b/libs/os/src/os_sched.c
index 240bc62..944f0f6 100644
--- a/libs/os/src/os_sched.c
+++ b/libs/os/src/os_sched.c
@@ -25,6 +25,9 @@ TAILQ_HEAD(, os_task) g_os_sleep_list = TAILQ_HEAD_INITIALIZER(g_os_sleep_list);
struct os_task *g_current_task;
+extern os_time_t g_os_time;
+os_time_t g_os_last_ctx_sw_time;
+
/**
* os sched insert
*
@@ -68,6 +71,57 @@ err:
}
/**
+ * Walk all the active tasks currently being scheduled.
+ *
+ * @param walk_func The walk function to call for each task
+ * @param arg The argument to pass the walk function
+ *
+ * @return 0 on success, < 0 on abort.
+ */
+int
+os_sched_walk(os_sched_walk_func_t walk_func, void *arg)
+{
+ struct os_task *t;
+ os_sr_t sr;
+ int rc;
+
+ /* Go through tasks and fill out the info blocks
+ */
+ OS_ENTER_CRITICAL(sr);
+ TAILQ_FOREACH(t, &g_os_run_list, t_os_list) {
+ rc = walk_func(t, arg);
+ if (rc != 0) {
+ goto done;
+ }
+ }
+
+ TAILQ_FOREACH(t, &g_os_sleep_list, t_os_list) {
+ rc = walk_func(t, arg);
+ if (rc != 0) {
+ goto done;
+ }
+ }
+
+done:
+ OS_EXIT_CRITICAL(sr);
+
+ return (rc);
+}
+
+void
+os_sched_ctx_sw_hook(struct os_task *next_t)
+{
+ if (g_current_task == next_t) {
+ return;
+ }
+
+ next_t->t_ctx_sw_cnt++;
+ g_current_task->t_run_time += g_os_time - g_os_last_ctx_sw_time;
+ g_os_last_ctx_sw_time = g_os_time;
+}
+
+
+/**
* os sched get current task
*
* Returns the currently running task. Note that this task may or may not be
@@ -118,7 +172,7 @@ os_sched(struct os_task *next_t, int isr)
next_t = os_sched_next_task();
}
- if (next_t != os_sched_get_current_task()) {
+ if (next_t != g_current_task) {
OS_EXIT_CRITICAL(sr);
if (isr) {
os_arch_ctx_sw_isr(next_t);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/os_task.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_task.c b/libs/os/src/os_task.c
index f9da560..950d54f 100644
--- a/libs/os/src/os_task.c
+++ b/libs/os/src/os_task.c
@@ -45,6 +45,12 @@ os_task_next_id(void)
return (rc);
}
+uint8_t
+os_task_count(void)
+{
+ return (g_task_id);
+}
+
int
os_task_sanity_checkin(struct os_task *t)
{
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/os_time.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_time.c b/libs/os/src/os_time.c
index cc2e819..9613159 100644
--- a/libs/os/src/os_time.c
+++ b/libs/os/src/os_time.c
@@ -17,7 +17,7 @@
#include "os/os.h"
#include "os/queue.h"
-static os_time_t g_os_time = 0;
+os_time_t g_os_time = 0;
os_time_t
os_time_get(void)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/test/mbuf_test.c
----------------------------------------------------------------------
diff --git a/libs/os/src/test/mbuf_test.c b/libs/os/src/test/mbuf_test.c
index 6d98452..8652494 100644
--- a/libs/os/src/test/mbuf_test.c
+++ b/libs/os/src/test/mbuf_test.c
@@ -38,7 +38,7 @@ os_mbuf_test_setup(void)
MBUF_TEST_POOL_BUF_SIZE, &os_mbuf_membuf[0], "mbuf_pool");
TEST_ASSERT_FATAL(rc == 0, "Error creating memory pool %d", rc);
- rc = os_mbuf_pool_init(&os_mbuf_pool, &os_mbuf_mempool, 0,
+ rc = os_mbuf_pool_init(&os_mbuf_pool, &os_mbuf_mempool,
MBUF_TEST_POOL_BUF_SIZE, MBUF_TEST_POOL_BUF_COUNT);
TEST_ASSERT_FATAL(rc == 0, "Error creating mbuf pool %d", rc);
}
@@ -53,7 +53,7 @@ TEST_CASE(os_mbuf_test_case_1)
m = os_mbuf_get(&os_mbuf_pool, 0);
TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf");
- rc = os_mbuf_free(&os_mbuf_pool, m);
+ rc = os_mbuf_free(m);
TEST_ASSERT_FATAL(rc == 0, "Error free'ing mbuf %d", rc);
}
@@ -68,14 +68,14 @@ TEST_CASE(os_mbuf_test_case_2)
m = os_mbuf_get(&os_mbuf_pool, 0);
TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf");
- dup = os_mbuf_dup(&os_mbuf_pool, m);
+ dup = os_mbuf_dup(m);
TEST_ASSERT_FATAL(dup != NULL, "NULL mbuf returned from dup");
TEST_ASSERT_FATAL(dup != m, "duplicate matches original.");
- rc = os_mbuf_free(&os_mbuf_pool, m);
+ rc = os_mbuf_free(m);
TEST_ASSERT_FATAL(rc == 0, "Error free'ing mbuf m %d", rc);
- rc = os_mbuf_free(&os_mbuf_pool, dup);
+ rc = os_mbuf_free(dup);
TEST_ASSERT_FATAL(rc == 0, "Error free'ing mbuf dup %d", rc);
m = os_mbuf_get(&os_mbuf_pool, 0);
@@ -86,16 +86,16 @@ TEST_CASE(os_mbuf_test_case_2)
SLIST_NEXT(m, om_next) = m2;
- dup = os_mbuf_dup(&os_mbuf_pool, m);
+ dup = os_mbuf_dup(m);
TEST_ASSERT_FATAL(dup != NULL, "NULL mbuf returned from dup");
TEST_ASSERT_FATAL(dup != m, "Duplicate matches original");
TEST_ASSERT_FATAL(SLIST_NEXT(dup, om_next) != NULL,
"NULL chained element, duplicate should match original");
- rc = os_mbuf_free_chain(&os_mbuf_pool, m);
+ rc = os_mbuf_free_chain(m);
TEST_ASSERT_FATAL(rc == 0, "Cannot free mbuf chain %d", rc);
- rc = os_mbuf_free_chain(&os_mbuf_pool, dup);
+ rc = os_mbuf_free_chain(dup);
TEST_ASSERT_FATAL(rc == 0, "Cannot free mbuf chain %d", rc);
}
@@ -109,7 +109,7 @@ TEST_CASE(os_mbuf_test_case_3)
m = os_mbuf_get(&os_mbuf_pool, 0);
TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf");
- rc = os_mbuf_append(&os_mbuf_pool, m, databuf, sizeof(databuf));
+ rc = os_mbuf_append(m, databuf, sizeof(databuf));
TEST_ASSERT_FATAL(rc == 0, "Cannot add %d bytes to mbuf",
sizeof(databuf));
TEST_ASSERT_FATAL(m->om_len == sizeof(databuf),
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/testutil/src/suite.c
----------------------------------------------------------------------
diff --git a/libs/testutil/src/suite.c b/libs/testutil/src/suite.c
index b6decb0..a6f2126 100644
--- a/libs/testutil/src/suite.c
+++ b/libs/testutil/src/suite.c
@@ -18,8 +18,8 @@
#include "testutil/testutil.h"
#include "testutil_priv.h"
-const char *tu_suite_name;
-int tu_suite_failed;
+const char *tu_suite_name = 0;
+int tu_suite_failed = 0;
static void
tu_suite_set_name(const char *name)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/egg.yml
----------------------------------------------------------------------
diff --git a/libs/util/egg.yml b/libs/util/egg.yml
new file mode 100644
index 0000000..3faef1b
--- /dev/null
+++ b/libs/util/egg.yml
@@ -0,0 +1,13 @@
+egg.name: libs/util
+egg.vers: 0.1
+egg.deps:
+ - hw/hal
+ - libs/os
+ - libs/testutil
+egg.deps.SHELL:
+ - libs/console/full
+ - libs/shell
+egg.cflags.SHELL: -DSHELL_PRESENT
+egg.deps.NFFS:
+ - libs/nffs
+egg.cflags.NFFS: -DNFFS_PRESENT
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/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..1a0fa34
--- /dev/null
+++ b/libs/util/include/util/cbmem.h
@@ -0,0 +1,63 @@
+/**
+ * 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_walk(struct cbmem *cbmem, cbmem_walk_func_t walk_func, void *arg);
+
+int cbmem_flush(struct cbmem *);
+
+#endif /* __UTIL_CBMEM_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/include/util/flash_map.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/flash_map.h b/libs/util/include/util/flash_map.h
new file mode 100644
index 0000000..3b77c86
--- /dev/null
+++ b/libs/util/include/util/flash_map.h
@@ -0,0 +1,88 @@
+/**
+ * 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 H_UTIL_FLASH_MAP_
+#define H_UTIL_FLASH_MAP_
+
+/**
+ *
+ * Provides abstraction of flash regions for type of use.
+ * I.e. dude where's my image?
+ *
+ * System will contain a map which contains flash areas. Every
+ * region will contain flash identifier, offset within flash and length.
+ *
+ * 1. This system map could be in a file within filesystem (Initializer
+ * must know/figure out where the filesystem is at).
+ * 2. Map could be at fixed location for project (compiled to code)
+ * 3. Map could be at specific place in flash (put in place at mfg time).
+ *
+ * Note that the map you use must be valid for BSP it's for,
+ * match the linker scripts when platform executes from flash,
+ * and match the target offset specified in download script.
+ */
+#include <inttypes.h>
+
+struct flash_area {
+ uint8_t fa_flash_id;
+ uint8_t _pad[3];
+ uint32_t fa_off;
+ uint32_t fa_size;
+};
+
+/*
+ * Flash area types
+ */
+#define FLASH_AREA_BOOTLOADER 0
+#define FLASH_AREA_IMAGE_0 1
+#define FLASH_AREA_IMAGE_1 2
+#define FLASH_AREA_IMAGE_SCRATCH 3
+#define FLASH_AREA_NFFS 4
+
+/*
+ * Initializes flash map. Memory will be referenced by flash_map code
+ * from this on.
+ */
+void flash_area_init(const struct flash_area *map, int map_entries);
+
+/*
+ * Start using flash area.
+ */
+int flash_area_open(int idx, const struct flash_area **);
+
+void flash_area_close(const struct flash_area *);
+
+/*
+ * Read/write/erase. Offset is relative from beginning of flash area.
+ */
+int flash_area_read(const struct flash_area *, uint32_t off, void *dst,
+ uint32_t len);
+int flash_area_write(const struct flash_area *, uint32_t off, void *src,
+ uint32_t len);
+int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len);
+
+/*
+ * Given flash map index, return info about sectors within the area.
+ */
+int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret);
+
+/*
+ * Given flash map index, return sector info in NFFS area desc format.
+ */
+struct nffs_area_desc;
+int flash_area_to_nffs_desc(int idx, int *cnt, struct nffs_area_desc *nad);
+
+#endif /* H_UTIL_FLASH_MAP_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/include/util/log.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/log.h b/libs/util/include/util/log.h
new file mode 100644
index 0000000..b1b64d7
--- /dev/null
+++ b/libs/util/include/util/log.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_LOG_H__
+#define __UTIL_LOG_H__
+
+#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 {
+ int64_t ue_ts;
+};
+
+struct util_log {
+ char *ul_name;
+ struct ul_handler *ul_ulh;
+ STAILQ_ENTRY(util_log) ul_next;
+};
+
+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-tadpole/blob/29ce5cdc/libs/util/include/util/stats.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/stats.h b/libs/util/include/util/stats.h
new file mode 100644
index 0000000..f35e0c0
--- /dev/null
+++ b/libs/util/include/util/stats.h
@@ -0,0 +1,108 @@
+/**
+ * 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_STATS_H__
+#define __UTIL_STATS_H__
+
+#include <os/queue.h>
+#include <stdint.h>
+
+struct stats_name_map {
+ void *snm_off;
+ char *snm_name;
+};
+
+struct stats_hdr {
+ char *s_name;
+ uint8_t s_size;
+ uint8_t s_cnt;
+ uint16_t s_pad1;
+#ifdef STATS_NAME_ENABLE
+ struct stats_name_map *s_map;
+ int s_map_cnt;
+#endif
+ STAILQ_ENTRY(stats_hdr) s_next;
+};
+
+
+#define STATS_SECT_START(__name) \
+struct stats_ ## __name { \
+ struct stats_hdr s_hdr;
+
+
+#define STATS_SECT_END(__name) \
+} g_stats_ ## __name;
+
+#define STATS_SECT_NAME(__name) \
+ g_stats_ ## __name
+
+#define STATS_HDR(__name) ((struct stats_hdr *) &STATS_SECT_NAME(__name))
+
+#define STATS_SECT_VAR(__var) \
+ s##__var
+
+#define STATS_SIZE_16 (sizeof(uint16_t))
+#define STATS_SIZE_32 (sizeof(uint32_t))
+#define STATS_SIZE_64 (sizeof(uint64_t))
+
+#define STATS_SECT_ENTRY(__var) uint32_t STATS_SECT_VAR(__var);
+#define STATS_SECT_ENTRY16(__var) uint16_t STATS_SECT_VAR(__var);
+#define STATS_SECT_ENTRY32(__var) uint32_t STATS_SECT_VAR(__var);
+#define STATS_SECT_ENTRY64(__var) uint64_t STATS_SECT_VAR(__var);
+
+#define STATS_SIZE_INIT_PARMS(__name, __size) \
+ __size, \
+ ((sizeof(STATS_SECT_NAME(__name)) - sizeof(struct stats_hdr)) / __size)
+
+
+#define STATS_INC(__name, __var) \
+ (STATS_SECT_NAME(__name).STATS_SECT_VAR(__var)++)
+
+#define STATS_INCN(__name, __var, __n) \
+ (STATS_SECT_NAME(__name).STATS_SECT_VAR(__var) += (__n))
+
+#ifdef STATS_NAME_ENABLE
+
+#define STATS_NAME_MAP_NAME(__name) g_stats_map_ ## __name
+
+#define STATS_NAME_START(__name) \
+struct stats_name_map STATS_NAME_MAP_NAME(__name)[] = {
+
+#define STATS_NAME(__name, __entry) \
+ { &STATS_SECT_NAME(__name).STATS_SECT_VAR(__entry), #__entry },
+
+#define STATS_NAME_END(__name) \
+};
+
+#define STATS_NAME_INIT_PARMS(__name) \
+ &(STATS_NAME_MAP_NAME(__name)[0]), \
+ (sizeof(STATS_NAME_MAP_NAME(__name)) / sizeof(struct stats_name_map))
+
+#else /* STATS_NAME_ENABLE */
+
+#define STATS_NAME_START(__name)
+#define STATS_NAME(__name, __entry)
+#define STATS_NAME_END(__name)
+#define STATS_NAME_INIT_PARMS(__name) NULL, 0
+
+#endif /* STATS_NAME_ENABLE */
+
+int stats_module_init(void);
+int stats_init(struct stats_hdr *shdr, uint8_t size, uint8_t cnt,
+ struct stats_name_map *map, uint8_t map_cnt);
+int stats_register(char *name, struct stats_hdr *shdr);
+struct stats_hdr *stats_find(char *name);
+
+#endif /* __UTIL_STATS_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/include/util/tpq.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/tpq.h b/libs/util/include/util/tpq.h
new file mode 100644
index 0000000..e0a536b
--- /dev/null
+++ b/libs/util/include/util/tpq.h
@@ -0,0 +1,64 @@
+/**
+ * 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_TPQ_H__
+#define __UTIL_TPQ_H__
+
+#include <os/queue.h>
+#include <os/os_eventq.h>
+
+/* A task packet queue element */
+struct tpq_elem {
+ STAILQ_ENTRY(tpq_elem) tpq_next;
+};
+
+/* The task packet queue object */
+struct tpq
+{
+ STAILQ_HEAD(, tpq_elem) tpq_head;
+ struct os_event tpq_ev;
+};
+
+/**
+ * Put an element on a task packet queue and post an event to an event queue.
+ *
+ * @param evq Pointer to event queue
+ * @param tpq Pointer to task packet queue
+ * @param elem Pointer to element to enqueue
+ */
+void tpq_put(struct os_eventq *evq, struct tpq *tpq, struct tpq_elem *elem);
+
+/**
+ * Retrieve an element from a task packet queue. This removes the element at
+ * the head of the queue.
+ *
+ * @param head
+ *
+ * @return struct tpq_elem*
+ */
+struct tpq_elem *tpq_get(struct tpq *tpq);
+
+/**
+ * Initialize a task packet queue
+ *
+ * @param tpq Pointer to task packet queue
+ * @param ev_type Type of event.
+ * @param ev_arg Argument of event
+ *
+ * @return int
+ */
+void tpq_init(struct tpq *tpq, uint8_t ev_type, void *ev_arg);
+
+#endif /* __UTIL_TPQ_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/include/util/util.h
----------------------------------------------------------------------
diff --git a/libs/util/include/util/util.h b/libs/util/include/util/util.h
new file mode 100644
index 0000000..110af87
--- /dev/null
+++ b/libs/util/include/util/util.h
@@ -0,0 +1,19 @@
+/**
+ * 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_H__
+#define __UTIL_H__
+
+#endif /* __UTIL_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/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..84d161f
--- /dev/null
+++ b/libs/util/src/cbmem.c
@@ -0,0 +1,269 @@
+/**
+ * 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;
+ }
+
+ if (off > hdr->ceh_len) {
+ rc = -1;
+ cbmem_lock_release(cbmem);
+ goto err;
+ }
+
+ 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-tadpole/blob/29ce5cdc/libs/util/src/flash_map.c
----------------------------------------------------------------------
diff --git a/libs/util/src/flash_map.c b/libs/util/src/flash_map.c
new file mode 100644
index 0000000..28f26c9
--- /dev/null
+++ b/libs/util/src/flash_map.c
@@ -0,0 +1,146 @@
+/**
+ * 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 <string.h>
+
+#include <hal/hal_flash.h>
+#include <hal/hal_flash_int.h>
+#ifdef NFFS_PRESENT
+#include <nffs/nffs.h>
+#endif
+#include "util/flash_map.h"
+
+static const struct flash_area *flash_map;
+static int flash_map_entries;
+
+void
+flash_area_init(const struct flash_area *map, int map_entries)
+{
+ flash_map = map;
+ flash_map_entries = map_entries;
+ /*
+ * XXX should we validate this against current flashes?
+ */
+}
+
+int
+flash_area_open(int idx, const struct flash_area **fap)
+{
+ if (!flash_map || idx >= flash_map_entries) {
+ return -1;
+ }
+ *fap = &flash_map[idx];
+ return 0;
+}
+
+void
+flash_area_close(const struct flash_area *fa)
+{
+ /* nothing to do for now */
+}
+
+int
+flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
+{
+ int i;
+ const struct hal_flash *hf;
+ const struct flash_area *fa;
+ uint32_t start, size;
+
+ if (!flash_map || idx >= flash_map_entries) {
+ return -1;
+ }
+ *cnt = 0;
+ fa = &flash_map[idx];
+
+ hf = bsp_flash_dev(fa->fa_flash_id);
+ for (i = 0; i < hf->hf_sector_cnt; i++) {
+ hf->hf_itf->hff_sector_info(i, &start, &size);
+ if (start >= fa->fa_off && start < fa->fa_off + fa->fa_size) {
+ if (ret) {
+ ret->fa_flash_id = fa->fa_flash_id;
+ ret->fa_off = start;
+ ret->fa_size = size;
+ ret++;
+ }
+ *cnt = *cnt + 1;
+ }
+ }
+ return 0;
+}
+
+#ifdef NFFS_PRESENT
+int
+flash_area_to_nffs_desc(int idx, int *cnt, struct nffs_area_desc *nad)
+{
+ int i;
+ const struct hal_flash *hf;
+ const struct flash_area *fa;
+ uint32_t start, size;
+
+ if (!flash_map || idx >= flash_map_entries) {
+ return -1;
+ }
+ *cnt = 0;
+ fa = &flash_map[idx];
+
+ hf = bsp_flash_dev(fa->fa_flash_id);
+ for (i = 0; i < hf->hf_sector_cnt; i++) {
+ hf->hf_itf->hff_sector_info(i, &start, &size);
+ if (start >= fa->fa_off && start < fa->fa_off + fa->fa_size) {
+ if (nad) {
+ nad->nad_flash_id = fa->fa_flash_id;
+ nad->nad_offset = start;
+ nad->nad_length = size;
+ nad++;
+ }
+ *cnt = *cnt + 1;
+ }
+ }
+ if (nad) {
+ memset(nad, 0, sizeof(*nad));
+ }
+ return 0;
+}
+#endif /* NFFS_PRESENT */
+
+int
+flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
+ uint32_t len)
+{
+ if (off > fa->fa_size || off + len > fa->fa_size) {
+ return -1;
+ }
+ return hal_flash_read(fa->fa_flash_id, fa->fa_off + off, dst, len);
+}
+
+int
+flash_area_write(const struct flash_area *fa, uint32_t off, void *src,
+ uint32_t len)
+{
+ if (off > fa->fa_size || off + len > fa->fa_size) {
+ return -1;
+ }
+ return hal_flash_write(fa->fa_flash_id, fa->fa_off + off, src, len);
+}
+
+int
+flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
+{
+ if (off > fa->fa_size || off + len > fa->fa_size) {
+ return -1;
+ }
+ return hal_flash_erase(fa->fa_flash_id, fa->fa_off + off, len);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/src/log.c
----------------------------------------------------------------------
diff --git a/libs/util/src/log.c b/libs/util/src/log.c
new file mode 100644
index 0000000..5d16364
--- /dev/null
+++ b/libs/util/src/log.c
@@ -0,0 +1,274 @@
+/**
+ * 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/log.h"
+#include "util/cbmem.h"
+
+#include <stdio.h>
+
+#ifdef SHELL_PRESENT
+
+#include <shell/shell.h>
+#include <console/console.h>
+
+struct shell_cmd shell_log_cmd;
+uint8_t shell_registered;
+
+#endif
+
+static STAILQ_HEAD(, util_log) g_util_log_list =
+ STAILQ_HEAD_INITIALIZER(g_util_log_list);
+
+
+#ifdef SHELL_PRESENT
+
+static int
+shell_log_dump_entry(struct util_log *log, void *arg, void *dptr, uint16_t len)
+{
+ struct ul_entry_hdr ueh;
+ char data[128];
+ int dlen;
+ int rc;
+
+ rc = util_log_read(log, dptr, &ueh, 0, sizeof(ueh));
+ if (rc != sizeof(ueh)) {
+ goto err;
+ }
+
+ dlen = min(len-sizeof(ueh), 128);
+
+ rc = util_log_read(log, dptr, data, sizeof(ueh), dlen);
+ if (rc < 0) {
+ goto err;
+ }
+ data[rc] = 0;
+
+ /* XXX: This is evil. newlib printf does not like 64-bit
+ * values, and this causes memory to be overwritten. Cast to a
+ * unsigned 32-bit value for now.
+ */
+ console_printf("[%d] %s\n", (uint32_t) ueh.ue_ts, data);
+
+ return (0);
+err:
+ return (rc);
+}
+
+static int
+shell_log_dump_all(int argc, char **argv)
+{
+ struct util_log *log;
+ int rc;
+
+ STAILQ_FOREACH(log, &g_util_log_list, ul_next) {
+ rc = util_log_walk(log, shell_log_dump_entry, NULL);
+ if (rc != 0) {
+ goto err;
+ }
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+#endif
+
+static int
+ulh_cbmem_append(struct util_log *log, void *buf, int len)
+{
+ struct cbmem *cbmem;
+ int rc;
+
+ cbmem = (struct cbmem *) log->ul_ulh->ulh_arg;
+
+ rc = cbmem_append(cbmem, buf, len);
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+static int
+ulh_cbmem_read(struct util_log *log, void *dptr, void *buf, uint16_t offset,
+ uint16_t len)
+{
+ struct cbmem *cbmem;
+ struct cbmem_entry_hdr *hdr;
+ int rc;
+
+ 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;
+
+ 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;
+ }
+
+ 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:
+ return (rc);
+}
+
+static int
+ulh_cbmem_flush(struct util_log *log)
+{
+ 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
+util_log_cbmem_handler_init(struct ul_handler *handler, struct cbmem *cbmem)
+{
+ 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_handler *ulh)
+{
+#ifdef SHELL_PRESENT
+ if (!shell_registered) {
+ /* register the shell */
+
+ shell_registered = 1;
+ shell_cmd_register(&shell_log_cmd, "log", shell_log_dump_all);
+ }
+#endif
+
+ log->ul_name = name;
+ log->ul_ulh = ulh;
+
+ STAILQ_INSERT_TAIL(&g_util_log_list, log, ul_next);
+
+ return (0);
+}
+
+int
+util_log_append(struct util_log *log, uint8_t *data, uint16_t len)
+{
+ struct ul_entry_hdr *ue;
+ int rc;
+
+ ue = (struct ul_entry_hdr *) data;
+ ue->ue_ts = (int64_t) os_time_get();
+
+ rc = log->ul_ulh->ulh_append(log, data, len + sizeof(*ue));
+ if (rc != 0) {
+ goto err;
+ }
+
+ 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;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+int
+util_log_read(struct util_log *log, void *dptr, void *buf, uint16_t off,
+ uint16_t len)
+{
+ int rc;
+
+ rc = log->ul_ulh->ulh_read(log, dptr, buf, off, len);
+
+ return (rc);
+}
+
+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-tadpole/blob/29ce5cdc/libs/util/src/stats.c
----------------------------------------------------------------------
diff --git a/libs/util/src/stats.c b/libs/util/src/stats.c
new file mode 100644
index 0000000..0d2eb36
--- /dev/null
+++ b/libs/util/src/stats.c
@@ -0,0 +1,218 @@
+/**
+ * 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/stats.h"
+
+#ifdef SHELL_PRESENT
+#include "shell/shell.h"
+#include "console/console.h"
+#endif
+
+#include <stdio.h>
+
+STATS_SECT_START(stats)
+ STATS_SECT_ENTRY(num_registered)
+STATS_SECT_END(stats)
+
+STATS_NAME_START(stats)
+ STATS_NAME(stats, num_registered)
+STATS_NAME_END(stats)
+
+STAILQ_HEAD(, stats_hdr) g_stats_registry =
+ STAILQ_HEAD_INITIALIZER(g_stats_registry);
+
+#ifdef SHELL_PRESENT
+uint8_t stats_shell_registered;
+struct shell_cmd shell_stats_cmd;
+#endif
+
+#ifdef SHELL_PRESENT
+
+static void
+shell_stats_display_entry(struct stats_hdr *hdr, uint8_t *ptr)
+{
+ char *name;
+ char buf[12];
+ int ent_n;
+ int len;
+#ifdef STATS_NAME_ENABLE
+ int i;
+#endif
+
+ name = NULL;
+
+#ifdef STATS_NAME_ENABLE
+ for (i = 0; i < hdr->s_map_cnt; i++) {
+ if (hdr->s_map[i].snm_off == ptr) {
+ name = hdr->s_map[i].snm_name;
+ break;
+ }
+ }
+#endif
+
+ if (name == NULL) {
+ ent_n = (ptr - ((uint8_t *) hdr + sizeof(*hdr))) / hdr->s_size;
+
+ len = snprintf(buf, sizeof(buf), "s%d", ent_n);
+ buf[len] = 0;
+ name = buf;
+ }
+
+ switch (hdr->s_size) {
+ case sizeof(uint16_t):
+ console_printf("%s: %u\n", name, *(uint16_t *) ptr);
+ break;
+ case sizeof(uint32_t):
+ console_printf("%s: %u\n", name, *(uint32_t *) ptr);
+ break;
+ case sizeof(uint64_t):
+ console_printf("%s: %llu\n", name, *(uint64_t *) ptr);
+ break;
+ default:
+ console_printf("Unknown stat size for %s %u\n", name,
+ hdr->s_size);
+ break;
+ }
+}
+
+static int
+shell_stats_display(int argc, char **argv)
+{
+ struct stats_hdr *hdr;
+ char *name;
+ uint8_t *cur;
+ uint8_t *end;
+
+ name = argv[1];
+ if (name == NULL || !strcmp(name, "")) {
+ console_printf("Must specify a statistic name to dump, "
+ "possible names are:\n");
+ STAILQ_FOREACH(hdr, &g_stats_registry, s_next) {
+ console_printf("\t%s\n", hdr->s_name);
+ }
+ goto done;
+ }
+
+
+ hdr = stats_find(name);
+ if (!hdr) {
+ console_printf("Could not find statistic %s\n", name);
+ goto done;
+ }
+
+ cur = (uint8_t *) hdr + sizeof(*hdr);
+ end = (uint8_t *) hdr + sizeof(*hdr) + (hdr->s_size * hdr->s_cnt);
+ while (cur < end) {
+ shell_stats_display_entry(hdr, (uint8_t *) cur);
+ cur += hdr->s_size;
+ }
+
+done:
+ return (0);
+}
+
+#endif
+
+int
+stats_module_init(void)
+{
+ int rc;
+#ifdef SHELL_PRESENT
+ if (!stats_shell_registered) {
+ stats_shell_registered = 1;
+ shell_cmd_register(&shell_stats_cmd, "stat", shell_stats_display);
+ }
+#endif
+
+ rc = stats_init(STATS_HDR(stats), STATS_SIZE_INIT_PARMS(stats, STATS_SIZE_32),
+ STATS_NAME_INIT_PARMS(stats));
+ if (rc != 0) {
+ goto err;
+ }
+
+ rc = stats_register("stat", STATS_HDR(stats));
+ if (rc != 0) {
+ goto err;
+ }
+
+ return (0);
+err:
+ return (rc);
+}
+
+
+int
+stats_init(struct stats_hdr *shdr, uint8_t size, uint8_t cnt,
+ struct stats_name_map *map, uint8_t map_cnt)
+{
+ memset((uint8_t *) shdr, 0, sizeof(*shdr) + (size * cnt));
+
+ shdr->s_size = size;
+ shdr->s_cnt = cnt;
+#ifdef STATS_NAME_ENABLE
+ shdr->s_map = map;
+ shdr->s_map_cnt = map_cnt;
+#endif
+
+ return (0);
+}
+
+int
+stats_register(char *name, struct stats_hdr *shdr)
+{
+ struct stats_hdr *cur;
+ int rc;
+
+ /* Don't allow duplicate entries, return an error if this stat
+ * is already registered.
+ */
+ STAILQ_FOREACH(cur, &g_stats_registry, s_next) {
+ if (!strcmp(cur->s_name, name)) {
+ rc = -1;
+ goto err;
+ }
+ }
+
+ shdr->s_name = name;
+
+ STAILQ_INSERT_TAIL(&g_stats_registry, shdr, s_next);
+
+ STATS_INC(stats, num_registered);
+
+ return (0);
+err:
+ return (rc);
+}
+
+struct stats_hdr *
+stats_find(char *name)
+{
+ struct stats_hdr *cur;
+
+ cur = NULL;
+ STAILQ_FOREACH(cur, &g_stats_registry, s_next) {
+ if (!strcmp(cur->s_name, name)) {
+ break;
+ }
+ }
+
+ return (cur);
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/src/test/cbmem_test.c
----------------------------------------------------------------------
diff --git a/libs/util/src/test/cbmem_test.c b/libs/util/src/test/cbmem_test.c
new file mode 100644
index 0000000..af4b323
--- /dev/null
+++ b/libs/util/src/test/cbmem_test.c
@@ -0,0 +1,173 @@
+/**
+ * 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 <stdio.h>
+#include <string.h>
+
+#include "testutil/testutil.h"
+#include "util/cbmem.h"
+
+#define CBMEM1_BUF_SIZE (64 * 1024)
+
+struct cbmem cbmem1;
+uint8_t cbmem1_buf[CBMEM1_BUF_SIZE];
+uint8_t cbmem1_entry[1024];
+
+/*
+ * Things to test.
+ *
+ * - Wrap of the circular buffer.
+ * - Reading through all entries.
+ */
+
+static void
+setup_cbmem1(void)
+{
+ int i;
+ int rc;
+
+ rc = cbmem_init(&cbmem1, cbmem1_buf, CBMEM1_BUF_SIZE);
+ TEST_ASSERT_FATAL(rc == 0, "cbmem_init() failed, non-zero RC = %d", rc);
+
+ memset(cbmem1_entry, 0xff, sizeof(cbmem1_entry));
+
+ /* Insert 65 1024 entries, and overflow buffer.
+ * This should overflow two entries, because the buffer is sized for 64
+ * entries, and then the headers themselves will eat into one of the entries,
+ * so there should be a total of 63 entries.
+ * Ensure no data corruption.
+ */
+ for (i = 0; i < 65; i++) {
+ cbmem1_entry[0] = i;
+ rc = cbmem_append(&cbmem1, cbmem1_entry, sizeof(cbmem1_entry));
+ TEST_ASSERT_FATAL(rc == 0, "Could not append entry %d, rc = %d", i, rc);
+ }
+}
+
+static int
+cbmem_test_case_1_walk(struct cbmem *cbmem, struct cbmem_entry_hdr *hdr,
+ void *arg)
+{
+ uint8_t expected;
+ uint8_t actual;
+ int rc;
+
+ expected = *(uint8_t *) arg;
+
+ rc = cbmem_read(cbmem, hdr, &actual, 0, sizeof(actual));
+ TEST_ASSERT_FATAL(rc == 1, "Couldn't read 1 byte from cbmem");
+ TEST_ASSERT_FATAL(actual == expected,
+ "Actual doesn't equal expected (%d = %d)", actual, expected);
+
+ *(uint8_t *) arg = ++expected;
+
+ return (0);
+}
+
+TEST_CASE(cbmem_test_case_1)
+{
+ int i;
+ int rc;
+
+ /* i starts at 2, for the 2 overwritten entries. */
+ i = 2;
+ rc = cbmem_walk(&cbmem1, cbmem_test_case_1_walk, &i);
+ TEST_ASSERT_FATAL(rc == 0, "Could not walk cbmem tree! rc = %d", rc);
+ TEST_ASSERT_FATAL(i == 65,
+ "Did not go through every element of walk, %d processed", i - 2);
+
+}
+
+TEST_CASE(cbmem_test_case_2)
+{
+ struct cbmem_entry_hdr *hdr;
+ struct cbmem_iter iter;
+ uint8_t i;
+ uint8_t val;
+ int rc;
+
+ i = 2;
+ cbmem_iter_start(&cbmem1, &iter);
+ while (1) {
+ hdr = cbmem_iter_next(&cbmem1, &iter);
+ if (hdr == NULL) {
+ break;
+ }
+
+ rc = cbmem_read(&cbmem1, hdr, &val, 0, sizeof(val));
+ TEST_ASSERT_FATAL(rc == 1, "Couldn't read 1 byte from cbmem");
+ TEST_ASSERT_FATAL(val == i, "Entry index does not match %d vs %d",
+ val, i);
+
+ i++;
+ }
+
+ /* i starts at 2, for the 2 overwritten entries */
+ TEST_ASSERT_FATAL(i == 65,
+ "Did not iterate through all 63 elements of CBMEM1, processed %d",
+ i - 2);
+}
+
+TEST_CASE(cbmem_test_case_3)
+{
+ struct cbmem_entry_hdr *hdr;
+ struct cbmem_iter iter;
+ uint16_t off;
+ uint16_t len;
+ uint8_t buf[128];
+ int i;
+ int rc;
+
+ i = 0;
+ cbmem_iter_start(&cbmem1, &iter);
+ while (1) {
+ hdr = cbmem_iter_next(&cbmem1, &iter);
+ if (hdr == NULL) {
+ break;
+ }
+
+ /* first ensure we can read the entire entry */
+ off = 0;
+ len = 0;
+ while (1) {
+ rc = cbmem_read(&cbmem1, hdr, buf, off, sizeof(buf));
+ TEST_ASSERT_FATAL(rc >= 0,
+ "Error reading from buffer rc=%d, off=%d,len=%d", rc, off,
+ sizeof(buf));
+ if (rc == 0) {
+ break;
+ }
+ off += rc;
+ len += rc;
+ }
+ TEST_ASSERT_FATAL(len == 1024,
+ "Couldn't read full entry, expected %d got %d", 1024, len);
+ i++;
+
+ /* go apesh*t, and read data out of bounds, see what we get. */
+ rc = cbmem_read(&cbmem1, hdr, buf, 2048, sizeof(buf));
+ TEST_ASSERT_FATAL(rc < 0,
+ "Reading invalid should return error, instead %d returned.",
+ rc);
+ }
+}
+
+TEST_SUITE(cbmem_test_suite)
+{
+ setup_cbmem1();
+ cbmem_test_case_1();
+ cbmem_test_case_2();
+ cbmem_test_case_3();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/src/test/flash_map_test.c
----------------------------------------------------------------------
diff --git a/libs/util/src/test/flash_map_test.c b/libs/util/src/test/flash_map_test.c
new file mode 100644
index 0000000..005139c
--- /dev/null
+++ b/libs/util/src/test/flash_map_test.c
@@ -0,0 +1,151 @@
+/**
+ * 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 <stdio.h>
+#include <string.h>
+
+#include "os/os.h"
+#include "testutil/testutil.h"
+#include "util/flash_map.h"
+
+#include "hal/hal_flash.h"
+#include "hal/hal_flash_int.h"
+
+/*
+ * Test flash_area_to_sectors()
+ */
+TEST_CASE(flash_map_test_case_1)
+{
+ const struct flash_area *fa;
+ int areas_checked = 0;
+ int i, j, rc;
+ const struct hal_flash *hf;
+ struct flash_area my_secs[32];
+ int my_sec_cnt;
+ uint32_t end;
+
+ os_init();
+
+ for (i = 0; i < 8; i++) {
+ rc = flash_area_open(i, &fa);
+ if (rc) {
+ continue;
+ }
+
+ hf = bsp_flash_dev(fa->fa_flash_id);
+ TEST_ASSERT_FATAL(hf != NULL, "bsp_flash_dev");
+
+ rc = flash_area_to_sectors(i, &my_sec_cnt, my_secs);
+ TEST_ASSERT_FATAL(rc == 0, "flash_area_to_sectors failed");
+
+ end = fa->fa_off;
+ for (j = 0; j < my_sec_cnt; j++) {
+ TEST_ASSERT_FATAL(end == my_secs[j].fa_off, "Non contiguous area");
+ TEST_ASSERT_FATAL(my_secs[j].fa_flash_id == fa->fa_flash_id,
+ "Sectors not in same flash?");
+ end = my_secs[j].fa_off + my_secs[j].fa_size;
+ }
+ if (my_sec_cnt) {
+ areas_checked++;
+ TEST_ASSERT_FATAL(my_secs[my_sec_cnt - 1].fa_off +
+ my_secs[my_sec_cnt - 1].fa_size == fa->fa_off + fa->fa_size,
+ "Last sector not in the end");
+ }
+ }
+ TEST_ASSERT_FATAL(areas_checked != 0, "No flash map areas to check!");
+}
+
+/*
+ * Test flash_erase
+ */
+TEST_CASE(flash_map_test_case_2)
+{
+ const struct flash_area *fa;
+ struct flash_area secs[32];
+ int sec_cnt;
+ int i;
+ int rc;
+ uint32_t off;
+ uint8_t wd[256];
+ uint8_t rd[256];
+
+ os_init();
+
+ rc = flash_area_open(FLASH_AREA_IMAGE_0, &fa);
+ TEST_ASSERT_FATAL(rc == 0, "flash_area_open() fail");
+
+ rc = flash_area_to_sectors(FLASH_AREA_IMAGE_0, &sec_cnt, secs);
+ TEST_ASSERT_FATAL(rc == 0, "flash_area_to_sectors failed");
+
+ /*
+ * First erase the area so it's ready for use.
+ */
+ for (i = 0; i < sec_cnt; i++) {
+ rc = hal_flash_erase_sector(secs[i].fa_flash_id, secs[i].fa_off);
+ TEST_ASSERT_FATAL(rc == 0, "hal_flash_erase_sector() failed");
+ }
+ TEST_ASSERT_FATAL(rc == 0, "read data != write data");
+
+ memset(wd, 0xa5, sizeof(wd));
+
+ /* write stuff to beginning of every sector */
+ off = 0;
+ for (i = 0; i < sec_cnt; i++) {
+ rc = flash_area_write(fa, off, wd, sizeof(wd));
+ TEST_ASSERT_FATAL(rc == 0, "flash_area_write() fail");
+
+ /* read it back via hal_flash_Read() */
+ rc = hal_flash_read(fa->fa_flash_id, fa->fa_off + off, rd, sizeof(rd));
+ TEST_ASSERT_FATAL(rc == 0, "hal_flash_read() fail");
+
+ rc = memcmp(wd, rd, sizeof(wd));
+ TEST_ASSERT_FATAL(rc == 0, "read data != write data");
+
+ /* write stuff to end of area */
+ rc = hal_flash_write(fa->fa_flash_id,
+ fa->fa_off + off + secs[i].fa_size - sizeof(wd), wd, sizeof(wd));
+ TEST_ASSERT_FATAL(rc == 0, "hal_flash_write() fail");
+
+ /* and read it back */
+ memset(rd, 0, sizeof(rd));
+ rc = flash_area_read(fa, off + secs[i].fa_size - sizeof(rd),
+ rd, sizeof(rd));
+ TEST_ASSERT_FATAL(rc == 0, "hal_flash_read() fail");
+
+ rc = memcmp(wd, rd, sizeof(rd));
+ TEST_ASSERT_FATAL(rc == 0, "read data != write data");
+
+ off += secs[i].fa_size;
+ }
+ /* erase it */
+ rc = flash_area_erase(fa, 0, fa->fa_size);
+ TEST_ASSERT_FATAL(rc == 0, "read data != write data");
+
+ /* should read back ff all throughout*/
+ memset(wd, 0xff, sizeof(wd));
+ for (off = 0; off < fa->fa_size; off += sizeof(rd)) {
+ rc = flash_area_read(fa, off, rd, sizeof(rd));
+ TEST_ASSERT_FATAL(rc == 0, "hal_flash_read() fail");
+
+ rc = memcmp(wd, rd, sizeof(rd));
+ TEST_ASSERT_FATAL(rc == 0, "area not erased");
+ }
+}
+
+TEST_SUITE(flash_map_test_suite)
+{
+ flash_map_test_case_1();
+ flash_map_test_case_2();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/src/test/util_test.c
----------------------------------------------------------------------
diff --git a/libs/util/src/test/util_test.c b/libs/util/src/test/util_test.c
new file mode 100644
index 0000000..9998fa7
--- /dev/null
+++ b/libs/util/src/test/util_test.c
@@ -0,0 +1,43 @@
+/**
+ * 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 <assert.h>
+#include <stddef.h>
+#include "testutil/testutil.h"
+#include "util_test_priv.h"
+
+int
+util_test_all(void)
+{
+ cbmem_test_suite();
+ flash_map_test_suite();
+ return tu_case_failed;
+}
+
+#ifdef PKG_TEST
+
+int
+main(int argc, char **argv)
+{
+ tu_config.tc_print_results = 1;
+ tu_init();
+
+ util_test_all();
+
+ return tu_any_failed;
+}
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/src/test/util_test_priv.h
----------------------------------------------------------------------
diff --git a/libs/util/src/test/util_test_priv.h b/libs/util/src/test/util_test_priv.h
new file mode 100644
index 0000000..d6f8da4
--- /dev/null
+++ b/libs/util/src/test/util_test_priv.h
@@ -0,0 +1,23 @@
+/**
+ * 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_TEST_PRIV_
+#define __UTIL_TEST_PRIV_
+
+int cbmem_test_suite(void);
+int flash_map_test_suite(void);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/util/src/tpq.c
----------------------------------------------------------------------
diff --git a/libs/util/src/tpq.c b/libs/util/src/tpq.c
new file mode 100644
index 0000000..72133c0
--- /dev/null
+++ b/libs/util/src/tpq.c
@@ -0,0 +1,85 @@
+/**
+ * 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 "util/tpq.h"
+
+/**
+ * Put an element on a task packet queue and post an event to an event queue.
+ *
+ * @param evq Pointer to event queue
+ * @param tpq Pointer to task packet queue
+ * @param elem Pointer to element to enqueue
+ */
+void
+tpq_put(struct os_eventq *evq, struct tpq *tpq, struct tpq_elem *elem)
+{
+ os_sr_t sr;
+
+ OS_ENTER_CRITICAL(sr);
+ STAILQ_INSERT_TAIL(&tpq->tpq_head, elem, tpq_next);
+ OS_EXIT_CRITICAL(sr);
+ os_eventq_put(evq, &tpq->tpq_ev);
+}
+
+/**
+ * Retrieve an element from a task packet queue. This removes the element at
+ * the head of the queue.
+ *
+ * @param head
+ *
+ * @return struct tpq_elem*
+ */
+struct tpq_elem *
+tpq_get(struct tpq *tpq)
+{
+ os_sr_t sr;
+ struct tpq_elem *elem;
+
+ OS_ENTER_CRITICAL(sr);
+ elem = STAILQ_FIRST(&tpq->tpq_head);
+ if (elem) {
+ STAILQ_REMOVE_HEAD(&tpq->tpq_head, tpq_next);
+ }
+ OS_EXIT_CRITICAL(sr);
+
+ return elem;
+}
+
+/**
+ * Initialize a task packet queue
+ *
+ * @param tpq Pointer to task packet queue
+ * @param ev_type Type of event.
+ * @param ev_arg Argument of event
+ *
+ * @return int
+ */
+void
+tpq_init(struct tpq *tpq, uint8_t ev_type, void *ev_arg)
+{
+ struct os_event *ev;
+
+ /* Initialize the task packet queue */
+ STAILQ_INIT(&tpq->tpq_head);
+
+ /* Initial task packet queue event */
+ ev = &tpq->tpq_ev;
+ ev->ev_arg = ev_arg;
+ ev->ev_type = ev_type;
+ ev->ev_queued = 0;
+ STAILQ_NEXT(ev, ev_next) = NULL;
+}
+
[2/2] incubator-mynewt-tadpole git commit: Merge larva changes to
tadpole.
Posted by ma...@apache.org.
Merge larva changes to tadpole.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/commit/29ce5cdc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/tree/29ce5cdc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/diff/29ce5cdc
Branch: refs/heads/master
Commit: 29ce5cdc6409e210c12fb2eef8d222dd21efac12
Parents: ad160f5
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Mon Nov 30 12:55:58 2015 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Mon Nov 30 12:55:58 2015 -0800
----------------------------------------------------------------------
compiler/sim/compiler.yml | 2 +-
compiler/sim/linux-compiler.yml | 7 +-
compiler/sim/osx-compiler.yml | 2 +-
hw/bsp/native/egg.yml | 3 +
hw/bsp/native/src/hal_bsp.c | 34 ++
hw/bsp/native/src/os_bsp.c | 53 ++
hw/bsp/native/src/sbrk.c | 56 ++
hw/hal/include/hal/hal_cputime.h | 2 +-
hw/hal/include/hal/hal_flash.h | 14 +-
hw/hal/include/hal/hal_flash_int.h | 47 ++
hw/hal/include/hal/hal_spim.h | 44 ++
hw/hal/include/hal/hal_system.h | 2 +-
hw/hal/include/hal/hal_uart.h | 11 +-
hw/hal/src/hal_flash.c | 153 ++++++
hw/mcu/native/include/mcu/mcu_sim.h | 23 +
hw/mcu/native/include/mcu/native_bsp.h | 21 +
hw/mcu/native/src/hal_cputime.c | 490 +++++++++++++++++
hw/mcu/native/src/hal_flash.c | 257 ++++-----
hw/mcu/native/src/hal_gpio.c | 1 -
hw/mcu/native/src/hal_system.c | 49 +-
hw/mcu/native/src/hal_uart.c | 90 +++-
libs/os/egg.yml | 10 +
libs/os/include/os/arch/cortex_m4/os/os_arch.h | 4 +-
libs/os/include/os/arch/sim/os/os_arch.h | 2 +
libs/os/include/os/os.h | 3 +
libs/os/include/os/os_eventq.h | 3 +
libs/os/include/os/os_mbuf.h | 115 ++--
libs/os/include/os/os_sched.h | 4 +
libs/os/include/os/os_task.h | 7 +-
libs/os/include/os/os_time.h | 7 +-
libs/os/src/arch/cortex_m4/m4/HAL_CM4.s | 30 ++
libs/os/src/arch/cortex_m4/os_arch_arm.c | 41 +-
libs/os/src/arch/cortex_m4/os_fault.c | 85 +++
libs/os/src/arch/sim/os_arch_sim.c | 15 +-
libs/os/src/arch/sim/os_fault.c | 30 ++
libs/os/src/os.c | 3 +
libs/os/src/os_info.c | 169 ++++++
libs/os/src/os_mbuf.c | 568 +++++++++++++++++++-
libs/os/src/os_sched.c | 56 +-
libs/os/src/os_task.c | 6 +
libs/os/src/os_time.c | 2 +-
libs/os/src/test/mbuf_test.c | 18 +-
libs/testutil/src/suite.c | 4 +-
libs/util/egg.yml | 13 +
libs/util/include/util/cbmem.h | 63 +++
libs/util/include/util/flash_map.h | 88 +++
libs/util/include/util/log.h | 61 +++
libs/util/include/util/stats.h | 108 ++++
libs/util/include/util/tpq.h | 64 +++
libs/util/include/util/util.h | 19 +
libs/util/src/cbmem.c | 269 +++++++++
libs/util/src/flash_map.c | 146 +++++
libs/util/src/log.c | 274 ++++++++++
libs/util/src/stats.c | 218 ++++++++
libs/util/src/test/cbmem_test.c | 173 ++++++
libs/util/src/test/flash_map_test.c | 151 ++++++
libs/util/src/test/util_test.c | 43 ++
libs/util/src/test/util_test_priv.h | 23 +
libs/util/src/tpq.c | 85 +++
59 files changed, 4042 insertions(+), 299 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/compiler/sim/compiler.yml
----------------------------------------------------------------------
diff --git a/compiler/sim/compiler.yml b/compiler/sim/compiler.yml
index 6803c63..fd61dc9 100644
--- a/compiler/sim/compiler.yml
+++ b/compiler/sim/compiler.yml
@@ -23,7 +23,7 @@ compiler.path.objsize: "objsize"
compiler.path.objcopy: "gobjcopy"
compiler.flags.base: >
- -m32 -Wall -Werror -ggdb -O0
+ -m32 -Wall -Werror -ggdb -O0 -DMN_OSX
compiler.flags.default: [compiler.flags.base]
compiler.flags.debug: [compiler.flags.base, -ggdb -O0]
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/compiler/sim/linux-compiler.yml
----------------------------------------------------------------------
diff --git a/compiler/sim/linux-compiler.yml b/compiler/sim/linux-compiler.yml
index 3dac5f2..d9603ec 100644
--- a/compiler/sim/linux-compiler.yml
+++ b/compiler/sim/linux-compiler.yml
@@ -16,17 +16,18 @@
############################# Compiler Variables #############################
-compiler.path.cc: "gcc"
+compiler.path.cc: "gcc"
compiler.path.archive: "ar"
compiler.path.objdump: "objdump"
-compiler.path.objsize: "objsize"
+compiler.path.objsize: "size"
compiler.path.objcopy: "objcopy"
compiler.flags.base: >
- -m32 -Wall -Werror -ggdb -O0
+ -m32 -Wall -Werror -ggdb -O0 -DMN_LINUX
compiler.flags.default: [compiler.flags.base]
compiler.flags.debug: [compiler.flags.base, -ggdb -O0]
compiler.ld.mapfile: false
compiler.ld.resolve_circular_deps: true
+compiler.ld.flags: -lutil
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/compiler/sim/osx-compiler.yml
----------------------------------------------------------------------
diff --git a/compiler/sim/osx-compiler.yml b/compiler/sim/osx-compiler.yml
index 6803c63..fd61dc9 100644
--- a/compiler/sim/osx-compiler.yml
+++ b/compiler/sim/osx-compiler.yml
@@ -23,7 +23,7 @@ compiler.path.objsize: "objsize"
compiler.path.objcopy: "gobjcopy"
compiler.flags.base: >
- -m32 -Wall -Werror -ggdb -O0
+ -m32 -Wall -Werror -ggdb -O0 -DMN_OSX
compiler.flags.default: [compiler.flags.base]
compiler.flags.debug: [compiler.flags.base, -ggdb -O0]
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/bsp/native/egg.yml
----------------------------------------------------------------------
diff --git a/hw/bsp/native/egg.yml b/hw/bsp/native/egg.yml
index 64a7a20..8e0741c 100644
--- a/hw/bsp/native/egg.yml
+++ b/hw/bsp/native/egg.yml
@@ -1,3 +1,6 @@
egg.name: "hw/bsp/native"
egg.deps:
- hw/mcu/native
+ - libs/util
+egg.deps.BLE_DEVICE:
+ - net/nimble/drivers/native
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/bsp/native/src/hal_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/native/src/hal_bsp.c b/hw/bsp/native/src/hal_bsp.c
new file mode 100644
index 0000000..389c49a
--- /dev/null
+++ b/hw/bsp/native/src/hal_bsp.c
@@ -0,0 +1,34 @@
+/**
+ * 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 <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <inttypes.h>
+#include "hal/hal_flash_int.h"
+#include "mcu/native_bsp.h"
+
+const struct hal_flash *
+bsp_flash_dev(uint8_t id)
+{
+ /*
+ * Just one to start with
+ */
+ if (id != 0) {
+ return NULL;
+ }
+ return &native_flash_dev;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/bsp/native/src/os_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/native/src/os_bsp.c b/hw/bsp/native/src/os_bsp.c
new file mode 100644
index 0000000..cc414da
--- /dev/null
+++ b/hw/bsp/native/src/os_bsp.c
@@ -0,0 +1,53 @@
+/**
+ * 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 <util/flash_map.h>
+
+static struct flash_area bsp_flash_areas[] = {
+ [FLASH_AREA_BOOTLOADER] = {
+ .fa_flash_id = 0, /* internal flash */
+ .fa_off = 0x00000000, /* beginning */
+ .fa_size = (32 * 1024)
+ },
+ /* 2 * 16K and 1*64K sectors here */
+ [FLASH_AREA_IMAGE_0] = {
+ .fa_flash_id = 0,
+ .fa_off = 0x00020000,
+ .fa_size = (384 * 1024)
+ },
+ [FLASH_AREA_IMAGE_1] = {
+ .fa_flash_id = 0,
+ .fa_off = 0x00080000,
+ .fa_size = (384 * 1024)
+ },
+ [FLASH_AREA_IMAGE_SCRATCH] = {
+ .fa_flash_id = 0,
+ .fa_off = 0x000e0000,
+ .fa_size = (128 * 1024)
+ },
+ [FLASH_AREA_NFFS] = {
+ .fa_flash_id = 0,
+ .fa_off = 0x00008000,
+ .fa_size = (32 * 1024)
+ }
+
+};
+
+void os_bsp_init(void)
+{
+ flash_area_init(bsp_flash_areas,
+ sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0]));
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/bsp/native/src/sbrk.c
----------------------------------------------------------------------
diff --git a/hw/bsp/native/src/sbrk.c b/hw/bsp/native/src/sbrk.c
new file mode 100644
index 0000000..154bd39
--- /dev/null
+++ b/hw/bsp/native/src/sbrk.c
@@ -0,0 +1,56 @@
+/**
+ * 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 <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+
+extern int getpagesize(void);
+
+static void *cont;
+static int sys_pagesize;
+static int cont_left;
+
+void *
+_sbrk(int incr)
+{
+ void *result;
+
+ if (!sys_pagesize) {
+ sys_pagesize = getpagesize();
+ }
+ if (cont && incr <= cont_left) {
+ result = cont;
+ cont_left -= incr;
+ if (cont_left) {
+ cont = (char *)cont + incr;
+ } else {
+ cont = NULL;
+ }
+ return result;
+ }
+ result = mmap(NULL, incr, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED,
+ -1, 0);
+ if (result) {
+ cont_left = sys_pagesize - (incr % sys_pagesize);
+ if (cont_left) {
+ cont = (char *)result + incr;
+ } else {
+ cont = NULL;
+ }
+ }
+ return result;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/include/hal/hal_cputime.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_cputime.h b/hw/hal/include/hal/hal_cputime.h
index 286736c..97d8709 100644
--- a/hw/hal/include/hal/hal_cputime.h
+++ b/hw/hal/include/hal/hal_cputime.h
@@ -170,7 +170,7 @@ void cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs);
*
* Stops a cputimer from running. The timer is removed from the timer queue
* and interrupts are disabled if no timers are left on the queue. Can be
- * called even if timer is running.
+ * called even if timer is not running.
*
* @param timer Pointer to cputimer to stop. Cannot be NULL.
*/
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/include/hal/hal_flash.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_flash.h b/hw/hal/include/hal/hal_flash.h
index 98813d1..be3b358 100644
--- a/hw/hal/include/hal/hal_flash.h
+++ b/hw/hal/include/hal/hal_flash.h
@@ -4,7 +4,7 @@
* 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
@@ -19,11 +19,13 @@
#include <inttypes.h>
-int flash_read(uint32_t address, void *dst, uint32_t num_bytes);
-int flash_write(uint32_t address, const void *src, uint32_t num_bytes);
-int flash_erase_sector(uint32_t sector_address);
-int flash_erase(uint32_t address, uint32_t num_bytes);
-int flash_init(void);
+int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
+ uint32_t num_bytes);
+int hal_flash_write(uint8_t flash_id, uint32_t address, const void *src,
+ uint32_t num_bytes);
+int hal_flash_erase_sector(uint8_t flash_id, uint32_t sector_address);
+int hal_flash_erase(uint8_t flash_id, uint32_t address, uint32_t num_bytes);
+int hal_flash_init(void);
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/include/hal/hal_flash_int.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_flash_int.h b/hw/hal/include/hal/hal_flash_int.h
new file mode 100644
index 0000000..ab7e159
--- /dev/null
+++ b/hw/hal/include/hal/hal_flash_int.h
@@ -0,0 +1,47 @@
+/**
+ * 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 H_HAL_FLASH_INT
+#define H_HAL_FLASH_INT
+
+#include <inttypes.h>
+/*
+ * API that flash driver has to implement.
+ */
+struct hal_flash_funcs {
+ int (*hff_read)(uint32_t address, void *dst, uint32_t num_bytes);
+ int (*hff_write)(uint32_t address, const void *src, uint32_t num_bytes);
+ int (*hff_erase_sector)(uint32_t sector_address);
+ int (*hff_sector_info)(int idx, uint32_t *address, uint32_t *size);
+ int (*hff_init)(void);
+};
+
+struct hal_flash {
+ const struct hal_flash_funcs *hf_itf;
+ uint32_t hf_base_addr;
+ uint32_t hf_size;
+ int hf_sector_cnt;
+};
+
+/*
+ * Return size of the flash sector. sec_idx is index to hf_sectors array.
+ */
+uint32_t hal_flash_sector_size(const struct hal_flash *hf, int sec_idx);
+
+/* External function prototype supplied by BSP */
+const struct hal_flash *bsp_flash_dev(uint8_t flash_id);
+
+#endif /* H_HAL_FLASH_INT */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/include/hal/hal_spim.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_spim.h b/hw/hal/include/hal/hal_spim.h
new file mode 100644
index 0000000..fa1eeeb
--- /dev/null
+++ b/hw/hal/include/hal/hal_spim.h
@@ -0,0 +1,44 @@
+/**
+ * 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 H_HAL_SPIM_H_
+#define H_HAL_SPIM_H_
+
+#include <inttypes.h>
+
+/**
+ *
+ * hal_spim_init()
+ *
+ * Sets up a SPI master port ready for data transfer.
+ * Mapping logical port number to pins is dictated by BSP.
+ */
+int hal_spim_init(int port, int mode, int speed);
+
+/*
+ * hal_spim_select()/hal_spim_deselect.
+ * Assert and deassert chip select for the target, respectively.
+ */
+int hal_spim_select(int port);
+int hal_spim_deselect(int port);
+
+/**
+ *
+ * hal_spim_txrx()
+ * Initiate data transfer. Specify TX data or RX data, or both.
+ */
+int hal_spim_txrx(int port, void *tx_buf, int tx_len, void *rx_buf, int rx_len);
+
+#endif /* H_HAL_SPIM_H_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/include/hal/hal_system.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_system.h b/hw/hal/include/hal/hal_system.h
index 3d5569c..19f5ed1 100644
--- a/hw/hal/include/hal/hal_system.h
+++ b/hw/hal/include/hal/hal_system.h
@@ -17,6 +17,6 @@
#ifndef H_HAL_SYSTEM_
#define H_HAL_SYSTEM_
-void system_reset(void);
+void system_reset(void) __attribute((noreturn));
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/include/hal/hal_uart.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_uart.h b/hw/hal/include/hal/hal_uart.h
index 6dc47bd..b308b84 100644
--- a/hw/hal/include/hal/hal_uart.h
+++ b/hw/hal/include/hal/hal_uart.h
@@ -41,7 +41,7 @@ typedef void (*hal_uart_tx_done)(void *arg);
typedef int (*hal_uart_rx_char)(void *arg, uint8_t byte);
/**
- * hal uart init
+ * hal uart init cbs
*
* Initializes given uart. Mapping of logical UART number to physical
* UART/GPIO pins is in BSP.
@@ -85,4 +85,13 @@ void hal_uart_start_tx(int uart);
*/
void hal_uart_start_rx(int uart);
+/**
+ * hal uart blocking tx
+ *
+ * This is type of write where UART has to block until character has been sent.
+ * Used when printing diag output from system crash.
+ * Must be called with interrupts disabled.
+ */
+void hal_uart_blocking_tx(int uart, uint8_t byte);
+
#endif /* H_HAL_UART_H_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/hal/src/hal_flash.c
----------------------------------------------------------------------
diff --git a/hw/hal/src/hal_flash.c b/hw/hal/src/hal_flash.c
new file mode 100644
index 0000000..90fd985
--- /dev/null
+++ b/hw/hal/src/hal_flash.c
@@ -0,0 +1,153 @@
+/**
+ * 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 <inttypes.h>
+#include <assert.h>
+#include <bsp/bsp.h>
+
+#include "hal/hal_flash.h"
+#include "hal/hal_flash_int.h"
+
+int
+hal_flash_init(void)
+{
+ const struct hal_flash *hf;
+ uint8_t i;
+ int rc = 0;
+
+ for (i = 0; ; i++) {
+ hf = bsp_flash_dev(i);
+ if (!hf) {
+ break;
+ }
+ if (hf->hf_itf->hff_init()) {
+ rc = -1;
+ }
+ }
+ return rc;
+}
+
+uint32_t
+hal_flash_sector_size(const struct hal_flash *hf, int sec_idx)
+{
+ uint32_t size;
+ uint32_t start;
+
+ if (hf->hf_itf->hff_sector_info(sec_idx, &start, &size)) {
+ return 0;
+ }
+ return size;
+}
+
+static int
+hal_flash_check_addr(const struct hal_flash *hf, uint32_t addr)
+{
+ if (addr < hf->hf_base_addr || addr > hf->hf_base_addr + hf->hf_size) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+hal_flash_read(uint8_t id, uint32_t address, void *dst, uint32_t num_bytes)
+{
+ const struct hal_flash *hf;
+
+ hf = bsp_flash_dev(id);
+ if (!hf) {
+ return -1;
+ }
+ if (hal_flash_check_addr(hf, address) ||
+ hal_flash_check_addr(hf, address + num_bytes)) {
+ return -1;
+ }
+ return hf->hf_itf->hff_read(address, dst, num_bytes);
+}
+
+int
+hal_flash_write(uint8_t id, uint32_t address, const void *src,
+ uint32_t num_bytes)
+{
+ const struct hal_flash *hf;
+
+ hf = bsp_flash_dev(id);
+ if (!hf) {
+ return -1;
+ }
+ if (hal_flash_check_addr(hf, address) ||
+ hal_flash_check_addr(hf, address + num_bytes)) {
+ return -1;
+ }
+ return hf->hf_itf->hff_write(address, src, num_bytes);
+}
+
+int
+hal_flash_erase_sector(uint8_t id, uint32_t sector_address)
+{
+ const struct hal_flash *hf;
+
+ hf = bsp_flash_dev(id);
+ if (!hf) {
+ return -1;
+ }
+ if (hal_flash_check_addr(hf, sector_address)) {
+ return -1;
+ }
+ return hf->hf_itf->hff_erase_sector(sector_address);
+}
+
+int
+hal_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
+{
+ const struct hal_flash *hf;
+ uint32_t start, size;
+ uint32_t end;
+ uint32_t end_area;
+ int i;
+ int rc;
+
+ hf = bsp_flash_dev(id);
+ if (!hf) {
+ return -1;
+ }
+ if (hal_flash_check_addr(hf, address) ||
+ hal_flash_check_addr(hf, address + num_bytes)) {
+ return -1;
+ }
+
+ end = address + num_bytes;
+ if (end <= address) {
+ /*
+ * Check for wrap-around.
+ */
+ return -1;
+ }
+
+ for (i = 0; i < hf->hf_sector_cnt; i++) {
+ rc = hf->hf_itf->hff_sector_info(i, &start, &size);
+ assert(rc == 0);
+ end_area = start + size;
+ if (address < end_area && end > start) {
+ /*
+ * If some region of eraseable area falls inside sector,
+ * erase the sector.
+ */
+ if (hf->hf_itf->hff_erase_sector(start)) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/include/mcu/mcu_sim.h
----------------------------------------------------------------------
diff --git a/hw/mcu/native/include/mcu/mcu_sim.h b/hw/mcu/native/include/mcu/mcu_sim.h
new file mode 100644
index 0000000..7ab0842
--- /dev/null
+++ b/hw/mcu/native/include/mcu/mcu_sim.h
@@ -0,0 +1,23 @@
+/**
+ * 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 __MCU_SIM_H__
+#define __MCU_SIM_H__
+
+extern char *native_flash_file;
+
+void mcu_sim_parse_args(int argc, char **argv);
+
+#endif /* __MCU_SIM_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/include/mcu/native_bsp.h
----------------------------------------------------------------------
diff --git a/hw/mcu/native/include/mcu/native_bsp.h b/hw/mcu/native/include/mcu/native_bsp.h
new file mode 100644
index 0000000..91d41dc
--- /dev/null
+++ b/hw/mcu/native/include/mcu/native_bsp.h
@@ -0,0 +1,21 @@
+/**
+ * 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 H_NATIVE_BSP_
+#define H_NATIVE_BSP_
+
+extern const struct hal_flash native_flash_dev;
+
+#endif /* H_NATIVE_BSP_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/src/hal_cputime.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_cputime.c b/hw/mcu/native/src/hal_cputime.c
new file mode 100644
index 0000000..6aef643
--- /dev/null
+++ b/hw/mcu/native/src/hal_cputime.c
@@ -0,0 +1,490 @@
+/**
+ * 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 <stdint.h>
+#include <assert.h>
+#include "os/os.h"
+#include "hal/hal_cputime.h"
+
+/* CPUTIME data */
+struct cputime_data
+{
+ uint32_t ticks_per_usec; /* number of ticks per usec */
+ uint32_t timer_isrs; /* Number of timer interrupts */
+ uint32_t ocmp_ints; /* Number of ocmp interrupts */
+ uint32_t uif_ints; /* Number of overflow interrupts */
+ uint32_t last_ostime;
+ uint64_t cputime; /* 64-bit cputime */
+};
+struct cputime_data g_cputime;
+
+/* Queue for timers */
+TAILQ_HEAD(cputime_qhead, cpu_timer) g_cputimer_q;
+
+/* For native cpu implementation */
+#define NATIVE_CPUTIME_STACK_SIZE (1024)
+os_stack_t g_native_cputime_stack[NATIVE_CPUTIME_STACK_SIZE];
+struct os_task g_native_cputime_task;
+
+struct os_callout_func g_native_cputimer;
+struct os_eventq g_native_cputime_evq;
+static uint32_t g_native_cputime_cputicks_per_ostick;
+
+
+/**
+ * Convert cpu time ticks to os ticks.
+ *
+ *
+ * @param cputicks
+ *
+ * @return uint32_t
+ */
+static uint32_t
+native_cputime_ticks_to_osticks(uint32_t cputicks)
+{
+ uint32_t osticks;
+
+ osticks = cputicks / g_native_cputime_cputicks_per_ostick;
+ return osticks;
+}
+
+/**
+ * cputime set ocmp
+ *
+ * Set the OCMP used by the cputime module to the desired cputime.
+ *
+ * @param timer Pointer to timer.
+ */
+static void
+cputime_set_ocmp(struct cpu_timer *timer)
+{
+ uint32_t curtime;
+ uint32_t osticks;
+
+ curtime = cputime_get32();
+ if ((int32_t)(timer->cputime - curtime) < 0) {
+ osticks = 0;
+ } else {
+ osticks = native_cputime_ticks_to_osticks(timer->cputime - curtime);
+ }
+
+ /* Re-start the timer */
+ os_callout_reset(&g_native_cputimer.cf_c, osticks);
+}
+
+/**
+ * cputime chk expiration
+ *
+ * Iterates through the cputimer queue to determine if any timers have expired.
+ * If the timer has expired the timer is removed from the queue and the timer
+ * callback function is executed.
+ *
+ */
+static void
+cputime_chk_expiration(void)
+{
+ os_sr_t sr;
+ struct cpu_timer *timer;
+
+ OS_ENTER_CRITICAL(sr);
+ while ((timer = TAILQ_FIRST(&g_cputimer_q)) != NULL) {
+ if ((int32_t)(cputime_get32() - timer->cputime) >= 0) {
+ TAILQ_REMOVE(&g_cputimer_q, timer, link);
+ timer->cb(timer->arg);
+ } else {
+ break;
+ }
+ }
+
+ /* Any timers left on queue? If so, we need to set OCMP */
+ timer = TAILQ_FIRST(&g_cputimer_q);
+ if (timer) {
+ cputime_set_ocmp(timer);
+ } else {
+ os_callout_stop(&g_native_cputimer.cf_c);
+ }
+ OS_EXIT_CRITICAL(sr);
+}
+
+/**
+ * This is the function called when the cputimer fires off.
+ *
+ * @param arg
+ */
+void
+native_cputimer_cb(void *arg)
+{
+ /* Count # of interrupts */
+ ++g_cputime.ocmp_ints;
+
+ /* Execute the timer */
+ cputime_chk_expiration();
+}
+
+void
+native_cputime_task_handler(void *arg)
+{
+ struct os_event *ev;
+ struct os_callout_func *cf;
+
+ while (1) {
+ ev = os_eventq_get(&g_native_cputime_evq);
+ switch (ev->ev_type) {
+ case OS_EVENT_T_TIMER:
+ cf = (struct os_callout_func *)ev;
+ assert(cf->cf_func);
+ cf->cf_func(cf->cf_arg);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
+/**
+ * cputime init
+ *
+ * Initialize the cputime module. This must be called after os_init is called
+ * and before any other timer API are used. This should be called only once
+ * and should be called before the hardware timer is used.
+ *
+ * @param clock_freq The desired cputime frequency, in hertz (Hz).
+ *
+ * @return int 0 on success; -1 on error.
+ */
+int
+cputime_init(uint32_t clock_freq)
+{
+ /* Clock frequency must be at least 1 MHz */
+ if (clock_freq < 1000000U) {
+ return -1;
+ }
+
+ /* Initialize the timer queue */
+ TAILQ_INIT(&g_cputimer_q);
+
+ /* Set the clock frequency */
+ g_cputime.ticks_per_usec = clock_freq / 1000000U;
+ g_native_cputime_cputicks_per_ostick = clock_freq / OS_TICKS_PER_SEC;
+
+ os_task_init(&g_native_cputime_task,
+ "native_cputimer",
+ native_cputime_task_handler,
+ NULL,
+ OS_TASK_PRI_HIGHEST,
+ OS_WAIT_FOREVER,
+ g_native_cputime_stack,
+ NATIVE_CPUTIME_STACK_SIZE);
+
+ /* Initialize the eventq and task */
+ os_eventq_init(&g_native_cputime_evq);
+
+ /* Initialize the callout function */
+ os_callout_func_init(&g_native_cputimer,
+ &g_native_cputime_evq,
+ native_cputimer_cb,
+ NULL);
+
+ return 0;
+}
+
+/**
+ * cputime get64
+ *
+ * Returns cputime as a 64-bit number.
+ *
+ * @return uint64_t The 64-bit representation of cputime.
+ */
+uint64_t
+cputime_get64(void)
+{
+ cputime_get32();
+ return g_cputime.cputime;
+}
+
+/**
+ * cputime get32
+ *
+ * Returns the low 32 bits of cputime.
+ *
+ * @return uint32_t The lower 32 bits of cputime
+ */
+uint32_t
+cputime_get32(void)
+{
+ os_sr_t sr;
+ uint32_t ostime;
+ uint32_t delta_osticks;
+
+ OS_ENTER_CRITICAL(sr);
+ ostime = os_time_get();
+ delta_osticks = (uint32_t)(ostime - g_cputime.last_ostime);
+ if (delta_osticks) {
+ g_cputime.last_ostime = ostime;
+ g_cputime.cputime +=
+ (uint64_t)g_native_cputime_cputicks_per_ostick * delta_osticks;
+
+ }
+ OS_EXIT_CRITICAL(sr);
+
+ return (uint32_t)g_cputime.cputime;
+}
+
+/**
+ * cputime nsecs to ticks
+ *
+ * Converts the given number of nanoseconds into cputime ticks.
+ *
+ * @param usecs The number of nanoseconds to convert to ticks
+ *
+ * @return uint32_t The number of ticks corresponding to 'nsecs'
+ */
+uint32_t
+cputime_nsecs_to_ticks(uint32_t nsecs)
+{
+ uint32_t ticks;
+
+ ticks = ((nsecs * g_cputime.ticks_per_usec) + 999) / 1000;
+ return ticks;
+}
+
+/**
+ * cputime ticks to nsecs
+ *
+ * Convert the given number of ticks into nanoseconds.
+ *
+ * @param ticks The number of ticks to convert to nanoseconds.
+ *
+ * @return uint32_t The number of nanoseconds corresponding to 'ticks'
+ */
+uint32_t
+cputime_ticks_to_nsecs(uint32_t ticks)
+{
+ uint32_t nsecs;
+
+ nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) /
+ g_cputime.ticks_per_usec;
+
+ return nsecs;
+}
+
+/**
+ * cputime usecs to ticks
+ *
+ * Converts the given number of microseconds into cputime ticks.
+ *
+ * @param usecs The number of microseconds to convert to ticks
+ *
+ * @return uint32_t The number of ticks corresponding to 'usecs'
+ */
+uint32_t
+cputime_usecs_to_ticks(uint32_t usecs)
+{
+ uint32_t ticks;
+
+ ticks = (usecs * g_cputime.ticks_per_usec);
+ return ticks;
+}
+
+/**
+ * cputime ticks to usecs
+ *
+ * Convert the given number of ticks into microseconds.
+ *
+ * @param ticks The number of ticks to convert to microseconds.
+ *
+ * @return uint32_t The number of microseconds corresponding to 'ticks'
+ */
+uint32_t
+cputime_ticks_to_usecs(uint32_t ticks)
+{
+ uint32_t us;
+
+ us = (ticks + (g_cputime.ticks_per_usec - 1)) / g_cputime.ticks_per_usec;
+ return us;
+}
+
+/**
+ * cputime delay ticks
+ *
+ * Wait until the number of ticks has elapsed. This is a blocking delay.
+ *
+ * @param ticks The number of ticks to wait.
+ */
+void
+cputime_delay_ticks(uint32_t ticks)
+{
+ uint32_t until;
+
+ until = cputime_get32() + ticks;
+ while ((int32_t)(cputime_get32() - until) < 0) {
+ /* Loop here till finished */
+ }
+}
+
+/**
+ * cputime delay nsecs
+ *
+ * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay.
+ *
+ * @param nsecs The number of nanoseconds to wait.
+ */
+void
+cputime_delay_nsecs(uint32_t nsecs)
+{
+ uint32_t ticks;
+
+ ticks = cputime_nsecs_to_ticks(nsecs);
+ cputime_delay_ticks(ticks);
+}
+
+/**
+ * cputime delay usecs
+ *
+ * Wait until 'usecs' microseconds has elapsed. This is a blocking delay.
+ *
+ * @param usecs The number of usecs to wait.
+ */
+void
+cputime_delay_usecs(uint32_t usecs)
+{
+ uint32_t ticks;
+
+ ticks = cputime_usecs_to_ticks(usecs);
+ cputime_delay_ticks(ticks);
+}
+
+/**
+ * cputime timer init
+ *
+ *
+ * @param timer The timer to initialize. Cannot be NULL.
+ * @param fp The timer callback function. Cannot be NULL.
+ * @param arg Pointer to data object to pass to timer.
+ */
+void
+cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg)
+{
+ assert(timer != NULL);
+ assert(fp != NULL);
+
+ timer->cb = fp;
+ timer->arg = arg;
+ timer->link.tqe_prev = (void *) NULL;
+}
+
+/**
+ * cputime timer start
+ *
+ * Start a cputimer that will expire at 'cputime'. If cputime has already
+ * passed, the timer callback will still be called (at interrupt context).
+ *
+ * @param timer Pointer to timer to start. Cannot be NULL.
+ * @param cputime The cputime at which the timer should expire.
+ */
+void
+cputime_timer_start(struct cpu_timer *timer, uint32_t cputime)
+{
+ struct cpu_timer *entry;
+ os_sr_t sr;
+
+ assert(timer != NULL);
+
+ /* XXX: should this use a mutex? not sure... */
+ OS_ENTER_CRITICAL(sr);
+
+ timer->cputime = cputime;
+ if (TAILQ_EMPTY(&g_cputimer_q)) {
+ TAILQ_INSERT_HEAD(&g_cputimer_q, timer, link);
+ } else {
+ TAILQ_FOREACH(entry, &g_cputimer_q, link) {
+ if ((int32_t)(timer->cputime - entry->cputime) < 0) {
+ TAILQ_INSERT_BEFORE(entry, timer, link);
+ break;
+ }
+ }
+ if (!entry) {
+ TAILQ_INSERT_TAIL(&g_cputimer_q, timer, link);
+ }
+ }
+
+ /* If this is the head, we need to set new OCMP */
+ if (timer == TAILQ_FIRST(&g_cputimer_q)) {
+ cputime_set_ocmp(timer);
+ }
+
+ OS_EXIT_CRITICAL(sr);
+}
+
+/**
+ * cputimer timer relative
+ *
+ * Sets a cpu timer that will expire 'usecs' microseconds from the current
+ * cputime.
+ *
+ * @param timer Pointer to timer. Cannot be NULL.
+ * @param usecs The number of usecs from now at which the timer will expire.
+ */
+void
+cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs)
+{
+ uint32_t cputime;
+
+ assert(timer != NULL);
+
+ cputime = cputime_get32() + cputime_usecs_to_ticks(usecs);
+ cputime_timer_start(timer, cputime);
+}
+
+/**
+ * cputime timer stop
+ *
+ * Stops a cputimer from running. The timer is removed from the timer queue
+ * and interrupts are disabled if no timers are left on the queue. Can be
+ * called even if timer is running.
+ *
+ * @param timer Pointer to cputimer to stop. Cannot be NULL.
+ */
+void
+cputime_timer_stop(struct cpu_timer *timer)
+{
+ os_sr_t sr;
+ int reset_ocmp;
+ struct cpu_timer *entry;
+
+ assert(timer != NULL);
+
+ OS_ENTER_CRITICAL(sr);
+
+ /* If first on queue, we will need to reset OCMP */
+ if (timer->link.tqe_prev != NULL) {
+ reset_ocmp = 0;
+ if (timer == TAILQ_FIRST(&g_cputimer_q)) {
+ entry = TAILQ_NEXT(timer, link);
+ reset_ocmp = 1;
+ }
+ TAILQ_REMOVE(&g_cputimer_q, timer, link);
+ if (reset_ocmp) {
+ if (entry) {
+ cputime_set_ocmp(entry);
+ } else {
+ os_callout_stop(&g_native_cputimer.cf_c);
+ }
+ }
+ }
+
+ OS_EXIT_CRITICAL(sr);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/src/hal_flash.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_flash.c b/hw/mcu/native/src/hal_flash.c
index 63f3645..98eb6df 100644
--- a/hw/mcu/native/src/hal_flash.c
+++ b/hw/mcu/native/src/hal_flash.c
@@ -4,7 +4,7 @@
* 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
@@ -14,79 +14,97 @@
* limitations under the License.
*/
-#include <stdio.h>
+#include <sys/mman.h>
+#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <inttypes.h>
-#include "hal/hal_flash.h"
-
-static FILE *file;
-
-static const struct flash_area_desc {
- uint32_t fad_offset;
- uint32_t fad_length;
- uint32_t fad_sector_id;
-} flash_area_descs[] = {
- { 0x00000000, 16 * 1024, 0 },
- { 0x00004000, 16 * 1024, 1 },
- { 0x00008000, 16 * 1024, 2 },
- { 0x0000c000, 16 * 1024, 3 },
- { 0x00010000, 64 * 1024, 4 },
- { 0x00020000, 128 * 1024, 5 },
- { 0x00040000, 128 * 1024, 6 },
- { 0x00060000, 128 * 1024, 7 },
- { 0x00080000, 128 * 1024, 8 },
- { 0x000a0000, 128 * 1024, 9 },
- { 0x000c0000, 128 * 1024, 10 },
- { 0x000e0000, 128 * 1024, 11 },
+#include <stdlib.h>
+#include "hal/hal_flash_int.h"
+#include "mcu/mcu_sim.h"
+
+char *native_flash_file;
+static int file;
+static void *file_loc;
+
+static int native_flash_init(void);
+static int native_flash_read(uint32_t address, void *dst, uint32_t length);
+static int native_flash_write(uint32_t address, const void *src,
+ uint32_t length);
+static int native_flash_erase_sector(uint32_t sector_address);
+static int native_flash_sector_info(int idx, uint32_t *address, uint32_t *size);
+
+static const struct hal_flash_funcs native_flash_funcs = {
+ .hff_read = native_flash_read,
+ .hff_write = native_flash_write,
+ .hff_erase_sector = native_flash_erase_sector,
+ .hff_sector_info = native_flash_sector_info,
+ .hff_init = native_flash_init
+};
+
+static const uint32_t native_flash_sectors[] = {
+ 0x00000000, /* 16 * 1024 */
+ 0x00004000, /* 16 * 1024 */
+ 0x00008000, /* 16 * 1024 */
+ 0x0000c000, /* 16 * 1024 */
+ 0x00010000, /* 64 * 1024 */
+ 0x00020000, /* 128 * 1024 */
+ 0x00040000, /* 128 * 1024 */
+ 0x00060000, /* 128 * 1024 */
+ 0x00080000, /* 128 * 1024 */
+ 0x000a0000, /* 128 * 1024 */
+ 0x000c0000, /* 128 * 1024 */
+ 0x000e0000, /* 128 * 1024 */
};
-#define FLASH_NUM_AREAS (int)(sizeof flash_area_descs / \
- sizeof flash_area_descs[0])
+#define FLASH_NUM_AREAS (int)(sizeof native_flash_sectors / \
+ sizeof native_flash_sectors[0])
+
+const struct hal_flash native_flash_dev = {
+ .hf_itf = &native_flash_funcs,
+ .hf_base_addr = 0,
+ .hf_size = 1024 * 1024,
+ .hf_sector_cnt = FLASH_NUM_AREAS,
+};
static void
flash_native_erase(uint32_t addr, uint32_t len)
{
- static uint8_t buf[256];
- uint32_t end;
- int chunk_sz;
- int rc;
-
- end = addr + len;
- memset(buf, 0xff, sizeof buf);
+ memset(file_loc + addr, 0xff, len);
+}
- rc = fseek(file, addr, SEEK_SET);
- assert(rc == 0);
+static void
+flash_native_file_open(char *name)
+{
+ int created = 0;
+ extern char *tmpnam(char *s);
+ extern int ftruncate(int fd, off_t length);
- while (addr < end) {
- if (end - addr < sizeof buf) {
- chunk_sz = end - addr;
- } else {
- chunk_sz = sizeof buf;
+ if (!name) {
+ name = tmpnam(NULL);
+ }
+ file = open(name, O_RDWR);
+ if (file < 0) {
+ file = open(name, O_RDWR | O_CREAT);
+ assert(file > 0);
+ created = 1;
+ if (ftruncate(file, native_flash_dev.hf_size) < 0) {
+ assert(0);
}
- rc = fwrite(buf, chunk_sz, 1, file);
- assert(rc == 1);
-
- addr += chunk_sz;
}
- fflush(file);
+ file_loc = mmap(0, native_flash_dev.hf_size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, file, 0);
+ assert(file_loc != MAP_FAILED);
+ if (created) {
+ flash_native_erase(0, native_flash_dev.hf_size);
+ }
}
static void
flash_native_ensure_file_open(void)
{
- int expected_sz;
- int i;
-
- if (file == NULL) {
- expected_sz = 0;
- for (i = 0; i < FLASH_NUM_AREAS; i++) {
- expected_sz += flash_area_descs[i].fad_length;
- }
-
- file = tmpfile();
- assert(file != NULL);
- flash_native_erase(0, expected_sz);
+ if (file == 0) {
+ flash_native_file_open(NULL);
}
}
@@ -109,8 +127,6 @@ flash_native_write_internal(uint32_t address, const void *src, uint32_t length,
flash_native_ensure_file_open();
- fseek(file, address, SEEK_SET);
-
cur = address;
while (cur < end) {
if (end - cur < sizeof buf) {
@@ -121,7 +137,7 @@ flash_native_write_internal(uint32_t address, const void *src, uint32_t length,
/* Ensure data is not being overwritten. */
if (!allow_overwrite) {
- rc = flash_read(cur, buf, chunk_sz);
+ rc = native_flash_read(cur, buf, chunk_sz);
assert(rc == 0);
for (i = 0; i < chunk_sz; i++) {
assert(buf[i] == 0xff);
@@ -131,60 +147,29 @@ flash_native_write_internal(uint32_t address, const void *src, uint32_t length,
cur += chunk_sz;
}
- fseek(file, address, SEEK_SET);
- rc = fwrite(src, length, 1, file);
- assert(rc == 1);
+ memcpy((char *)file_loc + address, src, length);
- fflush(file);
return 0;
}
-int
-flash_write(uint32_t address, const void *src, uint32_t length)
+static int
+native_flash_write(uint32_t address, const void *src, uint32_t length)
{
return flash_native_write_internal(address, src, length, 0);
}
int
-flash_native_overwrite(uint32_t address, const void *src, uint32_t length)
-{
- return flash_native_write_internal(address, src, length, 1);
-}
-
-int
flash_native_memset(uint32_t offset, uint8_t c, uint32_t len)
{
- uint8_t buf[256];
- int chunk_sz;
- int rc;
-
- memset(buf, c, sizeof buf);
-
- while (len > 0) {
- if (len > sizeof buf) {
- chunk_sz = sizeof buf;
- } else {
- chunk_sz = len;
- }
-
- rc = flash_native_overwrite(offset, buf, chunk_sz);
- if (rc != 0) {
- return rc;
- }
-
- offset += chunk_sz;
- len -= chunk_sz;
- }
-
+ memset(file_loc + offset, c, len);
return 0;
}
-int
-flash_read(uint32_t address, void *dst, uint32_t length)
+static int
+native_flash_read(uint32_t address, void *dst, uint32_t length)
{
flash_native_ensure_file_open();
- fseek(file, address, SEEK_SET);
- fread(dst, length, 1, file);
+ memcpy(dst, (char *)file_loc + address, length);
return 0;
}
@@ -195,7 +180,7 @@ find_area(uint32_t address)
int i;
for (i = 0; i < FLASH_NUM_AREAS; i++) {
- if (flash_area_descs[i].fad_offset == address) {
+ if (native_flash_sectors[i] == address) {
return i;
}
}
@@ -203,12 +188,24 @@ find_area(uint32_t address)
return -1;
}
-int
-flash_erase_sector(uint32_t sector_address)
+static int
+flash_sector_len(int sector)
+{
+ uint32_t end;
+
+ if (sector == FLASH_NUM_AREAS - 1) {
+ end = native_flash_dev.hf_size + native_flash_sectors[0];
+ } else {
+ end = native_flash_sectors[sector + 1];
+ }
+ return end - native_flash_sectors[sector];
+}
+
+static int
+native_flash_erase_sector(uint32_t sector_address)
{
- int next_sector_id;
- int sector_id;
int area_id;
+ uint32_t len;
flash_native_ensure_file_open();
@@ -216,59 +213,27 @@ flash_erase_sector(uint32_t sector_address)
if (area_id == -1) {
return -1;
}
-
- sector_id = flash_area_descs[area_id].fad_sector_id;
- while (1) {
- flash_native_erase(sector_address,
- flash_area_descs[area_id].fad_length);
-
- area_id++;
- if (area_id >= FLASH_NUM_AREAS) {
- break;
- }
-
- next_sector_id = flash_area_descs[area_id].fad_sector_id;
- if (next_sector_id != sector_id) {
- break;
- }
-
- sector_id = next_sector_id;
- }
-
+ len = flash_sector_len(area_id);
+ flash_native_erase(sector_address, len);
return 0;
}
-int
-flash_erase(uint32_t address, uint32_t num_bytes)
+static int
+native_flash_sector_info(int idx, uint32_t *address, uint32_t *size)
{
- const struct flash_area_desc *area;
- uint32_t end;
- int i;
-
- flash_native_ensure_file_open();
-
- end = address + num_bytes;
-
- for (i = 0; i < FLASH_NUM_AREAS; i++) {
- area = flash_area_descs + i;
-
- if (area->fad_offset >= end) {
- return 0;
- }
-
- if (address >= area->fad_offset &&
- address < area->fad_offset + area->fad_length) {
-
- flash_native_erase(area->fad_offset, area->fad_length);
- }
- }
+ assert(idx < FLASH_NUM_AREAS);
+ *address = native_flash_sectors[idx];
+ *size = flash_sector_len(idx);
return 0;
}
-int
-flash_init(void)
+static int
+native_flash_init(void)
{
+ if (native_flash_file) {
+ flash_native_file_open(native_flash_file);
+ }
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/src/hal_gpio.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_gpio.c b/hw/mcu/native/src/hal_gpio.c
index 5e864de..98f7c8c 100644
--- a/hw/mcu/native/src/hal_gpio.c
+++ b/hw/mcu/native/src/hal_gpio.c
@@ -78,7 +78,6 @@ void gpio_write(int pin, int val)
return;
}
hal_gpio[pin].val = (val != 0);
- printf("GPIO %d is now %d\n", pin, val);
}
int
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/src/hal_system.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_system.c b/hw/mcu/native/src/hal_system.c
index 00a981e..eb64b60 100644
--- a/hw/mcu/native/src/hal_system.c
+++ b/hw/mcu/native/src/hal_system.c
@@ -4,7 +4,7 @@
* 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
@@ -13,9 +13,54 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
#include "hal/hal_system.h"
+#include "mcu/mcu_sim.h"
void
system_reset(void)
-{ }
+{
+ while(1);
+}
+
+/*
+ * When running projects within simulator, it's useful to be able to
+ * pass operating info as parameters to simulator program.
+ * This routine is meant to parse those.
+ */
+static void
+usage(char *progname, int rc)
+{
+ const char msg[] =
+ "Usage: %s [-f flash_file]\n"
+ " -f flash_file tells where binary flash file is located. It gets\n"
+ " created if it doesn't already exist.\n";
+
+ write(2, msg, strlen(msg));
+ exit(rc);
+}
+
+void
+mcu_sim_parse_args(int argc, char **argv)
+{
+ int ch;
+ char *progname = argv[0];
+
+ while ((ch = getopt(argc, argv, "hf:")) != -1) {
+ switch (ch) {
+ case 'f':
+ native_flash_file = optarg;
+ break;
+ case 'h':
+ usage(progname, 0);
+ break;
+ default:
+ usage(progname, -1);
+ break;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/hw/mcu/native/src/hal_uart.c
----------------------------------------------------------------------
diff --git a/hw/mcu/native/src/hal_uart.c b/hw/mcu/native/src/hal_uart.c
index dd1d6a8..2f66016 100644
--- a/hw/mcu/native/src/hal_uart.c
+++ b/hw/mcu/native/src/hal_uart.c
@@ -18,14 +18,20 @@
#include "hal/hal_uart.h"
#include "bsp/bsp.h"
+#ifdef MN_LINUX
+#include <pty.h>
+#endif
+#ifdef MN_OSX
#include <util.h>
+#endif
+#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#define UART_MAX_BYTES_PER_POLL 64
-#define UART_POLLER_STACK_SZ 1024
+#define UART_POLLER_STACK_SZ (1024)
#define UART_POLLER_PRIO 0
struct uart {
@@ -117,23 +123,33 @@ uart_poller(void *arg)
}
}
-static int
-uart_pty(void)
+static void
+set_nonblock(int fd)
{
- int fd;
- int loop_slave;
int flags;
- struct termios tios;
- char pty_name[32];
- if (openpty(&fd, &loop_slave, pty_name, NULL, NULL) < 0) {
- perror("openpty() failed");
- return -1;
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1) {
+ const char msg[] = "fcntl(F_GETFL) fail";
+ write(1, msg, sizeof(msg));
+ return;
+ }
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ const char msg[] = "fcntl(F_SETFL) fail";
+ write(1, msg, sizeof(msg));
+ return;
}
+}
- if (tcgetattr(loop_slave, &tios)) {
- perror("tcgetattr() failed");
- goto err;
+static int
+uart_set_attr(int fd)
+{
+ struct termios tios;
+
+ if (tcgetattr(fd, &tios)) {
+ const char msg[] = "tcgetattr() failed";
+ write(1, msg, sizeof(msg));
+ return -1;
}
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
@@ -141,22 +157,34 @@ uart_pty(void)
tios.c_iflag = IGNPAR | IXON;
tios.c_oflag = 0;
tios.c_lflag = 0;
- if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0) {
- perror("tcsetattr() failed");
- goto err;
+ if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
+ const char msg[] = "tcsetattr() failed";
+ write(1, msg, sizeof(msg));
+ return -1;
}
+ return 0;
+}
- flags = fcntl(fd, F_GETFL);
- if (flags == -1) {
- perror("fcntl(F_GETFL) fail");
- goto err;
+static int
+uart_pty(int port)
+{
+ int fd;
+ int loop_slave;
+ char pty_name[32];
+ char msg[64];
+
+ if (openpty(&fd, &loop_slave, pty_name, NULL, NULL) < 0) {
+ const char msg[] = "openpty() failed";
+ write(1, msg, sizeof(msg));
+ return -1;
}
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
- perror("fcntl(F_SETFL) fail");
+
+ if (uart_set_attr(loop_slave)) {
goto err;
}
- printf("console at %s\n", pty_name);
+ snprintf(msg, sizeof(msg), "uart%d at %s\n", port, pty_name);
+ write(1, msg, strlen(msg));
return fd;
err:
close(fd);
@@ -183,6 +211,17 @@ hal_uart_start_rx(int port)
/* nothing to do here */
}
+void
+hal_uart_blocking_tx(int port, uint8_t data)
+{
+ if (port >= UART_CNT || uarts[port].u_open == 0) {
+ return;
+ }
+
+ /* XXX: Count statistics and add error checking here. */
+ (void) write(uarts[port].u_fd, &data, sizeof(data));
+}
+
int
hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done,
hal_uart_rx_char rx_func, void *arg)
@@ -228,10 +267,13 @@ hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
if (uart->u_open) {
return -1;
}
- uart->u_fd = uart_pty();
+
+ uart->u_fd = uart_pty(port);
if (uart->u_fd < 0) {
return -1;
}
+ set_nonblock(uart->u_fd);
+
uart->u_open = 1;
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/egg.yml
----------------------------------------------------------------------
diff --git a/libs/os/egg.yml b/libs/os/egg.yml
index c8bd535..08c4413 100644
--- a/libs/os/egg.yml
+++ b/libs/os/egg.yml
@@ -2,3 +2,13 @@ egg.name: libs/os
egg.vers: 0.1
egg.deps:
- libs/testutil
+egg.req_caps:
+ - console
+
+egg.deps.SHELL:
+ - libs/console/full
+ - libs/shell
+egg.cflags.SHELL: -DSHELL_PRESENT
+
+# Satisfy capability dependencies for the self-contained test executable.
+egg.deps.selftest: libs/console/stub
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/arch/cortex_m4/os/os_arch.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/arch/cortex_m4/os/os_arch.h b/libs/os/include/os/arch/cortex_m4/os/os_arch.h
index b6e0006..1d6bd13 100755
--- a/libs/os/include/os/arch/cortex_m4/os/os_arch.h
+++ b/libs/os/include/os/arch/cortex_m4/os/os_arch.h
@@ -57,9 +57,6 @@ typedef uint32_t os_stack_t;
#define sec_bss_core __attribute__((section(".bss.core")))
#define sec_bss_nz_core __attribute__((section(".bss.core.nz")))
-/* Define "assert" funtion */
-void _Die(char *file, int line);
-
os_stack_t *os_arch_task_stack_init(struct os_task *, os_stack_t *, int);
void timer_handler(void);
void os_arch_ctx_sw(struct os_task *);
@@ -72,6 +69,7 @@ os_error_t os_arch_os_init(void);
os_error_t os_arch_os_start(void);
void os_set_env(void);
void os_arch_init_task_stack(os_stack_t *sf);
+void os_default_irq_asm(void);
/* External function prototypes supplied by BSP */
void os_bsp_systick_init(uint32_t os_tick_usecs);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/arch/sim/os/os_arch.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/arch/sim/os/os_arch.h b/libs/os/include/os/arch/sim/os/os_arch.h
index 7144a44..3466727 100644
--- a/libs/os/include/os/arch/sim/os/os_arch.h
+++ b/libs/os/include/os/arch/sim/os/os_arch.h
@@ -60,4 +60,6 @@ void os_arch_restore_sr(int);
os_error_t os_arch_os_init(void);
os_error_t os_arch_os_start(void);
+void os_bsp_init(void);
+
#endif /* _OS_ARCH_SIM_H */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/os.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os.h b/libs/os/include/os/os.h
index 62b4c11..938f8b7 100644
--- a/libs/os/include/os/os.h
+++ b/libs/os/include/os/os.h
@@ -43,6 +43,8 @@
*/
extern int g_os_started;
+int os_info_init(void);
+
/**
* Returns 1 if the OS has been started, 0 if it has not yet been
* been started.
@@ -84,6 +86,7 @@ void os_init_idle_task(void);
#include "os/os_sched.h"
#include "os/os_eventq.h"
#include "os/os_callout.h"
+#include "os/os_heap.h"
#include "os/os_mutex.h"
#include "os/os_sem.h"
#include "os/os_mempool.h"
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/os_eventq.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_eventq.h b/libs/os/include/os/os_eventq.h
index 56dc436..4abdea4 100644
--- a/libs/os/include/os/os_eventq.h
+++ b/libs/os/include/os/os_eventq.h
@@ -17,6 +17,8 @@
#ifndef _OS_EVENTQ_H
#define _OS_EVENTQ_H
+#include <inttypes.h>
+
struct os_event {
uint8_t ev_queued;
uint8_t ev_type;
@@ -27,6 +29,7 @@ struct os_event {
#define OS_EVENT_QUEUED(__ev) ((__ev)->ev_queued)
#define OS_EVENT_T_TIMER (1)
+#define OS_EVENT_T_MQUEUE_DATA (2)
#define OS_EVENT_T_PERUSER (16)
struct os_eventq {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/os_mbuf.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h
index 9cb26f6..881ddba 100644
--- a/libs/os/include/os/os_mbuf.h
+++ b/libs/os/include/os/os_mbuf.h
@@ -17,11 +17,14 @@
#ifndef _OS_MBUF_H
#define _OS_MBUF_H
+#include "os/os_eventq.h"
/**
- * A mbuf pool to allocate a mbufs out of. This contains a pointer to the
- * mempool to allocate mbufs out of, along with convenient housekeeping
- * information on mbufs in the pool (e.g. length of variable packet header)
+ * A mbuf pool from which to allocate mbufs. This contains a pointer to the os
+ * mempool to allocate mbufs out of, the total number of elements in the pool,
+ * and the amount of "user" data in a non-packet header mbuf. The total pool
+ * size, in bytes, should be:
+ * os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf))
*/
struct os_mbuf_pool {
/**
@@ -34,10 +37,6 @@ struct os_mbuf_pool {
*/
uint16_t omp_mbuf_count;
/**
- * The length of the variable portion of the mbuf header
- */
- uint16_t omp_hdr_len;
- /**
* The memory pool which to allocate mbufs out of
*/
struct os_mempool *omp_pool;
@@ -51,7 +50,11 @@ struct os_mbuf_pkthdr {
/**
* Overall length of the packet.
*/
- uint32_t omp_len;
+ uint16_t omp_len;
+ /**
+ * Flags
+ */
+ uint16_t omp_flags;
/**
* Next packet in the mbuf chain.
*/
@@ -69,13 +72,22 @@ struct os_mbuf {
/**
* Flags associated with this buffer, see OS_MBUF_F_* defintions
*/
- uint16_t om_flags;
+ uint8_t om_flags;
+ /**
+ * Length of packet header
+ */
+ uint8_t om_pkthdr_len;
/**
* Length of data in this buffer
*/
uint16_t om_len;
/**
+ * The mbuf pool this mbuf was allocated out of
+ */
+ struct os_mbuf_pool *om_omp;
+
+ /**
* Pointer to next entry in the chained memory buffer
*/
SLIST_ENTRY(os_mbuf) om_next;
@@ -86,15 +98,10 @@ struct os_mbuf {
uint8_t om_databuf[0];
};
-/*
- * Mbuf flags:
- * - OS_MBUF_F_PKTHDR: Whether or not this mbuf is a packet header mbuf
- * - OS_MBUF_F_USER: The base user defined mbuf flag, start defining your
- * own flags from this flag number.
- */
-
-#define OS_MBUF_F_PKTHDR (0)
-#define OS_MBUF_F_USER (OS_MBUF_F_PKTHDR + 1)
+struct os_mqueue {
+ STAILQ_HEAD(, os_mbuf_pkthdr) mq_head;
+ struct os_event mq_ev;
+};
/*
* Given a flag number, provide the mask for it
@@ -109,12 +116,16 @@ struct os_mbuf {
* @param __om The mbuf to check
*/
#define OS_MBUF_IS_PKTHDR(__om) \
- ((__om)->om_flags & OS_MBUF_F_MASK(OS_MBUF_F_PKTHDR))
-
+ ((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr))
+/* Get a packet header pointer given an mbuf pointer */
#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \
((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf)))
+/* Given a mbuf packet header pointer, return a pointer to the mbuf */
+#define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \
+ (struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
+
/*
* Access the data of a mbuf, and cast it to type
*
@@ -124,31 +135,19 @@ struct os_mbuf {
#define OS_MBUF_DATA(__om, __type) \
(__type) ((__om)->om_data)
-/**
- * Returns the end offset of a mbuf buffer
- *
- * @param __omp
- */
-#define OS_MBUF_END_OFF(__omp) ((__omp)->omp_databuf_len)
-
-/**
- * Returns the start offset of a mbuf buffer
- */
-#define OS_MBUF_START_OFF(__omp) (0)
-
/*
* Called by OS_MBUF_LEADINGSPACE() macro
*/
static inline uint16_t
-_os_mbuf_leadingspace(struct os_mbuf_pool *omp, struct os_mbuf *om)
+_os_mbuf_leadingspace(struct os_mbuf *om)
{
uint16_t startoff;
uint16_t leadingspace;
startoff = 0;
if (OS_MBUF_IS_PKTHDR(om)) {
- startoff = sizeof(struct os_mbuf_pkthdr) + omp->omp_hdr_len;
+ startoff = om->om_pkthdr_len;
}
leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
@@ -167,12 +166,16 @@ _os_mbuf_leadingspace(struct os_mbuf_pool *omp, struct os_mbuf *om)
*
* @return Amount of leading space available in the mbuf
*/
-#define OS_MBUF_LEADINGSPACE(__omp, __om) _os_mbuf_leadingspace(__omp, __om)
+#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
/* Called by OS_MBUF_TRAILINGSPACE() macro. */
static inline uint16_t
-_os_mbuf_trailingspace(struct os_mbuf_pool *omp, struct os_mbuf *om)
+_os_mbuf_trailingspace(struct os_mbuf *om)
{
+ struct os_mbuf_pool *omp;
+
+ omp = om->om_omp;
+
return (&om->om_databuf[0] + omp->omp_databuf_len) - om->om_data;
}
@@ -185,30 +188,54 @@ _os_mbuf_trailingspace(struct os_mbuf_pool *omp, struct os_mbuf *om)
*
* @return The amount of trailing space available in the mbuf
*/
-#define OS_MBUF_TRAILINGSPACE(__omp, __om) _os_mbuf_trailingspace(__omp, __om)
+#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
+/* Mbuf queue functions */
+
+/* Initialize a mbuf queue */
+int os_mqueue_init(struct os_mqueue *, void *arg);
+
+/* Get an element from a mbuf queue */
+struct os_mbuf *os_mqueue_get(struct os_mqueue *);
+
+/* Put an element in a mbuf queue */
+int os_mqueue_put(struct os_mqueue *, struct os_eventq *, struct os_mbuf *);
/* Initialize a mbuf pool */
-int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp, uint16_t,
+int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
uint16_t, uint16_t);
/* Allocate a new mbuf out of the os_mbuf_pool */
struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
/* Allocate a new packet header mbuf out of the os_mbuf_pool */
-struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp);
+struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
+ uint8_t pkthdr_len);
/* Duplicate a mbuf from the pool */
-struct os_mbuf *os_mbuf_dup(struct os_mbuf_pool *omp, struct os_mbuf *m);
+struct os_mbuf *os_mbuf_dup(struct os_mbuf *m);
+
+struct os_mbuf * os_mbuf_off(struct os_mbuf *om, int off, int *out_off);
+
+/* Copy data from an mbuf to a flat buffer. */
+int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
/* Append data onto a mbuf */
-int os_mbuf_append(struct os_mbuf_pool *omp, struct os_mbuf *m, void *,
- uint16_t);
+int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
/* Free a mbuf */
-int os_mbuf_free(struct os_mbuf_pool *omp, struct os_mbuf *mb);
+int os_mbuf_free(struct os_mbuf *mb);
/* Free a mbuf chain */
-int os_mbuf_free_chain(struct os_mbuf_pool *omp, struct os_mbuf *om);
+int os_mbuf_free_chain(struct os_mbuf *om);
+
+void os_mbuf_adj(struct os_mbuf *mp, int req_len);
+int os_mbuf_memcmp(const struct os_mbuf *om, int off, const void *data,
+ int len);
+
+struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len);
+int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
+void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
+void *os_mbuf_extend(struct os_mbuf *om, uint16_t len);
#endif /* _OS_MBUF_H */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/os_sched.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_sched.h b/libs/os/include/os/os_sched.h
index ee84f76..a34c5e3 100644
--- a/libs/os/include/os/os_sched.h
+++ b/libs/os/include/os/os_sched.h
@@ -19,6 +19,10 @@
#include "os/os_task.h"
+typedef int (*os_sched_walk_func_t)(struct os_task *, void *arg);
+
+int os_sched_walk(os_sched_walk_func_t walk_func, void *arg);
+void os_sched_ctx_sw_hook(struct os_task *);
struct os_task *os_sched_get_current_task(void);
void os_sched_set_current_task(struct os_task *);
struct os_task *os_sched_next_task(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/os_task.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_task.h b/libs/os/include/os/os_task.h
index 8f7c746..3f75432 100644
--- a/libs/os/include/os/os_task.h
+++ b/libs/os/include/os/os_task.h
@@ -47,7 +47,8 @@ struct os_task {
uint8_t t_taskid;
uint8_t t_prio;
- uint8_t t_pad[2];
+ uint8_t t_state;
+ uint8_t t_pad;
char *t_name;
os_task_func_t t_func;
@@ -57,8 +58,9 @@ struct os_task {
struct os_sanity_check t_sanity_check;
- os_task_state_t t_state;
os_time_t t_next_wakeup;
+ os_time_t t_run_time;
+ uint32_t t_ctx_sw_cnt;
/* Used to chain task to either the run or sleep list */
TAILQ_ENTRY(os_task) t_os_list;
@@ -71,6 +73,7 @@ int os_task_init(struct os_task *, char *, os_task_func_t, void *, uint8_t,
os_time_t, os_stack_t *, uint16_t);
int os_task_sanity_checkin(struct os_task *);
+uint8_t os_task_count(void);
#endif /* _OS_TASK_H */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/include/os/os_time.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_time.h b/libs/os/include/os/os_time.h
index d934a68..9c2bc23 100644
--- a/libs/os/include/os/os_time.h
+++ b/libs/os/include/os/os_time.h
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-#ifndef _OS_TIME_H
-#define _OS_TIME_H
+#ifndef _OS_TIME_H
+#define _OS_TIME_H
+
+#include <stdint.h>
typedef uint32_t os_time_t;
@@ -34,5 +36,4 @@ void os_time_delay(int32_t osticks);
#define OS_TIME_TICK_GT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) > 0)
#define OS_TIME_TICK_GEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) >= 0)
-
#endif /* _OS_TIME_H */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/arch/cortex_m4/m4/HAL_CM4.s
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/cortex_m4/m4/HAL_CM4.s b/libs/os/src/arch/cortex_m4/m4/HAL_CM4.s
index 1c5651d..dcde207 100755
--- a/libs/os/src/arch/cortex_m4/m4/HAL_CM4.s
+++ b/libs/os/src/arch/cortex_m4/m4/HAL_CM4.s
@@ -201,6 +201,36 @@ SysTick_Handler:
.fnend
.size SysTick_Handler, .-SysTick_Handler
+ .thumb_func
+ .type os_default_irq_asm, %function
+ .global os_default_irq_asm
+os_default_irq_asm:
+ .fnstart
+ .cantunwind
+
+ /*
+ * LR = 0xfffffff9 if we were using MSP as SP
+ * LR = 0xfffffffd if we were using PSP as SP
+ */
+ TST LR,#4
+ ITE EQ
+ MRSEQ R3,MSP
+ MRSNE R3,PSP
+ PUSH {R3-R11,LR}
+ MOV R0, SP
+ BL os_default_irq
+ POP {R3-R11,LR} /* Restore EXC_RETURN */
+ BX LR
+
+ .fnend
+ .size os_default_irq_asm, .-os_default_irq_asm
+
+ /*
+ * Prevent libgcc unwind stuff from getting pulled in.
+ */
+ .section ".data"
+ .global __aeabi_unwind_cpp_pr0
+__aeabi_unwind_cpp_pr0:
.end
/*----------------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/arch/cortex_m4/os_arch_arm.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/cortex_m4/os_arch_arm.c b/libs/os/src/arch/cortex_m4/os_arch_arm.c
index fc69a91..d941809 100755
--- a/libs/os/src/arch/cortex_m4/os_arch_arm.c
+++ b/libs/os/src/arch/cortex_m4/os_arch_arm.c
@@ -17,6 +17,8 @@
#include "os/os.h"
#include "os/os_arch.h"
+#include <bsp/cmsis_nvic.h>
+
/* Initial program status register */
#define INITIAL_xPSR 0x01000000
@@ -50,9 +52,6 @@ struct stack_frame {
uint32_t xpsr;
};
-int die_line;
-char *die_module;
-
#define SVC_ArgN(n) \
register int __r##n __asm("r"#n);
@@ -100,6 +99,8 @@ timer_handler(void)
void
os_arch_ctx_sw(struct os_task *t)
{
+ os_sched_ctx_sw_hook(t);
+
/* Set PendSV interrupt pending bit to force context switch */
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
@@ -107,6 +108,8 @@ os_arch_ctx_sw(struct os_task *t)
void
os_arch_ctx_sw_isr(struct os_task *t)
{
+ os_sched_ctx_sw_hook(t);
+
/* Set PendSV interrupt pending bit to force context switch */
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
@@ -129,15 +132,6 @@ os_arch_restore_sr(os_sr_t isr_ctx)
}
}
-void
-_Die(char *file, int line)
-{
- die_line = line;
- die_module = file;
- while (1) {
- }
-}
-
os_stack_t *
os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
{
@@ -168,6 +162,10 @@ os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
void
os_arch_init(void)
{
+ /*
+ * Trap on divide-by-zero.
+ */
+ SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk;
os_init_idle_task();
}
@@ -195,6 +193,19 @@ os_arch_os_init(void)
NVIC->IP[i] = 0xff;
}
+ /*
+ * Install default interrupt handler, which'll print out system
+ * state at the time of the interrupt, and few other regs which
+ * should help in trying to figure out what went wrong.
+ */
+ NVIC_SetVector(-13, (uint32_t)os_default_irq_asm); /* Hardfault */
+ NVIC_SetVector(MemoryManagement_IRQn, (uint32_t)os_default_irq_asm);
+ NVIC_SetVector(BusFault_IRQn, (uint32_t)os_default_irq_asm);
+ NVIC_SetVector(UsageFault_IRQn, (uint32_t)os_default_irq_asm);
+ for (i = 0; i < NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET; i++) {
+ NVIC_SetVector(i, (uint32_t)os_default_irq_asm);
+ }
+
/* Call bsp related OS initializations */
os_bsp_init();
@@ -224,9 +235,9 @@ os_arch_os_init(void)
/**
* os systick init
- *
+ *
* Initializes systick for the MCU
- *
+ *
* @param os_tick_usecs The number of microseconds in an os time tick
*/
static void
@@ -283,7 +294,7 @@ os_arch_os_start(void)
err = OS_ERR_IN_ISR;
if (__get_IPSR() == 0) {
- /*
+ /*
* The following switch statement is really just a sanity check to
* insure that the os initialization routine was called prior to the
* os start routine.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/arch/cortex_m4/os_fault.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/cortex_m4/os_fault.c b/libs/os/src/arch/cortex_m4/os_fault.c
new file mode 100644
index 0000000..2c7c6fb
--- /dev/null
+++ b/libs/os/src/arch/cortex_m4/os_fault.c
@@ -0,0 +1,85 @@
+/**
+ * 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 <console/console.h>
+#include <hal/hal_system.h>
+#include "os/os.h"
+
+#include <stdint.h>
+#include <unistd.h>
+
+int os_die_line;
+const char *os_die_module;
+
+void __assert_func(const char *file, int line, const char *func, const char *e);
+
+void
+__assert_func(const char *file, int line, const char *func, const char *e)
+{
+ int sr;
+
+ OS_ENTER_CRITICAL(sr);
+ (void)sr;
+ os_die_line = line;
+ os_die_module = file;
+ console_blocking_mode();
+ console_printf("Assert %s; failed in %s:%d\n", e ? e : "", file, line);
+ system_reset();
+}
+
+struct exception_frame {
+ uint32_t r0;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r12;
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t psr;
+};
+
+struct trap_frame {
+ struct exception_frame *ef;
+ uint32_t sp;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+};
+
+void
+os_default_irq(struct trap_frame *tf)
+{
+ console_blocking_mode();
+ console_printf("Unhandled interrupt (%d), exception sp 0x%08x\n",
+ SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk, (uint32_t)tf->ef);
+ console_printf(" r0:0x%08x r1:0x%08x r2:0x%08x r3:0x%08x\n",
+ tf->ef->r0, tf->ef->r1, tf->ef->r2, tf->ef->r3);
+ console_printf(" r4:0x%08x r5:0x%08x r6:0x%08x r7:0x%08x\n",
+ tf->r4, tf->r5, tf->r6, tf->r7);
+ console_printf(" r8:0x%08x r9:0x%08x r10:0x%08x r11:0x%08x\n",
+ tf->r8, tf->r9, tf->r10, tf->r11);
+ console_printf("r12:0x%08x lr:0x%08x pc:0x%08x psr:0x%08x\n",
+ tf->ef->r12, tf->ef->lr, tf->ef->pc, tf->ef->psr);
+ console_printf("ICSR:0x%08x HFSR:0x%08x CFSR:0x%08x\n",
+ SCB->ICSR, SCB->HFSR, SCB->CFSR);
+ console_printf("BFAR:0x%08x MMFAR:0x%08x\n", SCB->BFAR, SCB->MMFAR);
+ system_reset();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/arch/sim/os_arch_sim.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/sim/os_arch_sim.c b/libs/os/src/arch/sim/os_arch_sim.c
index 5d2bfe6..0c83487 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <stdio.h>
+#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/time.h>
@@ -152,6 +153,8 @@ os_arch_ctx_sw(struct os_task *next_t)
}
}
+ os_sched_ctx_sw_hook(next_t);
+
os_sched_set_current_task(next_t);
sf = (struct stack_frame *) next_t->t_stackptr;
@@ -196,6 +199,8 @@ os_arch_ctx_sw_isr(struct os_task *next_t)
isr_state(&block_isr_off, NULL);
+ os_sched_ctx_sw_hook(next_t);
+
os_sched_set_current_task(next_t);
sf = (struct stack_frame *) next_t->t_stackptr;
@@ -294,8 +299,9 @@ start_timer(void)
rc = setitimer(ITIMER_VIRTUAL, &it, NULL);
if (rc != 0) {
- perror("Cannot set itimer");
- abort();
+ const char msg[] = "Cannot set itimer";
+ write(2, msg, sizeof(msg));
+ _exit(1);
}
}
@@ -308,7 +314,10 @@ os_arch_os_init(void)
TAILQ_INIT(&g_os_sleep_list);
os_init_idle_task();
- os_sanity_task_init();
+ os_sanity_task_init();
+
+ os_bsp_init();
+
return OS_OK;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/arch/sim/os_fault.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/sim/os_fault.c b/libs/os/src/arch/sim/os_fault.c
new file mode 100644
index 0000000..8bd8fbe
--- /dev/null
+++ b/libs/os/src/arch/sim/os_fault.c
@@ -0,0 +1,30 @@
+/**
+ * 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "os/os.h"
+#include "os_priv.h"
+
+void
+__assert_func(const char *file, int line, const char *func, const char *e)
+{
+ char msg[256];
+
+ snprintf(msg, sizeof(msg), "assert at %s:%d\n", file, line);
+ write(1, msg, strlen(msg));
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/os.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os.c b/libs/os/src/os.c
index 3ca3177..581db1d 100644
--- a/libs/os/src/os.c
+++ b/libs/os/src/os.c
@@ -59,6 +59,9 @@ os_init(void)
err = os_arch_os_init();
assert(err == OS_OK);
+
+ err = os_info_init();
+ assert(err == OS_OK);
}
void
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole/blob/29ce5cdc/libs/os/src/os_info.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_info.c b/libs/os/src/os_info.c
new file mode 100644
index 0000000..ebb6f12
--- /dev/null
+++ b/libs/os/src/os_info.c
@@ -0,0 +1,169 @@
+/**
+ * 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 "os/queue.h"
+
+#include "console/console.h"
+#ifdef SHELL_PRESENT
+#include "shell/shell.h"
+#endif
+
+#include <string.h>
+
+struct os_task_info_walk {
+ struct os_task_info *info;
+ int info_cnt;
+};
+
+#define OS_TASK_INFO_NAME_SIZE (32)
+struct os_task_info {
+ uint8_t oti_tid;
+ uint8_t oti_prio;
+ uint8_t oti_state;
+ uint8_t oti_pad1;
+ uint16_t oti_flags;
+ uint16_t oti_stack_size;
+ uint32_t oti_csw_cnt;
+ os_time_t oti_next_wakeup;
+ os_time_t oti_run_time;
+ char oti_name[OS_TASK_INFO_NAME_SIZE];
+};
+
+int os_task_info_get(struct os_task_info *info, int info_cnt);
+
+#ifdef SHELL_PRESENT
+struct shell_cmd shell_os_tasks_display_cmd;
+#endif
+
+
+#ifdef SHELL_PRESENT
+/* Code to register with shell, and display the results of os_getinfo()
+ */
+
+
+int
+shell_os_tasks_display(int argc, char **argv)
+{
+ struct os_task_info *info;
+ char *name;
+ int i;
+ int found;
+ int rc;
+ uint8_t tcount;
+
+ name = NULL;
+ found = 0;
+
+ if (argv[1] != NULL && strcmp(argv[1], "")) {
+ name = argv[1];
+ }
+
+ tcount = os_task_count();
+
+ info = (struct os_task_info *) os_malloc(
+ sizeof(struct os_task_info) * tcount);
+ if (!info) {
+ rc = -1;
+ goto err;
+ }
+
+ rc = os_task_info_get(info, tcount);
+
+ console_printf("%d tasks: \n", rc);
+ for (i = 0; i < rc; i++) {
+ if (name) {
+ if (strcmp(name, info[i].oti_name)) {
+ continue;
+ } else {
+ found = 1;
+ }
+ }
+
+ console_printf(" %s (prio: %u, nw: %u, flags: 0x%x, "
+ "ssize: %u, cswcnt: %lu, tot_run_time: %ums)",
+ info[i].oti_name,
+ info[i].oti_prio, info[i].oti_next_wakeup, info[i].oti_flags,
+ info[i].oti_stack_size,
+ info[i].oti_csw_cnt, info[i].oti_run_time);
+
+ }
+
+ if (name && !found) {
+ console_printf("Couldn't find task with name %s\n", name);
+ }
+
+ os_free(info);
+
+ return (0);
+err:
+ return (rc);
+}
+
+
+#endif
+
+static int
+_os_task_copy_info(struct os_task *t, void *arg)
+{
+ struct os_task_info_walk *walk;
+
+ walk = (struct os_task_info_walk *) arg;
+
+ if (walk->info_cnt == 0) {
+ /* Stored all the elements we can fit, exit out */
+ return (1);
+ }
+
+ walk->info->oti_tid = t->t_taskid;
+ walk->info->oti_prio = t->t_prio;
+ strncpy(walk->info->oti_name, t->t_name, OS_TASK_INFO_NAME_SIZE);
+ walk->info->oti_state = (uint8_t) t->t_state;
+ walk->info->oti_next_wakeup = t->t_next_wakeup;
+ walk->info->oti_flags = t->t_flags;
+ walk->info->oti_stack_size = t->t_stacksize;
+ walk->info->oti_csw_cnt = t->t_ctx_sw_cnt;
+ walk->info->oti_run_time = t->t_run_time;
+
+ walk->info += 1;
+ walk->info_cnt--;
+
+ return (0);
+}
+
+int
+os_task_info_get(struct os_task_info *info, int info_cnt)
+{
+ struct os_task_info_walk walk;
+
+ walk.info = info;
+ walk.info_cnt = info_cnt;
+
+ os_sched_walk(_os_task_copy_info, (void *) &walk);
+ return (info_cnt - walk.info_cnt);
+}
+
+
+int
+os_info_init(void)
+{
+#ifdef SHELL_PRESENT
+ shell_cmd_register(&shell_os_tasks_display_cmd, "tasks",
+ shell_os_tasks_display);
+#endif
+ return (0);
+}