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