From 17b59289fa18298fff598a1f1e527ce4182a975a Mon Sep 17 00:00:00 2001
From: Sasan Golchin <ahmad.golchin@mail.polimi.it>
Date: Thu, 12 May 2016 13:35:05 +0200
Subject: [PATCH] Added USE_CSTIMER macro to board_settings.h. This macro will
 specify whether to use ContextSwitchTimer or not.

---
 .../common/interfaces-impl/portability.cpp    |  5 +--
 .../board_settings.h                          |  2 +
 miosix/kernel/kernel.cpp                      | 42 ++++++++++++++++++-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
index c7a1069d..7600d8d7 100644
--- a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
+++ b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
@@ -39,7 +39,6 @@
 #include <cstring>
 #include <cassert>
 #include "interfaces/cstimer.h"
-//#define CNTX_SWITCH_USE_SYSTICK
 
 /**
  * \internal
@@ -51,7 +50,7 @@
 void SysTick_Handler()   __attribute__((naked));
 void SysTick_Handler()
 {
-#ifdef CNTX_SWITCH_USE_SYSTICK
+#ifndef USE_CSTIMER
     saveContext();
     //Call ISR_preempt(). Name is a C++ mangled name.
     asm volatile("bl _ZN14miosix_private11ISR_preemptEv");
@@ -308,7 +307,7 @@ void IRQportableStartKernel()
     NVIC_SetPriority(SVCall_IRQn,3);//High priority for SVC (Max=0, min=15)
     NVIC_SetPriority(SysTick_IRQn,3);//High priority for SysTick (Max=0, min=15)
     NVIC_SetPriority(MemoryManagement_IRQn,2);//Higher priority for MemoryManagement (Max=0, min=15)
-#ifdef CNTX_SWITCH_USE_SYSTICK
+#ifndef USE_CSTIMER
     SysTick->LOAD=SystemCoreClock/miosix::TICK_FREQ;
     SysTick->CTRL=SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk |
             SysTick_CTRL_CLKSOURCE_Msk;
diff --git a/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/board_settings.h b/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/board_settings.h
index e92c9e20..5223555d 100644
--- a/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/board_settings.h
+++ b/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery/board_settings.h
@@ -30,6 +30,8 @@
 
 #include "util/version.h"
 
+#define USE_CSTIMER
+
 /**
  * \internal
  * Versioning for board_settings.h for out of git tree projects
diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp
index 89e84ecc..962e154c 100644
--- a/miosix/kernel/kernel.cpp
+++ b/miosix/kernel/kernel.cpp
@@ -257,10 +257,12 @@ void IRQaddToSleepingList(SleepData *x)
            cur=cur->next;
        }
     }
+#ifdef USE_CSTIMER
     //Upon any change to the sleeping_list the ContextSwitchTimer should have
     //its interrupt set to the head of the list in order to keep it sync with
     //the list
     ContextSwitchTimer::instance().IRQsetNextInterrupt(sleeping_list->wakeup_time);
+#endif
 }
 
 /**
@@ -280,14 +282,20 @@ bool IRQwakeThreads()
         if(sleeping_list==NULL) break;//If no item in list, return
         //Since list is sorted, if we don't need to wake the first element
         //we don't need to wake the other too
-        //if(tick != sleeping_list->wakeup_time) break;
+#ifdef USE_CSTIMER
         if(ContextSwitchTimer::instance().getCurrentTick() < sleeping_list->wakeup_time) break;
         if (sleeping_list->p != 0) //distinguish between context switches and sleeps
             sleeping_list->p->flags.IRQsetSleep(false);//Wake thread
+#else
+        if(tick != sleeping_list->wakeup_time) break;
+        sleeping_list->p->flags.IRQsetSleep(false);//Wake thread
+#endif
         sleeping_list=sleeping_list->next;//Remove from list
         result=true;
+#ifdef USE_CSTIMER
         //update interrupt of context switch timer
         ContextSwitchTimer::instance().IRQsetNextInterrupt(sleeping_list->wakeup_time);
+#endif
     }
     return result;
 }
@@ -352,6 +360,7 @@ bool Thread::testTerminate()
     return const_cast<Thread*>(cur)->flags.isDeleting();
 }
 
+#ifdef USE_CSTIMER
 inline void Thread::tickSleepUntil(long long absTicks)
 {
     //absTicks: As it is in terms of real ticks of the kernel/timer, there's no 
@@ -388,15 +397,46 @@ void Thread::nanoSleepUntil(long long absoluteTime)
     if (ticks <= ContextSwitchTimer::instance().getCurrentTick()) return;
     tickSleepUntil(ticks);
 }
+#endif
 
 void Thread::sleep(unsigned int ms)
 {
+#ifdef USE_CSTIMER
     nanoSleep(ms * 1000000);
+#else
+    if(ms==0) return;
+    //pauseKernel() here is not enough since even if the kernel is stopped
+    //the tick isr will wake threads, modifying the sleeping_list
+    {
+        FastInterruptDisableLock lock;
+        SleepData d;
+        d.p=const_cast<Thread*>(cur);
+        if(((ms*TICK_FREQ)/1000)>0) d.wakeup_time=getTick()+(ms*TICK_FREQ)/1000;
+        //If tick resolution is too low, wait one tick
+        else d.wakeup_time=getTick()+1;
+        IRQaddToSleepingList(&d);//Also sets SLEEP_FLAG
+    }
+    Thread::yield();
+#endif
 }
 
 void Thread::sleepUntil(long long absoluteTime)
 {
+#ifdef USE_CSTIMER
     nanoSleepUntil(absoluteTime * 1000000);
+#else
+    //pauseKernel() here is not enough since even if the kernel is stopped
+    //the tick isr will wake threads, modifying the sleeping_list
+    {
+        FastInterruptDisableLock lock;
+        if(absoluteTime<=getTick()) return; //Wakeup time in the past, return
+        SleepData d;
+        d.p=const_cast<Thread*>(cur);
+        d.wakeup_time=absoluteTime;
+        IRQaddToSleepingList(&d);//Also sets SLEEP_FLAG
+    }
+    Thread::yield();
+#endif
 }
 
 Thread *Thread::getCurrentThread()
-- 
GitLab