程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 時鐘中斷是rt-thread的線程調度器的驅動力

時鐘中斷是rt-thread的線程調度器的驅動力

編輯:C++入門知識

1 系統時鐘中斷驅動引擎 rt-thread操作系統中當線程時間片耗盡,或是當線程sleep一段時間後喚醒再被調度,此過程又是如何進行的呢?到底是誰來驅動這一過程的呢? 答案是時鐘中斷源。且來看看時鐘中斷例程: 在bsp/stm32f20x/drivers/board.c源文件中存在這麼一個時鐘中斷例程代碼:(這裡以stm32f20x的MCU為例) [cpp]  /**   * This is the timer interrupt service routine.   *   */   void SysTick_Handler(void)   {       /* enter interrupt */       rt_interrupt_enter();//進入中斷          rt_tick_increase();//增加tick          /* leave interrupt */       rt_interrupt_leave();//離開中斷   }     其中rt_tick_increase的函數如下定義: [cpp]   /**   * This function will notify kernel there is one tick passed. Normally,   * this function is invoked by clock ISR.   */   void rt_tick_increase(void)   {       struct rt_thread *thread;          /* increase the global tick */       ++ rt_tick;//全局變量rt_tick加1          /* check time slice */       thread = rt_thread_self();//獲取當前調度的線程          -- thread->remaining_tick;//當前調度的線程的剩余時間片減1       if (thread->remaining_tick == 0)//如果當前調度的線程沒有剩余時間片了       {           /* change to initialized tick */           thread->remaining_tick = thread->init_tick;//重新將剩余時間片設置為初始化時間片              /* yield */           rt_thread_yield();//將此線程從調度器就緒隊列中取出來放到末尾,再次然後調度       }          /* check timer */       rt_timer_check();//檢查時鐘鏈表上是否有時間到達的時鐘   }   rt_thread_yield函數已在之前的文章http://blog.csdn.net/flydream0/article/details/8584362一文的第7章已有介紹,而rt_timer_check函數在http://blog.csdn.net/flydream0/article/details/8570841#t4一文中第3.3節也已有介紹。 由上述代碼可見,一旦系統產生時鐘中斷,在中斷例程中,系統首先將檢查當前正在運行的線程剩余時間片是否耗盡,如果耗盡則將其從調度器就緒隊列中取出放到末尾,然後再重新調度線程,接著檢查是否有休眠的線程時間到達,如果有,則觸發其時鐘超時回調函數,這個時鐘超時回調函數在之前的文章http://blog.csdn.net/flydream0/article/details/8584362#t2一文中的2.1節介紹初始化線程函數_rt_thread_init時有如下代碼: [cpp]   //...    /* init thread timer */       rt_timer_init(&(thread->thread_timer),//初始化線程的定時器                     thread->name,                     rt_thread_timeout,                     thread,                     0,                     RT_TIMER_FLAG_ONE_SHOT);   //...     可見在線程初始化時,就設置了線程內部時鐘的超時回調函數rt_thread_timeout函數,關鍵就是這個函數會進行一些線程調度的操作,其源碼如下定義: [cpp]   /**   * This function is the timeout function for thread, normally which is invoked   * when thread is timeout to wait some resource.   *   * @param parameter the parameter of thread timeout function   */   void rt_thread_timeout(void *parameter)   {       struct rt_thread *thread;          thread = (struct rt_thread *)parameter;          /* thread check */       RT_ASSERT(thread != RT_NULL);       RT_ASSERT(thread->stat == RT_THREAD_SUSPEND);          /* set error number */       thread->error = -RT_ETIMEOUT;          /* remove from suspend list *///從掛起鏈表中移除       rt_list_remove(&(thread->tlist));          /* insert to schedule ready list */       rt_schedule_insert_thread(thread);//加入調度器          /* do schedule */       rt_schedule();//重新調度   }   可見,其會將當前掛起的線程加入到調度器就緒隊列,然後重新調度。 2 系統時鐘中斷引擎小結 綜上所述,當系統產生時鐘中斷時,首先檢查當前正在運行的線程是否還有剩余時間片,如果耗盡則從就緒隊列中移除放到末尾再重新調度,接著檢查是否存在掛起的線程有時間到達的,如果有,則加入到調度器就緒隊列中,然後重新調度。 3 軟件定時器模式下的驅動引擎 此外,需要注意地是,如果用戶設置使用軟件軟件定時器方式,則系統中還存在一時鐘線程timer_thread,見http://blog.csdn.net/flydream0/article/details/8570841一文,此線程專門隨時系統時鐘tick的增加來檢查定時器是否時間到達,這其中就包含線程的定時器,一旦線程對應的定時器時間到達,則將加入到線程調度器就緒隊列中進行調度。由此可見,在設置了軟件定時器模式時(默認情況下,rt-thread使用硬件定時器),這個timer_thread線程也是rt_thread操作系統線程調度的驅動引擎.   4 如何設置系統時鐘中斷間隔 查看rt-thread操作系統的用戶手冊時,上面有提到rt_thead操作系統的時鐘每個tick的默認間隔為10ms,那麼這個10 ms雙是如何來的呢? 答案是在/bsp/stm32f20x/drivers/board.c源文件中,且看SysTick_Configuration函數的實現: [cpp]  /*******************************************************************************   * Function Name  : SysTick_Configuration   * Description    : Configures the SysTick for OS tick.   * Input          : None   * Output         : None   * Return         : None   *******************************************************************************/   void  SysTick_Configuration(void)   {       RCC_ClocksTypeDef  rcc_clocks;       rt_uint32_t         cnts;          RCC_GetClocksFreq(&rcc_clocks);//獲得系統的晶振頻率          cnts = (rt_uint32_t)rcc_clocks.HCLK_Frequency / RT_TICK_PER_SECOND;//計算出多少次晶振才是一個tick時間片          SysTick_Config(cnts);//配置系統tick       SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//配置時鐘源   }     由上述代碼可見,rt_thread的系統tick是由RT_TICK_PER_SECOND這個宏來配置的,RT_TICK_PER_SECOND在頭文件rtconfig.h文件中定義,如下: [cpp]  /* Tick per Second */   #define RT_TICK_PER_SECOND  100   此參數的含義是1秒包含多少個tick, 這裡默認是100,則默認情況下1秒包含100個tick,那麼即每個tick為10ms,現在明白了吧? 如果我們要修改每個tick的時間隔,則只需要修改RT_TICK_PER_SECOND這個宏的值即可.  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved