Raw-OSソース分析の同優先度タスク切替

4568 ワード

分析したカーネルバージョン番号は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が2つ作成され、準備キューに追加されました.
Raw-OS源代码分析之同优先级任务切换
Task Aタイムスライスが終了すると、同優先度のため、準備キューの最後にシステムがスケジューリングされ、Task Bは実行を開始し、Task Bタイムスライスが消費されると、同じように準備キューの最後にシステムがスケジューリングされ、これにより、システムスケジューリング時に同優先度の回転が実現される.
2.システムカウントのカーネル実装
一般的にOSでは、システムカウントの用途を提供するシステムクロックビートがあり、このシステムカウントは割り込みで実現されるため、多くのチップアーキテクチャでtickとtimerの外付けが分離され、システムカウントについては、移植に関連する部分であり、Raw-OS公式サイトで提供される移植にはこの部分が含まれている.だから閣下でやる必要はない
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-OS源代码分析之同优先级任务切换
ソースコードを見て見つめ消化しましょう~コードワードは確かにとても疲れることですが、ニマはもっと疲れることです~
        
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でやっと準備キューを更新して実現し、更新準備キュー、システムスケジューリングを完全に実現するには、次の節では、システム割り込みアーキテクチャについて説明します.