空閒函數 idle
- 如果沒有其它線程可以運行, RTOS 都會爲 CPU 創建一個空閒線程,這個時候 CPU 就運行空閒線程。 在 RTThread 中,空閒線程是系統在初始化的時候創建的優先級最低的線程,空閒線程主體主要是做一些系統內存的清理工作。
- 相關定義。
idle.c
#define IDLE_THREAD_STACK_SIZE 512
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE];
struct rt_thread idle;
extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
rt_ubase_t rt_idletask_ctr = 0;
void rt_thread_idle_entry(void *parameter)
{
parameter = parameter;
while (1)
{
rt_idletask_ctr ++;
}
}
void rt_thread_idle_init(void)
{
rt_thread_init(&idle,
"idle",
rt_thread_idle_entry,
RT_NULL,
&rt_thread_stack[0],
sizeof(rt_thread_stack));
rt_list_insert_before( &(rt_thread_priority_table[RT_THREAD_PRIORITY_MAX-1]),&(idle.tlist) );
}
阻塞延時
- 每個線程控制塊中加入
rt_ubase_t remaining_tick
屬性,表示該線程剩下的tick數。
- 在SysTick_Handler 中斷服務函數中,掃描就緒列表中所有線程的
remaining_tick
,如果不爲0,則減1。然後執行任務調度函數。
void SysTick_Handler(void)
{
rt_interrupt_enter();
rt_tick_increase();
rt_interrupt_leave();
}
void rt_tick_increase(void)
{
rt_ubase_t i;
struct rt_thread *thread;
rt_tick ++;
for(i=0; i < 2; i++)
{
thread = rt_list_entry( rt_thread_priority_table[i].next,
struct rt_thread,
tlist);
if(thread->remaining_tick > 0)
{
thread->remaining_tick --;
}
}
rt_schedule();
}
- 在調度函數中判斷其他線程的
remaining_tick
,如果有等於0的則切換到該線程,如果沒有則判斷當前線程是否要進入延時狀態,如果是,執行空閒線程,否則就不進行任何切換。(只適用於本章節環境)
void rt_schedule(void)
{
struct rt_thread *to_thread;
struct rt_thread *from_thread;
if( rt_current_thread == &idle )
{
if(rt_flag1_thread.remaining_tick == 0)
{
from_thread = rt_current_thread;
to_thread = &rt_flag1_thread;
rt_current_thread = to_thread;
}
else if(rt_flag2_thread.remaining_tick == 0)
{
from_thread = rt_current_thread;
to_thread = &rt_flag2_thread;
rt_current_thread = to_thread;
}
else
{
return;
}
}
else
{
if(rt_current_thread == &rt_flag1_thread)
{
if(rt_flag2_thread.remaining_tick == 0)
{
from_thread = rt_current_thread;
to_thread = &rt_flag2_thread;
rt_current_thread = to_thread;
}
else if(rt_current_thread->remaining_tick != 0)
{
from_thread = rt_current_thread;
to_thread = &idle;
rt_current_thread = to_thread;
}
else
{
return;
}
}
else if(rt_current_thread == &rt_flag2_thread)
{
if(rt_flag1_thread.remaining_tick == 0)
{
from_thread = rt_current_thread;
to_thread = &rt_flag1_thread;
rt_current_thread = to_thread;
}
else if(rt_current_thread->remaining_tick != 0)
{
from_thread = rt_current_thread;
to_thread = &idle;
rt_current_thread = to_thread;
}
else
{
return;
}
}
}
rt_hw_context_switch((rt_uint32_t)&from_thread->sp,(rt_uint32_t)&to_thread->sp);
}
- 通過庫函數配置
SysTick
中斷頻率,優先級。在main
函數中調用。下面配置 25MHz / (25MHz / 100) = 100Hz。即SysTick中斷10ms一次。
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1);
SysTick->LOAD = ticks - 1;
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
工程文件
空閒線程、阻塞延時