zoukankan      html  css  js  c++  java
  • Raw-OS源代码分析之同优先级任务切换

            分析的内核版本号截止到2014-04-15,基于1.05正式版,blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现”???”字样,则是未深究理解部分。

            Raw-OS官方站点:http://www.raw-os.org/

            Raw-OS托管地址:https://github.com/jorya/raw-os/


    1.同优先级任务轮转

            比如,系统中创建有两个同样优先级任务Task A和Task B,而且已经增加到就绪队列。


            当Task A时间片用完时,由于同优先级,会被系统调度至就绪队列的末尾,那么Task B就開始执行,当Task B时间片耗尽时,相同也会被系统调度至就绪队列末尾,由此,系统调度时实现相同优先级的轮转。

    2.系统计数的内核实现

            一般对于OS来说,都会有一个系统时钟节拍,来提供系统计数用途,并且,这个系统计数是专门用一个中断来实现,所以在非常多芯片架构都会专门分开tick和timer的外设,至于系统计数,是移植相关的部分,在Raw-OS官网提供的移植都包含这个部分,所以不须要阁下去做


            硬件移植依据Raw-OS的宏配置文件设置tick间隔,初始化芯片外设,这里关心的是内核实现。

            在系统时钟中断服务函数中,重点关注的是raw_time_tick()函数,至于由task 0推送事件,临时还没研究过,所以在内核宏配置我是先不去实现,一般的固定写法是:

    void tick_isr(){
    	/* 中断ISR进入,进入中断时必须先调用 */
    	raw_enter_interrupt();
    
    	/* 宏配置中先不要实现task 0,还没研究过源代码,不懂怎么去解释??? */
    	#ifdef (CONFIG_RAW_TASK_0 == 1)
    		/* task 0 转发??? */
    		task_0_tick_post();
    	#else
    		/* 调用系统时间tick处理函数 */
    		raw_time_tick();
    	#endif
    
    	/* 中断ISR退出,退出中断时必须配套raw_enter_interrupt()使用,这里可能发生中断任务切换 */
    	raw_finish_int();
    }


            那么raw_time_tick()函数就干以下的事



            看着源代码凝视消化一下吧~码字确实是非常累的事情,但尼玛抠图是更累的事情~

            

    RAW_VOID raw_time_tick(void)
    {
    	/* 开启task0宏后,不能在中断调用该函数???要使用task_0_post??? */
    	#if (CONFIG_RAW_TASK_0 > 0)
    	if (raw_int_nesting) {
    		RAW_ASSERT(0);
    	}
    	#endif
    
    	/* 移植相关,调用tick的hook函数 */
    	#if (CONFIG_RAW_USER_HOOK > 0)
    	raw_tick_hook();
    	#endif
    
    	#if (CONFIG_RAW_TICK_TASK > 0)
    	/*
    	 * 在raw_os_init(),依据宏配置会选择是否把tick封装成任务,若封装成任务则会建
    	 * 立一个优先级别为1的任务,而且在任务函数中堵塞在tick_task_obj的信号量上
    	 *
    	 * 假设tick计数为单独一个任务时,在这里释放tick任务信号量,在调度后立即执行tick task
    	 * 终于调用tick_list_update()更新tick list
    	 */
    	raw_task_semaphore_put(&tick_task_obj);
    	#else
    	/* 假设tick计数不作为一个单独任务,直接更新tick list */
    	tick_list_update();
    	#endif
    
    	/* 计算更新任务轮转时间片 */
    	#if (CONFIG_SCHED_FIFO_RR > 0)
    	calculate_time_slice(raw_task_active->priority);
    	#endif
    
    	/* 通知软件定时器任务更新信息,用于处理系统创建的软件定时器部分 */
    	#if (CONFIG_RAW_TIMER > 0)
    	call_timer_task();
    	#endif
    }

        

            那么,终于发生计算任务超时事件实现同优先级轮转会发生在calculate_time_slice()函数中,直接看凝视的源代码:

            

    void calculate_time_slice(RAW_U8 task_prio)
    {
    	RAW_TASK_OBJ   *task_ptr;
    	LIST *head;
    
    	RAW_SR_ALLOC();
    	/* 获取就绪hash表中最高优先级的就绪链表头 */
    	head = &raw_ready_queue.task_ready_list[task_prio];
    
    	RAW_CRITICAL_ENTER();
    
    	/* 就绪链表中没有就绪任务时,返回,这样的情况怎么发生??? */
    	if (is_list_empty(head)) {
    
    		RAW_CRITICAL_EXIT();
    		return;
    	}
    
    	/*
    	 * 当前就绪链表头的下一个元素就是第一个就绪任务,这个任务同一时候也是最高优先级任务
    	 * 通过list_entry获取任务控制块地址
    	 */
    	task_ptr = list_entry(head->next, RAW_TASK_OBJ, task_list);
    
    	/* 假设任务是FIFO调度,则不须要计算时间 */
    	if (task_ptr->sched_way == SCHED_FIFO) {
    
    		RAW_CRITICAL_EXIT();
    		return;
    	}
    
    	/*
    	这里推断获取最高优先级就绪链表中是否仅仅有一个任务,假设是,返回,
    	说明仅仅有一个最高优先级任务时,永远执行这个任务,由于没有同样优先级作为轮转操作
    	注:IDLE任务必须满足这个条件
    	 */
    	if (head->next->next == head)  {
    
    		RAW_CRITICAL_EXIT();
    		return;
    
    	}
    
    	/* 当前任务时间片减1 */
    	if (task_ptr->time_slice) {
    		task_ptr->time_slice--;
    	}
    
    	/* 当前任务时间片不为0,返回,即任务时间片未消耗完,返回 */
    	if (task_ptr->time_slice) {
    		RAW_CRITICAL_EXIT();
    		return;
    	}
    
    	/*
    	 * 任务时间片为0后,将当前执行的任务转移到同优先级别的就绪链表的表尾
    	 * 原来在这里实现同优先级任务的轮转
    	 */
    	move_to_ready_list_end(&raw_ready_queue, task_ptr);
    
    	/* 加入到表尾时重置该任务的时间片,等待下次调度时有原来设置的时间片 */
    	task_ptr->time_slice = task_ptr->time_total;
    
    	RAW_CRITICAL_EXIT();
    }

            最后能够总结了,每一次系统tick都会产生一个中断,然后在tick isr中更新系统时钟,和做一些其它有关须要用到系统时间的操作,对于本节讨论的同优先级任务轮转,会终于在tick isr中更新就绪队列来实现,至于完整地实现更新就绪队列,系统调度,在下节连同系统中断架构一起解说

  • 相关阅读:
    NOIP 模拟 $26; m 降雷皇$
    NOIP 模拟 $26; m 神炎皇$
    NOIP 模拟 $25; m queen$
    NOIP 模拟 $25; m string$
    创建自己的数字货币
    Etherscan
    ETH挖矿
    Claymore's Dua Miner挖矿教程
    微擎微赞密码重置
    SQL引擎及事务支持
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/3799036.html
Copyright © 2011-2022 走看看