?? rtos.s43
字號:
;========================================================================================
;
; 實時多任務(wù)操作系統(tǒng)源代碼
;
; M430/OS V1.20
;
;
; 文件名:RTOS.S43
;
; 作 者:劉兵 public_rtos@163.com 2002年11月27日
;
;----------------------------------------------------------------------------------------
;
; 注 釋:
;
; 本操作系統(tǒng)用的是搶占先式內(nèi)核,如果一個優(yōu)先級比較低的任務(wù)正在運行,另一個優(yōu)先級高的
; 任務(wù)就緒時,系統(tǒng)就把優(yōu)先級低的任務(wù)的現(xiàn)場保存,再切到優(yōu)先級高的任務(wù)運行;優(yōu)先級高的
; 任務(wù)運行完之后,再切到優(yōu)先級低的任務(wù)的斷點處繼續(xù)執(zhí)行。
;
;----------------------------------------------------------------------------------------
;
; 每個任務(wù)必須是以下結(jié)構(gòu):
;
; /--------------\
; ( 開 始 )
; \--------------/
; |
; V
; |----------------------|
; | 任務(wù)本身數(shù)據(jù)初始化 |
; |----------------------|
; |
; |<-------------------------\
; | |
; V |
; |------------------| |
; | 任務(wù)執(zhí)行代碼 | |
; |------------------| |
; | |
; V |
; |----------------------------------------| |
; | 調(diào)用OS_Time_Dly進行延時,這時系統(tǒng)會 | |
; | 把延時的這段時間切到其它任務(wù)來運行 | |
; |----------------------------------------| |
; | |
; \--------------------------/
;
;
; 每個任務(wù)都是一個無限循環(huán),只有開始,沒有結(jié)束。
;
;----------------------------------------------------------------------------------------
;
; 本操作系統(tǒng)包括9個函數(shù):
;
; 1. OS_Init
; 功能:初始化M430/OS的系統(tǒng)數(shù)據(jù)。
;
; 2. OS_Create
; 功能:建立任務(wù)。
;
; 3. OS_Start
; 功能:啟動M430/OS。
;
; 4. OS_Sched
; 功能:進行任務(wù)調(diào)度、任務(wù)切換。
;
; 5. OS_Time_Dly
; 功能:任務(wù)延時函數(shù)。
;
; 6. OS_Free_Task
; 功能:空閑任務(wù)。
;
; 7. OS_Task_Lock
; 功能:禁止任務(wù)調(diào)度。
;
; 8. OS_Task_Unlock
; 功能:允許任務(wù)調(diào)度。
;
; 9. OS_Task_Wakeup
; 功能:喚醒指定優(yōu)先級的任務(wù)
;
;
;
;========================================================================================
NAME RTOS(16)
RSEG CODE(1)
RSEG IDATA0(1)
RSEG CDATA0(1)
RSEG CONST(1)
COMMON INTVEC(1)
#include <msp430x14x.h>
#include "include.h"
#include "rtos.h"
CORRENT_DATA_LENGTH DEFINE Task_Data_Count*2 ;現(xiàn)場數(shù)據(jù)長度
PUBLIC OS_Init
PUBLIC OS_Sched
PUBLIC OS_Time_Dly
PUBLIC OS_Task_Lock
PUBLIC OS_Task_Unlock
PUBLIC OS_Task_Wakeup
PUBLIC OS_Task_Wakeup_I
PUBLIC Task_Flag
PUBLIC OS_Task_Create
PUBLIC OS_Start
EXTERN Task_SP
EXTERN Task_Tick
RSEG CODE
;------------------------------------------------
OS_Task_Create
;功能:建立新任務(wù)。
;參數(shù):任務(wù)TCB結(jié)構(gòu):
; unsigned int *task_base; //任務(wù)入口
; unsigned int *stack_base; //任務(wù)堆棧基址
; unsigned int *stack_point; //任務(wù)堆棧指針的位置
; unsigned int *time_tick; //任務(wù)時鐘嘀嗒數(shù)的位置
; unsigned int stack_size; //堆棧大小
;調(diào)用方式:
; push.w #Task_TCB
; call #OS_Task_Create
; incd.w sp
;
;任務(wù)堆棧示意圖
;
; ^ | |
; | |-----------| //棧頂(低地址)
; | | . |
; | | . |
; | | 棧區(qū) |
; | | . |
; | | . |
; | |-----------| //堆棧指針
; | | . |
; | | . |
; | | 現(xiàn)場數(shù)據(jù) |
; | | . |
; | | . |
; | |-----------|
; | |標志寄存器 |
; | |-----------|
; | | 斷點 |
; | ------------- //棧底(高地址)
;
;
;本函數(shù)共有18行代碼
;------------------------------------------------
push.w r10
push.w r11
mov.w 6(sp),r10 ;取出結(jié)構(gòu)指針
mov.w STACK_BASE(r10),r11 ;取出結(jié)構(gòu)指針指向的堆棧基址(棧頂)
add.w STACK_SIZE(r10),r11 ;找到棧底
mov.w TASK_BASE(r10),-2(r11) ;任務(wù)首地址做為斷點放入棧底
mov.w sr,-4(r11)
bis.w #GIE,-4(r11) ;標志寄存器放入棧底
mov.w TIME_TICK(r10),r10
clr.w 0(r10) ;清0此任務(wù)的時鐘嘀嗒數(shù)
mov.w 6(sp),r10
mov.w STACK_POINT(r10),r10
mov.w r11,0(r10)
sub.w #CORRENT_DATA_LENGTH+4,0(r10) ;堆棧指針
inc.w Free_Count
pop.w r11
pop.w r10
ret
;------------------------------------------------
OS_Start
;多任務(wù)動函數(shù)
;功能:初始化定時器TimeA0、空閑任務(wù),啟動最高優(yōu)先級的任務(wù)。
;參數(shù):無
;反值:無
;本函數(shù)有14行代碼
;------------------------------------------------
bis.w #(TASSEL1+TACLR+MC_1),&TACTL
mov.w 2(sp),&CCR0
bis.w #CCIE,&CCTL0 ;初始化TimerA0
mov.w #OS_Free_Task,2(sp)
mov.w sr,0(sp)
bis.w #GIE,0(sp)
decd.w sp
mov.w sp,free_task_stack_point
clr.w free_task_time_tick ;初始化空閑任務(wù)
cmp.w #Task_Count,Free_Count
jnz ERROR_USER_PROGRAM ;任務(wù)個數(shù)是否夠,如果不夠就死機或不斷復(fù)位
clr.w Free_Count
clr.w r10
jmp OS_Sched_jmp02
;------------------------------------------------
PUBLIC
OS_Init
;功能:初始多任務(wù)數(shù)據(jù)
;調(diào)用方法:call #OS_Init
;本函數(shù)共有4行代碼
;------------------------------------------------
clr.w Current_Task
clr.w Task_Flag
clr.w Free_Count
ret
;------------------------------------------------
PUBLIC
OS_Time_Dly
;功能:多任務(wù)延時,延時單位是時鐘滴嗒數(shù)
;調(diào)用方法:
;push.w #延時時間
;call #OS_Time_Dly
;incd.w sp
;本函數(shù)共有7行代碼
;------------------------------------------------
push.w SR ;模擬中斷發(fā)生
dint
push.w r10
mov.w Current_Task,r10
mov.w 6(sp),Task_Tick(r10) ;把任務(wù)延時的滴嗒數(shù)存入
bic.w #OS_TASK_LOCK,Task_Flag ;解開任務(wù)鎖
br #OS_Sched_endfor01
;------------------------------------------------
PUBLIC
OS_Sched
;功能:任務(wù)調(diào)度
;本函數(shù)共有51行代碼
;------------------------------------------------
push.w r10
#ifndef debug
mov.w #WDTPW+WDTCNTCL,&WDTCTL ;如果程序是編譯的不是debug版本,清看門狗
#endif
clr.w r10
OS_Sched_for01
cmp.w #Task_Count*2-1,r10
jge OS_Sched_endfor01
tst.w Task_Tick(r10)
jz OS_Sched_jmp01 ;如果時鐘滴嗒數(shù)為0,則不對其進行減1
dec.w Task_Tick(r10) ;對時鐘滴嗒數(shù)進行減1
OS_Sched_jmp01
incd.w r10
jmp OS_Sched_for01
OS_Sched_endfor01
bit.w #OS_TASK_LOCK,Task_Flag ;檢查任務(wù)鎖是否加上
jnz OS_Sched_exit ;如果任務(wù)鎖被加上,則不進行調(diào)度
clr.w r10
OS_Sched_for02
cmp.w #Task_Count*2-1,r10
jge OS_Sched_jmp06
tst.w Task_Tick(r10) ;檢查是否有任務(wù)就緒
jz OS_Sched_Task_Switch ;有,則跳轉(zhuǎn)到任務(wù)切換
incd.w r10
jmp OS_Sched_for02
OS_Sched_jmp06
tst.w free_task_time_tick
jnz ERROR_USER_PROGRAM
OS_Sched_Task_Switch
cmp.w Current_Task,r10 ;比較就緒任務(wù)是不是當前運行的任務(wù)
jz OS_Sched_exit ;如果是,轉(zhuǎn)向下一處
cmp.w #Task_Count*2,Current_Task
jz OS_Sched_jmp03
push.w r11
push.w r12
push.w r13
push.w r14
push.w r15 ;保存現(xiàn)場
mov.w Current_Task,r11 ;保存當前任務(wù)指針
mov.w sp,Task_SP(r11) ;保存當前任務(wù)堆棧指針
OS_Sched_jmp02
mov.w r10,Current_Task ;就緒任務(wù)指針保存為當前任務(wù)指針
cmp.w #Task_Count*2,r10
jz OS_Sched_jmp05
OS_Sched_jmp04
mov.w Task_SP(r10),sp ;堆棧切換
pop.w r15
pop.w r14
pop.w r13
pop.w r12
pop.w r11
OS_Sched_exit
pop.w r10 ;恢復(fù)就緒任務(wù)現(xiàn)場
reti
;如果用戶程序出錯,則把所有中斷關(guān)閉,然后死的此處。此段代碼只是調(diào)試時用。
;如果在產(chǎn)品投入應(yīng)用中,請把此段代碼改為單片機的復(fù)位代碼。
ERROR_USER_PROGRAM
#ifdef debug
dint
jmp ERROR_USER_PROGRAM
#else
br 0fffeh ;CPU復(fù)位
#endif
OS_Sched_jmp03
mov.w r10,Current_Task ;就緒任務(wù)指針保存為當前任務(wù)指針
mov.w sp,free_task_stack_point ;保存當前任務(wù)堆棧指針
jmp OS_Sched_jmp04
OS_Sched_jmp05
mov.w free_task_stack_point,sp
jmp OS_Sched_exit
;------------------------------------------------
PUBLIC
OS_Free_Task
;空閑任務(wù)
;功能:進行CPU空閑計數(shù)
;本函數(shù)共有3行代碼
;------------------------------------------------
OS_Free_Task_jmp01
inc.w Free_Count ;空閑計數(shù)累加
bis.w #OS_FREE_FLAG,Task_Flag ;置上空閑任務(wù)標志
jmp OS_Free_Task_jmp01
;------------------------------------------------
PUBLIC
OS_Task_Lock
;禁止任務(wù)調(diào)度
;本函數(shù)共2行代碼
;------------------------------------------------
bis.w #OS_TASK_LOCK,Task_Flag
ret
;------------------------------------------------
PUBLIC
OS_Task_Unlock
;允許任務(wù)調(diào)度
;本函數(shù)共2行代碼
;------------------------------------------------
bic.w #OS_TASK_LOCK,Task_Flag
ret
;------------------------------------------------
PUBLIC
OS_Task_Wakeup
;功能:喚醒指定優(yōu)先級的任務(wù)
;本函數(shù)共有7行代碼
;push.w #PRI
;call #OS_Task_Wakeup
;incd.w sp
;------------------------------------------------
push.w SR ;模擬中斷發(fā)生
dint
OS_Task_Wakeup_I
push.w r10
mov.w 6(sp),r10
add.w r10,r10
clr.w Task_Tick(r10)
br #OS_Sched_endfor01
RSEG IDATA0
Current_Task: ds 2
Task_Flag: ds 2
Free_Count: ds 2
free_task_stack_point:
ds 2
free_task_time_tick:
ds 2
RSEG CDATA0
dw 0
dw 0
dw 0
dw 0
dw 0
COMMON INTVEC
ds TIMERA0_VECTOR ;時鐘中斷向量
dw OS_Sched
end
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -