空闲函数 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数。线程初始化时这个值应该为0。 - 在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);
}
工程文件
空闲线程、阻塞延时