天天看點

RTX51 Tiny

參考文檔 :RTX51 Tiny 2.02 中文手冊.doc、Keil_Rtx51_tiny_RTOS中文版.pdf

RTX-51 有 2 個版本:Full 和 Tiny。類似的國人寫的 Small RTOS51。

Full 需要的資源較多(8K ROM/450的XDATA),但支援搶占式任務排程和中斷任務,以及任務間互發消息;Tiny 不支援搶占式排程,任務間也不能互發消息,但消耗資源少(7+3*任務數RAM/不占用XDATA)。注意對C8051F/STC類增強型51用large模式

 參考資料見《RTX51 Tiny第2版使用者手冊》

2類庫檔案

RTX51TNY.LIB 用于無代碼分組 (non_banking) 的 RTX51 Tiny 程式。

RTX51BT.LIB用于代碼分組(code_ banking 的 RTX51 Tiny 程式。

一 特點:隻适合51系列的周期性的任務場合(C8051F/STC),最多16個任務,沒有主函數,從_task_ 0開始(用于建立其它任務,然後将自己删除,除_task_ 0外其它都是while(1)死循環),結構小巧隻需要包含#include <rtx51tny.h>并在工程配置中選擇。且需要項目添加CONF_TNY.A51,占用了定時器0和寄存器組1.

RTX51 Tiny
RTX51 Tiny
Memory Model 用 Small 比較好,免得每次聲明變量都寫 data 修飾
RTX51 Tiny
二系統滴答:

  • 配置檔案ConfTny.A51中INT_CLOCK EQU 10000; default is 10000 cycles,意思是時鐘滴答為10000個機器周期,即10000*1uS=10ms。是以

    os_wait(K_TMO, T, 0)定時時間=T*10MS;

    ;定時器時鐘選擇為系統時鐘;因為C51是12T(一個單機器周期nop指令需要12個時鐘周期/震蕩周期(1/fs)),是以機器周期=12/fs(us).

    ;fs=12M;0.001s*12000000=12000

    ;fs=24M;0.001s*24000000=24000

    ;fs=48M;0.001S * 48000000 = 48000

    INT_CLOCK    EQU    24000    ; default is 10000 cycles

  •  TIMESHARING,即循環任務切換每個任務分到時間片,完了該任務被挂起切到其它就緒任務。預設是 5(5*INT_CLOCK),從這點來說Tiny-51适合周期性任務的場合,如果這個值是 0,那麼,Round Robin 的任務輪詢算法會停止,必須你自己手動 os_send_signal 或者 os_switch_task 來切換任務。某些時候,這樣會提高實時性
  • RAMTOP。指定了可用 RAM 的頂部位址,預設是 0FFH,即 256 位元組 RAM,任務多時要改小些
  • 任務若由時間片被動排程,修改時間的方法https://www.cnblogs.com/lizunicon/archive/2009/05/19/1460549.html
  • 我的程式要對一個脈寬30ms左右的脈沖計數,結果開始總是不對,後來才找到毛病。

    改配置檔案的方法:

    1. 打開D:"Keil"C51"RTX_TINY目錄下CONF_TNY.A51檔案,修改兩個參數

  • 如果使用timesharing,則一個延時函數的執行時間=(Tint+Ttimesharing)*任務數+delay/fos
任務的狀态:
1 運作态         (running)                :隻有一個
2 就緒态(read):通過調用延時函數後逾時就處于該狀态
3.阻塞(blocked):調用延時函數但未逾時,或者調用任務切換函數後的狀态。
4 休眠(sleeping):任務聲明但未使用或者已經删除過的任務。
任務的主動切換:
void os_switch_task (void)//同時切換到的任務必須就緒,否則也不能運作。
os_delete和os_wait
主動設定任務就緒:用 os_set_ready 和 isr_set_ready 函數,用于讓那些等待逾時、時間間隔、等待信号的任務設定就緒标志以運作
任務間通訊:用 os_send_signal 和isr_send_signal 函數 


關于         os_wait                的三類參數:K_TMO、K_IVL和K_SIG,可以是前兩個與信号的組合(或邏輯)。其傳回值表明發生的事件,SIG_EVENT(         由os_send_signal 和isr_send_signal                産生),RDY_EVENT(由         os_set_ready 或 isr_set_ready引起                ) TMO_EVENT(由逾時或時間間隔到達引起) 
延時的實際時間隻與基本時間片INT_CLOCK有關,與timesharing無關(而任務的執行時間=         timesharing/         INT_CLOCK                     ).延時函數隻是延遲一定時間後讓其就緒并不保證它馬上運作,是以真正的延時時間還與目前執行任務的狀況和總的任務數有關。
K_TMO:逾時信号不累計,在任務重的時候可能誤差較大
K_IVL:周期信号,可累計保證信号不丢失。
K_SIG
任務的獨占:
方法1:禁止循環任務排程排程:TIMESHARING=0(适應于實時性不高)、關中斷(EA=0/關TO中斷但時間不能太長)
方法2:模仿FULL_RTX51編寫申請和釋放信号量,參考 https://blog.csdn.net/dkr269944905/article/details/72822959
注意事項:
1高優先級中斷任務執行執行過長:原則高優先級中斷的ISR應該盡量簡潔(避免系統滴答中斷的重入),或者讓系統滴答的周期中斷時間長一些(但這樣實時性不好);最好的方法是LONG_USR_ISR=1,此時OS就會保護再入系統滴答中斷的代碼當然會增加開銷。
2          空閑任務:SJMP $ //某些相容的8051有低功耗模式,tinyos支援低功耗,在定時器滴答中斷或者其它中斷時MCU恢複運作。 CPU_IDLE 宏 其實就是置位PCON的空閑模式位降低功耗
                3 優化:盡可能禁止循環任務切換,而主動使用         os_switch_task                、         os_wait                來主動切換降低13個位元組的棧空間保護,同時避免系統滴答周期太快,任務從0開始。

三 函數:
3.1 建立任務:os_create_task         (         taskID                );                ,對應的删除任務os_delete_task (         taskID                );而具體的任務函數時無參數無傳回的
3.2發送信号:char isr_send_signal(unsigned char task_id)、 os_send_signal/os_clear_signal ,前者由中斷函數使用,傳回-1表示任務不存在,0表示成功。 
3.3設定就緒:char isr_set_ready{ unsigned char task_id} 、os_set_ready
3.4任務的切換:char os_switch_task(void) 
3.5等待:char os_wait1(unsigned char event_sel) 、char os_wait2(unsigned char event_sel, /* 要等待的事件 */unsigned char ticks); 
char os_wait(
unsigned char event_sel, /* 要等待的事件 */
unsigned char ticks, /* 要等待的滴答數 */
unsigned int dammy) ,前者隻能等待信号是後者的簡化版



3.4糾正當任務調用OS_Wait(K_IVL| K_SIG )同時等待一個信号和周期任務,在         K_SIG                到達OS_Wait退出而時間間隔并沒有調整而引起後續調用OS_Wait的時間不準問題,:void os_reset_interval(unsigned char ticks) ,使用方法:
switch(os_wait2(KSIG|K_IVL,100))
{
  case TMO_EVENT:
    /* 發生了逾時,不需要 Os_reset_interval*/
    break;
  case SIG_EVCENT:
  /* 收到信号,需要 Os_reset_interval*/
  os_reset_interval(100);
    /* 依信号執行的其它操作 */
  break;
}
… 
3.5增加任務優先級?http://bbs.21ic.com/icview-309676-1-1.html





四調試:
從 Peripherals 菜單選擇 RTX51 Tiny T asklist 顯示該對話框 
TID 是在任務定義中指定的任務 ID。
Task Name 是任務函數的名字。
State 是任務目前的狀态。
Wait for Event 指出任務正在等待什麼事件。
Sig 顯示任務信号标志的狀态( 1 為置位)。
Timer 訓示任務距逾時的滴答數, 這是一個自由運作的定時器, 僅在任務等待逾時和時間間隔時使用。
Stack 訓示任務棧的起始位址。


           

繼續閱讀