空闲线程与阻塞延时的实现

学习目标:

RT-THHRAD


学习内容:

 

在rt-thread的系统中,研究空闲线程与阻塞延时的实现



学习产出:

提示:这里统计学习计划的总量
想要实现空闲线程,并进行阻塞延时,则是需要进行滴答定时器的设计,可以通过滴答定时器进行的延时计算。

    /*Systick的中断频率设置*/
    SysTick_Config(SystemCoreClock /RT_TICK_PER_SECOND);

于是在SYSTick_Handler(void)中执行:

void SysTick_Handler(void)
{
    rt_interrupt_entry ();
    rt_tick_increase();
    rt_interrupt_leave ();
    
}

其中的rt_tick_increase()为:

通过进入就绪线程优先级链表数组,遍历链表数组,将里面的remaining_tick每进入一次滴答定时器中断就进行减一操作

void rt_tick_increase(void)
{
    rt_ubase_t  i;
    struct rt_thread  *thread;
    rt_tick ++;
    /*扫描remaining——tick,不为0就减一*/
    for(i=0;i<RT_THREAD_PRIORITY_MAX;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 ();  //进行任务调度工作

}

扩展 rt_schedule ():

*如果当前的线程是空闲线程
则尝试执行线程1或者线程2是否延时时间结束,否则继续执行空闲线程*/
    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
        {/*如果当前线程1或者线程2,检查另外的线程是否处于延时状态,如果不是就切换到该线程。
            否则判断当前线程是否进入延时,如果是就切换到空闲线程,否则继续执行*/
            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 ; /*线程都在延时,不切换*/
            }
            }
        
    }
#endif
    /*产生上下文切换*/
    rt_hw_context_switch ((rt_uint32_t )&from_thread ->sp ,(rt_uint32_t)&to_thread ->sp );     //进入汇编进行 任务栈调度

}
/*初始化系统调度器*/
/*
****************************************************************************
  初始化rt_thread_priority_table形成自闭和指针
    初始化rt_current_thread为空
    初始化rt_thread_defunct为自闭和指针
******************************************************************************
*/

 

 


void rt_system_scheduler_init(void)
{
    register rt_base_t offset;
    /*线程就绪列表初始化*/
    for (offset=0; offset<RT_THREAD_PRIORITY_MAX;offset ++)
    {
        rt_list_init(&rt_thread_priority_table[offset]);
    }
    /*初始化当前线程控制块指针*/
    rt_current_thread = RT_NULL;
    /*初始化线程休眠列表,当线程创建好没有启动之前会被放入到这个列表*/
    rt_list_init(&rt_thread_defunct);
}

初始化空闲线程,将空闲线程降到最低的优先级。

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_err_t rt_thread_init(struct rt_thread *thread,const  char  *name,void (*entry)(void *parameter),  void               *parameter,  void               *stack_start,         rt_uint32_t        stack_size)
                          
                                       
{     /* 线程结构体开头部分的成员就是rt_object_t类型 */
    rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);
    rt_list_init(&(thread->tlist));
    thread->entry = (void*)entry;
    thread->parameter = parameter;
    thread->stack_addr = stack_start;
    thread->stack_size = stack_size;
  /*初始化线程栈,并返回线程栈指针*/
    thread->sp = (void*)rt_hw_stack_init(thread->entry ,
                                           thread->parameter,
                                    (void*)((char *)thread->stack_addr+thread->stack_size-4));
    return RT_EOK;
}

/**
*该函数将初始化对象并将对象添加到对象容器中
*
*/
void rt_object_init(struct rt_object  *object,
                      enum rt_object_class_type  type,
                                            const char *name)
{
    register rt_base_t temp;
    struct  rt_object_information  *information;
    /*获取对象信息,即从容器里拿到对应对象列表头指针*/
    information = rt_object_get_information (type);
    /*设置对象的类型为静态*/
    object ->type  =type | RT_Object_Class_Static ;
    /*拷贝名字*/
    rt_strncpy(object->name,name,RT_NAME_MAX );
    /*关中断*/
    temp=rt_hw_interrupt_disable ();
    /*将对象插入到容器的对应列表中,不同的类型的对象所在列表不一样*/
    rt_list_insert_after(&(information ->object_list ),&(object ->list ));
    /*开中断*/
    rt_hw_interrupt_enable (temp);
}

上述操作是将线程挂载到容器列表中

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值