• 正文
    • 關(guān)于scmRTOS
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

分享一個(gè)用C++編寫(xiě)的輕量級(jí)RTOS

03/17 10:55
394
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

微信公眾號(hào) | strongerHuang

當(dāng)C++遇上輕量級(jí),你可能覺(jué)得“不可思議”。

今天就來(lái)分享一個(gè)GitHub上開(kāi)源的用C++編寫(xiě)的輕量級(jí)的RTOS:scmRTOS。

關(guān)于scmRTOS

scmRTOS是一個(gè)用C++編寫(xiě)的,適用于MCU的輕量級(jí)實(shí)時(shí)操作系統(tǒng)

最低只需要512字節(jié)RAM(內(nèi)存)、1K的代碼量、具有上下文切換極低的延時(shí)。

開(kāi)源地址:https://github.com/scmrtos/scmrtos

支持的MCU平臺(tái)或類型:

MSP430

AVR

Blackfin

ARM7

Cortex-M0

Cortex-M3

Cortex-M4

STM8

上下文切換耗時(shí)情況:

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

內(nèi)核全用C++編寫(xiě):

內(nèi)核os_kernel.cpp的源代碼量也很小:

#include?"scmRTOS.h"
using?namespace?OS;
OS::TKernel OS::Kernel;
#if?scmRTOS_SUSPENDED_PROCESS_ENABLE != 0OS::TProcessMap OS::TBaseProcess::SuspendedProcessMap = (1ul?<< (PROCESS_COUNT)) -?1;?#endif
TBaseProcess * TKernel::ProcessTable[scmRTOS_PROCESS_COUNT +?1];
//------------------------------------------------------------------------------//// ? ?TKernel functions//#if?scmRTOS_CONTEXT_SWITCH_SCHEME == 0void?TKernel::sched(){? ??uint_fast8_t?NextPrty =?highest_priority(ReadyProcessMap);? ??if(NextPrty != CurProcPriority)? ? {? ??#if?scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1? ? ? ??context_switch_user_hook();? ??#endif
? ? ? ??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);? ? }}#else//------------------------------------------------------------------------------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); }//------------------------------------------------------------------------------#endif?// scmRTOS_CONTEXT_SWITCH_SCHEME
//------------------------------------------------------------------------------//// ? ? ? OS Process's constructor//// ? ? ? Performs: ?// ? ? ? ? ? * initializing process data;// ? ? ? ? ? * registering process in the kernel;// ? ? ? ? ? * initializing stack frame;// ? ? ? ? ? ? ? ? ?//#if?SEPARATE_RETURN_STACK == 0
TBaseProcess::TBaseProcess(?stack_item_t?* StackPoolEnd? ? ? ? ? ? ? ? ? ? ? ? ? , TPriority pr? ? ? ? ? ? ? ? ? ? ? ? ? ,?void?(*exec)()? ? ? ? ? ? ? ? ? ? ??#if?scmRTOS_DEBUG_ENABLE == 1? ? ? ? ? ? ? ? ? ? ? ? ? ,?stack_item_t?* aStackPool? ? ? ? ? ? ? ? ? ? ? ? ? ,?const?char? ?* name_str? ? ? ? ? ? ? ? ? ? ??#endif? ? ? ? ? ? ? ? ? ? ? ? ? ) :?Timeout(0)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?Priority(pr)? ? ? ? ? ? ? ? ? ? ??#if?scmRTOS_DEBUG_ENABLE == 1? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?WaitingFor(0)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?StackPool(aStackPool)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?StackSize(StackPoolEnd - aStackPool)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?Name(name_str)? ? ? ? ? ? ? ? ? ? ??#endif?? ? ? ? ? ? ? ? ? ? ??#if?scmRTOS_PROCESS_RESTART_ENABLE == 1? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?WaitingProcessMap(0)? ? ? ? ? ? ? ? ? ? ??#endif
{? ? TKernel::register_process(this);? ??init_stack_frame( StackPoolEnd? ? ? ? ? ? ? ? ? ? , exec? ? ? ? ? ? ? ??#if?scmRTOS_DEBUG_ENABLE == 1 ? ??? ? ? ? ? ? ? ? ? ? , aStackPool? ? ? ? ? ? ? ??#endif??? ? ? ? ? ? ? ? ? ? );}
#else??// SEPARATE_RETURN_STACK
TBaseProcess::TBaseProcess(?stack_item_t?* Stack? ? ? ? ? ? ? ? ? ? ? ? ? ,?stack_item_t?* RStack? ? ? ? ? ? ? ? ? ? ? ? ? , TPriority pr? ? ? ? ? ? ? ? ? ? ? ? ? ,?void?(*exec)()? ? ? ? ? ? ? ? ? ? ??#if?scmRTOS_DEBUG_ENABLE == 1? ? ? ? ? ? ? ? ? ? ? ? ? ,?stack_item_t?* aStackPool? ? ? ? ? ? ? ? ? ? ? ? ? ,?stack_item_t?* aRStackPool? ? ? ? ? ? ? ? ? ? ? ? ? ,?const?char? ?* name_str? ? ? ? ? ? ? ? ? ? ??#endif? ? ? ? ? ? ? ? ? ? ? ? ? ) :?StackPointer(Stack)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?Timeout(0)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?Priority(pr)? ? ? ? ? ? ? ? ? ? ??#if?scmRTOS_DEBUG_ENABLE == 1? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?WaitingFor(0)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?StackPool(aStackPool)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?StackSize(Stack - aStackPool)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?Name(name_str)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?RStackPool(aRStackPool)? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?RStackSize(RStack - aRStackPool)? ? ? ? ? ? ? ? ? ? ??#endif?? ? ? ? ? ? ? ? ? ? ??#if?scmRTOS_PROCESS_RESTART_ENABLE == 1? ? ? ? ? ? ? ? ? ? ? ? ? ? ,?WaitingProcessMap(0)? ? ? ? ? ? ? ? ? ? ??#endif
{? ? TKernel::register_process(this);? ??init_stack_frame( Stack? ? ? ? ? ? ? ? ? ? , RStack? ? ? ? ? ? ? ? ? ? , exec? ? ? ? ? ? ? ??#if?scmRTOS_DEBUG_ENABLE == 1 ? ??? ? ? ? ? ? ? ? ? ? , aStackPool? ? ? ? ? ? ? ? ? ? , aRStackPool? ? ? ? ? ? ? ??#endif??? ? ? ? ? ? ? ? ? ? );}#endif?// SEPARATE_RETURN_STACK//------------------------------------------------------------------------------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{#ifndef?__GNUC__ ?// avoid GCC bug ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15867 )? ??template<>?void?TIdleProc::exec();#endif
#if?scmRTOS_DEBUG_ENABLE == 1? ??TIdleProc?IdleProc("Idle");#else? ? TIdleProc IdleProc;#endif

}
namespace?OS{? ??template<>?void?TIdleProc::exec()? ? {? ? ? ??for(;;)? ? ? ? {? ? ? ??#if?scmRTOS_IDLE_HOOK_ENABLE == 1? ? ? ? ? ??idle_process_user_hook();? ? ? ??#endif
? ? ? ??#if?scmRTOS_TARGET_IDLE_HOOK_ENABLE == 1? ? ? ? ? ??idle_process_target_hook();? ? ? ??#endif? ? ? ? }? ? }}//------------------------------------------------------------------------------#if?scmRTOS_DEBUG_ENABLE == 1#if?SEPARATE_RETURN_STACK == 0size_t?TBaseProcess::stack_slack()?const{? ? ?size_t?slack =?0;? ? ?const?stack_item_t?* Stack = StackPool;? ? ?while?(*Stack++ == scmRTOS_STACK_PATTERN)? ? ? ? ?slack++;? ? ?return?slack;}#else??// SEPARATE_RETURN_STACKstatic?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);}#endif?// SEPARATE_RETURN_STACK#endif?// scmRTOS_DEBUG_ENABLE//------------------------------------------------------------------------------#if?scmRTOS_PROCESS_RESTART_ENABLE == 1void?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;#if?scmRTOS_DEBUG_ENABLE == 1? ? WaitingFor =?0;#endif}#endif??// scmRTOS_PROCESS_RESTART_ENABLE//------------------------------------------------------------------------------

內(nèi)核主要是處理調(diào)度相關(guān)的內(nèi)容,有認(rèn)真學(xué)習(xí)過(guò)RTOS內(nèi)核機(jī)制的同學(xué)應(yīng)該都能看得懂。

官方針對(duì)不同的MCU平臺(tái),都提供了對(duì)應(yīng)的端口(Port),只需要適當(dāng)修改,即可移植到你工程。

內(nèi)核還支持用戶擴(kuò)展,提供了調(diào)試分析、互斥、“消息隊(duì)列”等功能。

最后,你覺(jué)得這款用C++編寫(xiě)的RTOS怎么樣?

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫(xiě)文章/發(fā)需求
立即登錄

作者黃工,從事嵌入式軟件開(kāi)發(fā)工作8年有余,高級(jí)嵌入式軟件工程師,業(yè)余維護(hù)公眾號(hào)『strongerHuang』,分享嵌入式軟硬件、單片機(jī)、物聯(lián)網(wǎng)等內(nèi)容。