作者 | strongerHuang
关于scmRTOS
https://github.com/scmrtos/scmrtos
MSP430
AVR
Blackfin
ARM7
Cortex-M0
Cortex-M3
Cortex-M4
STM8
900 ns在Cortex-M4上@ 168 MHz
1.8 us在Blackfin上@ 200 MHz
2.7 us在Cortex-M3上@72 MHz
5 us在ARM7上@ 50 MHz
38-42 us在AVR上@ 8 MHz
45-50 us在MSP430上@ 5 MHz
18-20 us在STM8上@ 16 MHz
using namespace OS;
OS::TKernel OS::Kernel;
OS::TProcessMap OS::TBaseProcess::SuspendedProcessMap = (1ul << (PROCESS_COUNT)) - 1;
TBaseProcess * TKernel::ProcessTable[scmRTOS_PROCESS_COUNT + 1];
//------------------------------------------------------------------------------
//
// TKernel functions
//
void TKernel::sched()
{
uint_fast8_t NextPrty = highest_priority(ReadyProcessMap);
if(NextPrty != CurProcPriority)
{
context_switch_user_hook();
stack_item_t* Next_SP = ProcessTable[NextPrty]->StackPointer;
stack_item_t** Curr_SP_addr = &(ProcessTable[CurProcPriority]->StackPointer);
CurProcPriority = NextPrty;
os_context_switcher(Curr_SP_addr, Next_SP);
}
}
//------------------------------------------------------------------------------
void TKernel::sched()
{
uint_fast8_t NextPrty = highest_priority(ReadyProcessMap);
if(NextPrty != CurProcPriority)
{
SchedProcPriority = NextPrty;
raise_context_switch();
do
{
enable_context_switch();
DUMMY_INSTR();
disable_context_switch();
}
while(CurProcPriority != SchedProcPriority); // until context switch done
}
}
//------------------------------------------------------------------------------
stack_item_t* os_context_switch_hook(stack_item_t* sp) { return Kernel.context_switch_hook(sp); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// OS Process's constructor
//
// Performs:
// * initializing process data;
// * registering process in the kernel;
// * initializing stack frame;
//
//
TBaseProcess::TBaseProcess( stack_item_t * StackPoolEnd
, TPriority pr
, void (*exec)()
, stack_item_t * aStackPool
, const char * name_str
) : Timeout(0)
, Priority(pr)
, WaitingFor(0)
, StackPool(aStackPool)
, StackSize(StackPoolEnd - aStackPool)
, Name(name_str)
, WaitingProcessMap(0)
{
TKernel::register_process(this);
init_stack_frame( StackPoolEnd
, exec
, aStackPool
);
}
TBaseProcess::TBaseProcess( stack_item_t * Stack
, stack_item_t * RStack
, TPriority pr
, void (*exec)()
, stack_item_t * aStackPool
, stack_item_t * aRStackPool
, const char * name_str
) : StackPointer(Stack)
, Timeout(0)
, Priority(pr)
, WaitingFor(0)
, StackPool(aStackPool)
, StackSize(Stack - aStackPool)
, Name(name_str)
, RStackPool(aRStackPool)
, RStackSize(RStack - aRStackPool)
, WaitingProcessMap(0)
{
TKernel::register_process(this);
init_stack_frame( Stack
, RStack
, exec
, aStackPool
, aRStackPool
);
}
//------------------------------------------------------------------------------
void TBaseProcess::sleep(timeout_t timeout)
{
TCritSect cs;
Kernel.ProcessTable[Kernel.CurProcPriority]->Timeout = timeout;
Kernel.set_process_unready(Kernel.CurProcPriority);
Kernel.scheduler();
}
//------------------------------------------------------------------------------
void OS::TBaseProcess::wake_up()
{
TCritSect cs;
if(this->Timeout)
{
this->Timeout = 0;
Kernel.set_process_ready(this->Priority);
Kernel.scheduler();
}
}
//------------------------------------------------------------------------------
void OS::TBaseProcess::force_wake_up()
{
TCritSect cs;
this->Timeout = 0;
Kernel.set_process_ready(this->Priority);
Kernel.scheduler();
}
//------------------------------------------------------------------------------
//
//
// Idle Process
//
//
namespace OS
{
template<> void TIdleProc::exec();
TIdleProc IdleProc("Idle");
TIdleProc IdleProc;
}
namespace OS
{
template<> void TIdleProc::exec()
{
for(;;)
{
idle_process_user_hook();
idle_process_target_hook();
}
}
}
//------------------------------------------------------------------------------
size_t TBaseProcess::stack_slack() const
{
size_t slack = 0;
const stack_item_t * Stack = StackPool;
while (*Stack++ == scmRTOS_STACK_PATTERN)
slack++;
return slack;
}
static size_t calc_stack_slack(const stack_item_t * Stack)
{
size_t slack = 0;
while (*Stack++ == scmRTOS_STACK_PATTERN)
slack++;
return slack;
}
size_t TBaseProcess::stack_slack() const
{
return calc_stack_slack(StackPool);
}
size_t TBaseProcess::rstack_slack() const
{
return calc_stack_slack(RStackPool);
}
//------------------------------------------------------------------------------
void TBaseProcess::reset_controls()
{
Kernel.set_process_unready(this->Priority);
if(WaitingProcessMap)
{
clr_prio_tag( *WaitingProcessMap, get_prio_tag(Priority) ); // remove current process from service's process map
WaitingProcessMap = 0;
}
Timeout = 0;
WaitingFor = 0;
}
//------------------------------------------------------------------------------