輪叫調度(Round-Robin Scheduling) 輪叫調度(Round Robin Scheduling)算法就是以輪叫的方式依次將請求調度不同的服務器,即每次調度執行i = (i + 1) mod n,并選出第i臺服務器。算法的優點是其簡潔性,它無需記錄當前所有連接的狀態,所以它是一種無狀態調度。 在系統實現時,我們引入了一個額外條件,當服務器的權值為零時,表示該服務器不可用而不被調度。這樣做的目的是將服務器切出服務(如屏蔽服務器故障和系統維護),同時與其他加權算法保持一致。所以,算法要作相應的改動,它的算法流程如下: 輪叫調度算法流程 假設有一組服務器S = {S0, S1, …, Sn-1},一個指示變量i表示上一次選擇的 服務器,W(Si)表示服務器Si的權值。變量i被初始化為n-1,其中n > 0。 j = i; do { j = (j + 1) mod n; if (W(Sj) > 0) { i = j; return Si; } } while (j != i); return NULL; 輪叫調度算法假設所有服務器處理性能均相同,不管服務器的當前連接數和響應速度。該算法相對簡單,不適用于服務器組中處理性能不一的情況,而且當請求服務時間變化比較大時,輪叫調度算法容易導致服務器間的負載不平衡。 雖然Round-Robin DNS方法也是以輪叫調度的方式將一個域名解析到多個IP地址,但輪叫DNS方法的調度粒度是基于每個域名服務器的,域名服務器對域名解析的緩存會妨礙輪叫解析域名生效,這會導致服務器間負載的嚴重不平衡。這里,IPVS輪叫調度算法的粒度是基于每個連接的,同一用戶的不同連接都會被調度到不同的服務器上,所以這種細粒度的輪叫調度要比DNS的輪叫調度優越很多。編輯本段Round-robin
RTX51 Tiny可以配置成使用round-robin多任務。Round-robin容許quasi-parallel執行多任務。任務并不是連續執行的,而是分時間片執行的(可用的CPU時間被分成時間片,RTX51 Tiny把時間片分配給各個任務)。時間片的時間很短(以毫秒為單位),所以任務看起來像連續執行一樣。任務在分配給他的時間片內執行(除非放棄)。然后切換到下一個就緒的任務。這個時間片在RTX51 Tiny Configuration.配置文件中定義. 下面的例子是一個使用round-robin多任務的RTX51 Tiny的程序。這個程序中的兩個任務都是循環計數器。RTX51 Tiny執行稱為job0的任務0。這個函數創建了另一個任務job1。Job0執行完它的時間片后,RTX51 Tiny開始執行job1。Job1執行完它的時間片后,RTX51 Tiny又返回到job0開始執行。然后再切換到job1,如此循環。 #include int counter0; int counter1; void job0 (void) _task_ 0 { os_create (1); /* mark task 1 as ready */ while (1) { /* loop forever */ counter0++; /* update the counter */ } } void job1 (void) _task_ 1 { while (1) { /* loop forever */ counter1++; /* update the counter */ } } 注意:除了一個任務的時片到時,也可以使用函數os_wait 或函數os_switch_task通知RTX51 Tiny可以切換到另一個任務。函數os_wait掛起當前任務直到特定的事件發生。在這期間任何其他的任務都可以執行。 Cooperative 任務切換??如果你禁止了round-robin多任務,你必須設計并執行你的任務從而讓他你們以cooperativ方式工作。特別地,你必須在每個任務的某個地方調用。這些函數告知RTX51 Tiny切換到另一任務。 函數os_wait 和函數os_switch_task的不同之處在于os_wait可以讓你的任務等待某一事件的發生,而函數os_switch_task直接切換到另一個準務就緒的任務。 空閑任務 當沒有任務需要運行時,RTX51 Tiny執行空閑任務。空閑任務只是一個簡單的無限循環,比如: SJMP $ 有些8051器件提供了空閑模式,通過持起任務的執行以降低功耗,直到出現中斷。在這種模式下,所有外圍設備包括中斷系統仍然在繼續工作。 RTX51 Tiny允許你在空閑任務中初始化空閑模式(沒有其他任務需要執行)。當RTX51 Tiny時鐘節拍中斷(或任何其他中斷)出現,微控制器恢復執行程序。空閑任務執行的代碼可以通過配置文件CONF_TNY.A51進行配置并使能 堆棧管理 RTX51 Tiny在8051的IDATA內存區為每個任務維持一個堆棧。當一個任務執行時,給他準備了最大可能需要地堆棧。當任務切換時,前一個任務的堆棧被壓棧并重定位,而把當前任務的堆棧被重定位并彈棧。STACK是堆棧的起始地址。在這個例子中,位于堆棧中的對像包括全局變量,寄存器和位地止內存,剩下的內存用作任務堆棧。內存的頂端在配置文件中定義。配置RTX51 Tiny?
RTX51 Tiny可以由根據用戶的應用來定制。 配置 RTX51 Tiny必須根據你的嵌入式應用來配置。所有地配置參數都在櫝置文件CONF_TNY.A51中,這個文件位于\KEIL\C51\RTXTINY2\文件夾中,文件中的櫝置選可以你做如下事情。 指定時鐘節拍中斷寄存器組 指定時鐘節拍間隔(多個8051機器周期) 指定在時鐘節拍中斷中執用的用戶代碼 指定round-robin溢出時間 使能禁能round-robin任務切換 指定你的應用程序包含了長時間的中斷 指定是否使用了code banking 定義RTX51 Tiny的棧頂 指令需要最小的堆棧空間 指定堆棧錯誤時執行代碼 定義空閑任務操作 CONF_TNY.A51的默認配置包含在RTX51 Tiny的庫中。然而,要在就用中使用配置文件,必須把配置文件拷貝到你的工程文件夾并添加到工程中。 要定制RTX51 Tiny的配置,必須改變CONF_TNY.A51的設置 注意: 如果在工程中不包括配置文件,默認的配置文件將會自動地包含到工程中。后事存在庫中的配置文件可能會對你的應用起到相反效果 硬件時鐘 以下參數指定了如何配置制RTX51 Tiny的配件時鐘 INT_REGBANK 指定制RTX51 Tiny時鐘中斷使用的寄存器組,默認的是寄存器組1 INT_CLOCK 指定時鐘產生中斷前的周期數據。這個值的范圍是1000~65535。較小的值產生中斷較快。這個值用來計算時鐘的重新裝載值(65536-INT_CLOCK)。缺省值是10000。 HW_TIMER_CODE 是一個宏定義,它用來指定在制RTX51 Tiny時鐘節拍中斷中執的代碼。這個宏缺省的設置是從中斷中返回(RETI)如: HW_TIMER_CODE MACRO ; Empty Macro by default RETI ENDM Round-robin Round-robin切換是默認使能的,以下參數用來設定Round-robin切換的時間或禁能Round-robin切換 TIMESHARING 指定任務在進行Round-robin切換前執行的RTX51 Tiny時鐘節拍數。當這個值為0時禁止Round-robin切換。缺省值是5個時鐘節拍。 長時間中斷 一般情況下,中斷服務程序(ISRs)都要求很快執行完畢。有時候,中斷服務程序可能需執行很長一段時間。如果一個高優先級的中斷執的時間超過了節拍間隔,RTX51的時鐘中斷就可能被這個更高優先級的中斷中斷了,并且被以后的RTX51 時鐘中斷重入了。 如果使用了需要運行很長時間的高優先級中斷,就應該考慮減少中斷服務程序的工作量,改變RTX51 時鐘節拍的速率,或考使用以下配置。 LONG_USR_ISR 指定是否使用執行時間超過時鐘節拍的中斷。當這個值置為1時,RTX51 Tiny就會把保護RTX51 Tiny時鐘節拍中斷重入的代碼包含進去。這個值缺省為0 Code banking 以下設置指定RTX51 Tiny應用中是否使用code banking CODE_BANKING 置1使用code banking,清0不使用code banking。缺省值為0 注意:L51_BANK.A51的2.2或更高版本需要RTX51 Tiny 程序使用code banking 堆棧 堆棧的配置選項有幾個。以下參指定了用于堆棧的內存空間的大小和堆棧的最小空間。當CPU的堆棧空間不夠時用一個宏指定去執行哪一段代碼。 RAMTOP指定棧頂地址。最好不要修改這個地址除非你在這個堆棧的上面使用了IDATA變量。 FREE_STACK指定堆棧上的最少可用空間。當切換到一個任務是時,如果RTX51 Tiny檢測到可用的堆棧空間小于這個值,STACK_ERROR宏就會被執行。置為0將禁止對堆棧的檢查,缺省值為20字節 STACK_ERROR是一個宏,它代表了一段在堆棧出現錯誤時執行的代碼。這個宏的缺省代碼為禁能中斷并進入一個無限循環。如 STACK_ERROR MACRO CLR EA ; disable interrupts SJMP $ ; endless loop if stack space is exhausted ENDM 空閑任務 沒有任務需要執行時,RTX51 Tiny就執行空閑任務。空閑任務什么都不做,只是等待RTX51 Tiny的時鐘節拍中斷并切換到另一個就緒的任務。以下參數用來配置RTX51 Tiny空閑任務的不同方面 CPU_IDLE 這是一個宏,代表了在空閑任務中執行的代碼。缺省指令是設置寄存器PCON的空閑模式位。這樣就可以通過掛起程序節省能耗。如 CPU_IDLE MACRO ORL PCON,#1 ; set 8051 CPU to IDLE ENDM CPU_IDLE_CODE 指定CPU_IDLE宏在空閑任務中是否執行。缺省值為0,這樣空閑任務將不包含CPU_IDLE宏 庫文件 RTX51 Tiny包括兩個庫文件 RTX51TNY.LIB is used for non-banking RTX51 Tiny programs RTX51BT.LIB is used for code-banking RTX51 Tiny programs. The RTXTINY2.PRJ project found in the \KEIL\C51\RTXTINY2\SOURCECODE\ folder is used to build these two libraries. 注意:不需要在應用顯式地包含這兩個文件。如果你使用μVision2 IDE或command-line linker時這兩個文件會自動地包含進去。 如果要建立RTX51 Tiny的庫,缺省的配置文件會加入進去。如果不顯式地聲明包含配置文件,默認的配置文件會包含進去。以后對配置文件做的修改會對就用產生意想不到的效果。 優化 可以通過以下方式優化RTX51 Tiny程序 如果可能,禁能round-robin任務切換。Round-robin需要13字節堆棧空間來存儲任務地址和所有寄存器。如果任務切換是通過RTX51 Tiny運行時庫(比如os_wait或 os_switch_task)來觸發的就不需要這些空間了。 使用os_wait而不是使用round-robin的時間耗盡來切換任務。這些會提高系統的反應時間和任務的反應速度 避免把系統時鐘節拍的中斷速率設的太高。把時鐘溢出的時間設的比較短增加了每秒的時鐘節拍數但是減少了每個任的可用時間,因為每個時鐘節拍中斷會使用100-200個周期來運行。所以要把湔出時間設的足夠的小從而減小時鐘節拍中斷帶來的副作用。 使用RTX51 Tiny 要使用RTX51 Tiny,必須成功地生成RTX51程序并編譯連接他們 編寫程序 定義RTX51程序使用關鍵字 _task_ 以RTX51TNY.H的模板使用RTX51 Tiny的內核 包含文件 RTX51 Tiny只需包含一個文件RTX51TNY.H。所有的運行時庫來常量都在這個頭文件中定義。可以采用以下方式包含它: #include <rtx51tny.h> 編程指南 使用RTX51 Tiny編程時須遵循下規則: 包含文件rtx51tny.h 不要創建C主函數,RTX51 Tiny有它自已的主要函數 程序至少創建一個任務 程序必須至少調用一次RTX51 Tiny運行時庫(如os_wait)。否則,連接器將不會把RTX51 Tiny庫包含進去 任務0是你的程序執行的第一任務。必須調用在任務0中調用os_create_task函數來運行其他任務 任務永不返回或退出。任務必須使用while(1)或類似的結構。使用os_delete_task函數可以掛起一個任務 必須在μVision2中或在連接編譯命令行中指定RTX51 Tiny 定義任務 實時或多任務應用由一個或多個完成特定功能的任務組成。RTX51 Tiny支持最多16個任務 任務必須是用_task_聲明的C函數,返回值和參數都必須是void類型的,如 void func (void) _task_ task_id 這里 func is the name of the task function. task_id is a task ID number from 0 to 15 以下例子定義了函數job0作為一個任務,任務編號為0。 void job0 (void) _task_ 0 { while (1) { counter0++; /* increment counter */ } } 注意:所有的任務都必須通過循環實現,而且永不返回 -----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;