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 2016/04/11 23:25:45 UTC

[15/28] incubator-mynewt-core git commit: Get rid of 'os_arch_idle()' in favor of calling 'os_tick_idle()' directly from the idle task. This was motivated by the fact that on most platforms the OS tick will be generated by a MCU-specific timer which impl

Get rid of 'os_arch_idle()' in favor of calling 'os_tick_idle()' directly
from the idle task. This was motivated by the fact that on most platforms
the OS tick will be generated by a MCU-specific timer which implies that
the idle function will also be MCU-specific.


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

Branch: refs/heads/develop
Commit: f59995ecd33ed99997cffd6e04884fc69bf875c4
Parents: 1dcc28c
Author: Neel Natu <ne...@nahannisys.com>
Authored: Wed Apr 6 11:57:17 2016 -0700
Committer: Neel Natu <ne...@nahannisys.com>
Committed: Wed Apr 6 11:57:17 2016 -0700

----------------------------------------------------------------------
 hw/bsp/nrf52pdk/src/os_bsp.c                   | 141 -----------------
 hw/hal/include/hal/hal_os_tick.h               |  35 +++++
 hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c       |  29 ++++
 hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c       | 158 ++++++++++++++++++++
 libs/os/include/os/arch/cortex_m0/os/os_arch.h |   1 -
 libs/os/include/os/arch/cortex_m4/os/os_arch.h |   1 -
 libs/os/include/os/arch/sim/os/os_arch.h       |   1 -
 libs/os/src/arch/cortex_m0/os_arch_arm.c       |  13 --
 libs/os/src/arch/cortex_m4/os_arch_arm.c       |  10 +-
 libs/os/src/arch/sim/os_arch_sim.c             |   2 +-
 libs/os/src/os.c                               |   4 +-
 11 files changed, 228 insertions(+), 167 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/hw/bsp/nrf52pdk/src/os_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52pdk/src/os_bsp.c b/hw/bsp/nrf52pdk/src/os_bsp.c
index f386137..d1e8809 100644
--- a/hw/bsp/nrf52pdk/src/os_bsp.c
+++ b/hw/bsp/nrf52pdk/src/os_bsp.c
@@ -16,12 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#include <assert.h>
-
-#include <os/os.h>
-#include <bsp/cmsis_nvic.h>
-#include <mcu/nrf52.h>
-#include <mcu/nrf52_bitfields.h>
 #include <util/util.h>
 #include <hal/flash_map.h>
 
@@ -83,138 +77,3 @@ os_bsp_init(void)
     flash_area_init(bsp_flash_areas,
       sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0]));
 }
-
-#define CALLOUT_TIMER       NRF_TIMER1
-#define CALLOUT_IRQ         TIMER1_IRQn
-#define CALLOUT_CMPREG      0   /* generate timer interrupt */
-#define CALLOUT_COUNTER     1   /* capture current timer value */
-#define CALLOUT_PRESCALER   4   /* prescaler to generate 1MHz timer freq */
-#define TIMER_LT(__t1, __t2)    ((int32_t)((__t1) - (__t2)) < 0)
-
-static int timer_ticks_per_ostick;
-static os_time_t nrf52_max_idle_ticks;
-static uint32_t lastocmp;
-
-static inline uint32_t
-nrf52_callout_counter(void)
-{
-    /*
-     * Make sure we are not interrupted between invoking the capture task
-     * and reading the value.
-     */
-    OS_ASSERT_CRITICAL();
-
-    /*
-     * Capture the current timer value and return it.
-     */
-    CALLOUT_TIMER->TASKS_CAPTURE[CALLOUT_COUNTER] = 1;
-    return (CALLOUT_TIMER->CC[CALLOUT_COUNTER]);
-}
-
-static inline void
-nrf52_callout_set_ocmp(uint32_t ocmp)
-{
-    uint32_t counter;
-
-    OS_ASSERT_CRITICAL();
-    while (1) {
-        CALLOUT_TIMER->CC[CALLOUT_CMPREG] = ocmp;
-        counter = nrf52_callout_counter();
-        if (TIMER_LT(counter, ocmp)) {
-            break;
-        }
-        ocmp += timer_ticks_per_ostick;
-    }
-}
-
-static void
-nrf52_timer_handler(void)
-{
-    int ticks;
-    os_sr_t sr;
-    uint32_t counter;
-
-    OS_ENTER_CRITICAL(sr);
-
-    /*
-     * Calculate elapsed ticks and advance OS time.
-     */
-    counter = nrf52_callout_counter();
-    ticks = (counter - lastocmp) / timer_ticks_per_ostick;
-    os_time_advance(ticks);
-
-    /* Clear timer interrupt */
-    CALLOUT_TIMER->EVENTS_COMPARE[CALLOUT_CMPREG] = 0;
-
-    /* Update the time associated with the most recent tick */
-    lastocmp += ticks * timer_ticks_per_ostick;
-
-    /* Update the output compare to interrupt at the next tick */
-    nrf52_callout_set_ocmp(lastocmp + timer_ticks_per_ostick);
-
-    OS_EXIT_CRITICAL(sr);
-}
-
-void
-os_bsp_idle(os_time_t ticks)
-{
-    uint32_t ocmp;
-
-    OS_ASSERT_CRITICAL();
-
-    if (ticks > 0) {
-        /*
-         * Enter tickless regime during long idle durations.
-         */
-        if (ticks > nrf52_max_idle_ticks) {
-            ticks = nrf52_max_idle_ticks;
-        }
-        ocmp = lastocmp + ticks * timer_ticks_per_ostick;
-        nrf52_callout_set_ocmp(ocmp);
-    }
-
-    __DSB();
-    __WFI();
-
-    if (ticks > 0) {
-        /*
-         * Update OS time before anything else when coming out of
-         * the tickless regime.
-         */
-        nrf52_timer_handler();
-    }
-}
-
-void
-os_bsp_systick_init(uint32_t os_ticks_per_sec, int prio)
-{
-    lastocmp = 0;
-    timer_ticks_per_ostick = 1000000 / os_ticks_per_sec;
-
-    /*
-     * The maximum number of timer ticks allowed to elapse during idle is
-     * limited to 1/4th the number of timer ticks before the counter rolls
-     * over.
-     */
-    nrf52_max_idle_ticks = (1UL << 30) / timer_ticks_per_ostick;
-
-    /*
-     * Program CALLOUT_TIMER to operate at 1MHz and trigger an output
-     * compare interrupt at a rate of 'os_ticks_per_sec'.
-     */
-    CALLOUT_TIMER->TASKS_STOP = 1;
-    CALLOUT_TIMER->TASKS_CLEAR = 1;
-    CALLOUT_TIMER->MODE = TIMER_MODE_MODE_Timer;
-    CALLOUT_TIMER->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
-    CALLOUT_TIMER->PRESCALER = CALLOUT_PRESCALER;
-
-    CALLOUT_TIMER->CC[CALLOUT_CMPREG] = timer_ticks_per_ostick;
-    CALLOUT_TIMER->INTENSET = TIMER_COMPARE_INT_MASK(CALLOUT_CMPREG);
-    CALLOUT_TIMER->EVENTS_COMPARE[CALLOUT_CMPREG] = 0;
-
-    NVIC_SetPriority(CALLOUT_IRQ, prio);
-    NVIC_SetVector(CALLOUT_IRQ, (uint32_t)nrf52_timer_handler);
-    NVIC_EnableIRQ(CALLOUT_IRQ);
-
-    CALLOUT_TIMER->TASKS_START = 1;     /* start the callout timer */
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/hw/hal/include/hal/hal_os_tick.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_os_tick.h b/hw/hal/include/hal/hal_os_tick.h
new file mode 100644
index 0000000..dce419e
--- /dev/null
+++ b/hw/hal/include/hal/hal_os_tick.h
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _HAL_OS_TICK_H_
+#define _HAL_OS_TICK_H_
+
+#include <os/os_time.h>
+
+/*
+ * Set up the periodic timer to interrupt at a frequency of 'os_ticks_per_sec'.
+ * 'prio' is the cpu-specific priority of the periodic timer interrupt.
+ */
+void os_tick_init(uint32_t os_ticks_per_sec, int prio);
+
+/*
+ * Halt CPU for up to 'n' ticks.
+ */
+void os_tick_idle(os_time_t n);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c b/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c
new file mode 100644
index 0000000..665abd9
--- /dev/null
+++ b/hw/mcu/nordic/nrf51xxx/src/hal_os_tick.c
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <os/os.h>
+#include <hal/hal_os_tick.h>
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    OS_ASSERT_CRITICAL();
+    __DSB();
+    __WFI();
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c b/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c
new file mode 100644
index 0000000..abded0e
--- /dev/null
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_os_tick.c
@@ -0,0 +1,158 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <os/os.h>
+#include <hal/hal_os_tick.h>
+#include <mcu/nrf52_bitfields.h>
+#include <bsp/cmsis_nvic.h>
+
+#define CALLOUT_TIMER       NRF_TIMER1
+#define CALLOUT_IRQ         TIMER1_IRQn
+#define CALLOUT_CMPREG      0   /* generate timer interrupt */
+#define CALLOUT_COUNTER     1   /* capture current timer value */
+#define CALLOUT_PRESCALER   4   /* prescaler to generate 1MHz timer freq */
+#define TIMER_LT(__t1, __t2)    ((int32_t)((__t1) - (__t2)) < 0)
+
+static int timer_ticks_per_ostick;
+static os_time_t nrf52_max_idle_ticks;
+static uint32_t lastocmp;
+
+static inline uint32_t
+nrf52_callout_counter(void)
+{
+    /*
+     * Make sure we are not interrupted between invoking the capture task
+     * and reading the value.
+     */
+    OS_ASSERT_CRITICAL();
+
+    /*
+     * Capture the current timer value and return it.
+     */
+    CALLOUT_TIMER->TASKS_CAPTURE[CALLOUT_COUNTER] = 1;
+    return (CALLOUT_TIMER->CC[CALLOUT_COUNTER]);
+}
+
+static inline void
+nrf52_callout_set_ocmp(uint32_t ocmp)
+{
+    uint32_t counter;
+
+    OS_ASSERT_CRITICAL();
+    while (1) {
+        CALLOUT_TIMER->CC[CALLOUT_CMPREG] = ocmp;
+        counter = nrf52_callout_counter();
+        if (TIMER_LT(counter, ocmp)) {
+            break;
+        }
+        ocmp += timer_ticks_per_ostick;
+    }
+}
+
+static void
+nrf52_timer_handler(void)
+{
+    int ticks;
+    os_sr_t sr;
+    uint32_t counter;
+
+    OS_ENTER_CRITICAL(sr);
+
+    /*
+     * Calculate elapsed ticks and advance OS time.
+     */
+    counter = nrf52_callout_counter();
+    ticks = (counter - lastocmp) / timer_ticks_per_ostick;
+    os_time_advance(ticks);
+
+    /* Clear timer interrupt */
+    CALLOUT_TIMER->EVENTS_COMPARE[CALLOUT_CMPREG] = 0;
+
+    /* Update the time associated with the most recent tick */
+    lastocmp += ticks * timer_ticks_per_ostick;
+
+    /* Update the output compare to interrupt at the next tick */
+    nrf52_callout_set_ocmp(lastocmp + timer_ticks_per_ostick);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t ocmp;
+
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /*
+         * Enter tickless regime during long idle durations.
+         */
+        if (ticks > nrf52_max_idle_ticks) {
+            ticks = nrf52_max_idle_ticks;
+        }
+        ocmp = lastocmp + ticks * timer_ticks_per_ostick;
+        nrf52_callout_set_ocmp(ocmp);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        /*
+         * Update OS time before anything else when coming out of
+         * the tickless regime.
+         */
+        nrf52_timer_handler();
+    }
+}
+
+void
+os_tick_init(uint32_t os_ticks_per_sec, int prio)
+{
+    lastocmp = 0;
+    timer_ticks_per_ostick = 1000000 / os_ticks_per_sec;
+
+    /*
+     * The maximum number of timer ticks allowed to elapse during idle is
+     * limited to 1/4th the number of timer ticks before the counter rolls
+     * over.
+     */
+    nrf52_max_idle_ticks = (1UL << 30) / timer_ticks_per_ostick;
+
+    /*
+     * Program CALLOUT_TIMER to operate at 1MHz and trigger an output
+     * compare interrupt at a rate of 'os_ticks_per_sec'.
+     */
+    CALLOUT_TIMER->TASKS_STOP = 1;
+    CALLOUT_TIMER->TASKS_CLEAR = 1;
+    CALLOUT_TIMER->MODE = TIMER_MODE_MODE_Timer;
+    CALLOUT_TIMER->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
+    CALLOUT_TIMER->PRESCALER = CALLOUT_PRESCALER;
+
+    CALLOUT_TIMER->CC[CALLOUT_CMPREG] = timer_ticks_per_ostick;
+    CALLOUT_TIMER->INTENSET = TIMER_COMPARE_INT_MASK(CALLOUT_CMPREG);
+    CALLOUT_TIMER->EVENTS_COMPARE[CALLOUT_CMPREG] = 0;
+
+    NVIC_SetPriority(CALLOUT_IRQ, prio);
+    NVIC_SetVector(CALLOUT_IRQ, (uint32_t)nrf52_timer_handler);
+    NVIC_EnableIRQ(CALLOUT_IRQ);
+
+    CALLOUT_TIMER->TASKS_START = 1;     /* start the callout timer */
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/libs/os/include/os/arch/cortex_m0/os/os_arch.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/arch/cortex_m0/os/os_arch.h b/libs/os/include/os/arch/cortex_m0/os/os_arch.h
index 23016c7..7231cb7 100755
--- a/libs/os/include/os/arch/cortex_m0/os/os_arch.h
+++ b/libs/os/include/os/arch/cortex_m0/os/os_arch.h
@@ -66,7 +66,6 @@ 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);
-void os_arch_idle(os_time_t ticks);
 
 /* External function prototypes supplied by BSP */
 void os_bsp_systick_init(uint32_t os_ticks_per_sec, int prio);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/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 a68f38a..590542a 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
@@ -66,7 +66,6 @@ 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);
-void os_arch_idle(os_time_t ticks);
 
 /* External function prototypes supplied by BSP */
 void os_bsp_systick_init(uint32_t os_tick_per_sec, int prio);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/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 b1368ee..6b98b8e 100644
--- a/libs/os/include/os/arch/sim/os/os_arch.h
+++ b/libs/os/include/os/arch/sim/os/os_arch.h
@@ -70,7 +70,6 @@ int os_arch_in_critical(void);
 os_error_t os_arch_os_init(void);
 void os_arch_os_stop(void);
 os_error_t os_arch_os_start(void);
-void os_arch_idle(os_time_t ticks);
 
 void os_bsp_init(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/libs/os/src/arch/cortex_m0/os_arch_arm.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/cortex_m0/os_arch_arm.c b/libs/os/src/arch/cortex_m0/os_arch_arm.c
index e8cf44f..8a2015c 100755
--- a/libs/os/src/arch/cortex_m0/os_arch_arm.c
+++ b/libs/os/src/arch/cortex_m0/os_arch_arm.c
@@ -329,16 +329,3 @@ os_arch_os_start(void)
 
     return err;
 }
-
-void
-os_arch_idle(os_time_t ticks)
-{
-    os_sr_t sr;
-
-    OS_ENTER_CRITICAL(sr);
-    __DSB();
-    __WFI();
-    OS_EXIT_CRITICAL(sr);
-
-    return;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/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 dc91e84..b9c0c1d 100755
--- a/libs/os/src/arch/cortex_m4/os_arch_arm.c
+++ b/libs/os/src/arch/cortex_m4/os_arch_arm.c
@@ -19,7 +19,7 @@
 
 #include "os/os.h"
 #include "os/os_arch.h"
-
+#include <hal/hal_os_tick.h>
 #include <bsp/cmsis_nvic.h>
 
 /* Initial program status register */
@@ -246,7 +246,7 @@ os_arch_start(void)
     __set_PSP((uint32_t)t->t_stackptr + offsetof(struct stack_frame, r0));
 
     /* Intitialize and start system clock timer */
-    os_bsp_systick_init(OS_TICKS_PER_SEC, SYSTICK_PRIO);
+    os_tick_init(OS_TICKS_PER_SEC, SYSTICK_PRIO);
 
     /* Mark the OS as started, right before we run our first task */
     g_os_started = 1;
@@ -322,9 +322,3 @@ os_arch_os_start(void)
 
     return err;
 }
-
-void
-os_arch_idle(os_time_t ticks)
-{
-    os_bsp_idle(ticks);
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/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 bbdc641..521d51a 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -177,7 +177,7 @@ os_arch_in_critical(void)
 }
 
 void
-os_arch_idle(os_time_t ticks)
+os_tick_idle(os_time_t ticks)
 {
     int rc;
     struct itimerval it;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f59995ec/libs/os/src/os.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os.c b/libs/os/src/os.c
index 4310178..963fc40 100644
--- a/libs/os/src/os.c
+++ b/libs/os/src/os.c
@@ -20,6 +20,8 @@
 #include "os/os.h"
 #include "os/queue.h"
 
+#include "hal/hal_os_tick.h"
+
 #include <assert.h> 
 
 struct os_task g_idle_task; 
@@ -59,7 +61,7 @@ os_idle_task(void *arg)
         } else {
             /* NOTHING */
         }
-        os_arch_idle(iticks);
+        os_tick_idle(iticks);
         OS_EXIT_CRITICAL(sr);
     }
 }