📄 rtos.s43
字号:
;========================================================================================
;
; 实时多任务操作系统源代码
;
; M430/OS V1.20
;
;
; 文件名:RTOS.S43
;
; 作 者:刘兵 public_rtos@163.com 2002年11月27日
;
;----------------------------------------------------------------------------------------
;
; 注 释:
;
; 本操作系统用的是抢占先式内核,如果一个优先级比较低的任务正在运行,另一个优先级高的
; 任务就绪时,系统就把优先级低的任务的现场保存,再切到优先级高的任务运行;优先级高的
; 任务运行完之后,再切到优先级低的任务的断点处继续执行。
;
;----------------------------------------------------------------------------------------
;
; 每个任务必须是以下结构:
;
; /--------------\
; ( 开 始 )
; \--------------/
; |
; V
; |----------------------|
; | 任务本身数据初始化 |
; |----------------------|
; |
; |<-------------------------\
; | |
; V |
; |------------------| |
; | 任务执行代码 | |
; |------------------| |
; | |
; V |
; |----------------------------------------| |
; | 调用OS_Time_Dly进行延时,这时系统会 | |
; | 把延时的这段时间切到其它任务来运行 | |
; |----------------------------------------| |
; | |
; \--------------------------/
;
;
; 每个任务都是一个无限循环,只有开始,没有结束。
;
;----------------------------------------------------------------------------------------
;
; 本操作系统包括9个函数:
;
; 1. OS_Init
; 功能:初始化M430/OS的系统数据。
;
; 2. OS_Create
; 功能:建立任务。
;
; 3. OS_Start
; 功能:启动M430/OS。
;
; 4. OS_Sched
; 功能:进行任务调度、任务切换。
;
; 5. OS_Time_Dly
; 功能:任务延时函数。
;
; 6. OS_Free_Task
; 功能:空闲任务。
;
; 7. OS_Task_Lock
; 功能:禁止任务调度。
;
; 8. OS_Task_Unlock
; 功能:允许任务调度。
;
; 9. OS_Task_Wakeup
; 功能:唤醒指定优先级的任务
;
;
;
;========================================================================================
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 ;现场数据长度
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
;功能:建立新任务。
;参数:任务TCB结构:
; unsigned int *task_base; //任务入口
; unsigned int *stack_base; //任务堆栈基址
; unsigned int *stack_point; //任务堆栈指针的位置
; unsigned int *time_tick; //任务时钟嘀嗒数的位置
; unsigned int stack_size; //堆栈大小
;调用方式:
; push.w #Task_TCB
; call #OS_Task_Create
; incd.w sp
;
;任务堆栈示意图
;
; ^ | |
; | |-----------| //栈顶(低地址)
; | | . |
; | | . |
; | | 栈区 |
; | | . |
; | | . |
; | |-----------| //堆栈指针
; | | . |
; | | . |
; | | 现场数据 |
; | | . |
; | | . |
; | |-----------|
; | |标志寄存器 |
; | |-----------|
; | | 断点 |
; | ------------- //栈底(高地址)
;
;
;本函数共有18行代码
;------------------------------------------------
push.w r10
push.w r11
mov.w 6(sp),r10 ;取出结构指针
mov.w STACK_BASE(r10),r11 ;取出结构指针指向的堆栈基址(栈顶)
add.w STACK_SIZE(r10),r11 ;找到栈底
mov.w TASK_BASE(r10),-2(r11) ;任务首地址做为断点放入栈底
mov.w sr,-4(r11)
bis.w #GIE,-4(r11) ;标志寄存器放入栈底
mov.w TIME_TICK(r10),r10
clr.w 0(r10) ;清0此任务的时钟嘀嗒数
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
;多任务动函数
;功能:初始化定时器TimeA0、空闲任务,启动最高优先级的任务。
;参数:无
;反值:无
;本函数有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 ;初始化空闲任务
cmp.w #Task_Count,Free_Count
jnz ERROR_USER_PROGRAM ;任务个数是否够,如果不够就死机或不断复位
clr.w Free_Count
clr.w r10
jmp OS_Sched_jmp02
;------------------------------------------------
PUBLIC
OS_Init
;功能:初始多任务数据
;调用方法:call #OS_Init
;本函数共有4行代码
;------------------------------------------------
clr.w Current_Task
clr.w Task_Flag
clr.w Free_Count
ret
;------------------------------------------------
PUBLIC
OS_Time_Dly
;功能:多任务延时,延时单位是时钟滴嗒数
;调用方法:
;push.w #延时时间
;call #OS_Time_Dly
;incd.w sp
;本函数共有7行代码
;------------------------------------------------
push.w SR ;模拟中断发生
dint
push.w r10
mov.w Current_Task,r10
mov.w 6(sp),Task_Tick(r10) ;把任务延时的滴嗒数存入
bic.w #OS_TASK_LOCK,Task_Flag ;解开任务锁
br #OS_Sched_endfor01
;------------------------------------------------
PUBLIC
OS_Sched
;功能:任务调度
;本函数共有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 ;如果时钟滴嗒数为0,则不对其进行减1
dec.w Task_Tick(r10) ;对时钟滴嗒数进行减1
OS_Sched_jmp01
incd.w r10
jmp OS_Sched_for01
OS_Sched_endfor01
bit.w #OS_TASK_LOCK,Task_Flag ;检查任务锁是否加上
jnz OS_Sched_exit ;如果任务锁被加上,则不进行调度
clr.w r10
OS_Sched_for02
cmp.w #Task_Count*2-1,r10
jge OS_Sched_jmp06
tst.w Task_Tick(r10) ;检查是否有任务就绪
jz OS_Sched_Task_Switch ;有,则跳转到任务切换
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 ;比较就绪任务是不是当前运行的任务
jz OS_Sched_exit ;如果是,转向下一处
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 ;保存现场
mov.w Current_Task,r11 ;保存当前任务指针
mov.w sp,Task_SP(r11) ;保存当前任务堆栈指针
OS_Sched_jmp02
mov.w r10,Current_Task ;就绪任务指针保存为当前任务指针
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 ;恢复就绪任务现场
reti
;如果用户程序出错,则把所有中断关闭,然后死的此处。此段代码只是调试时用。
;如果在产品投入应用中,请把此段代码改为单片机的复位代码。
ERROR_USER_PROGRAM
#ifdef debug
dint
jmp ERROR_USER_PROGRAM
#else
br 0fffeh ;CPU复位
#endif
OS_Sched_jmp03
mov.w r10,Current_Task ;就绪任务指针保存为当前任务指针
mov.w sp,free_task_stack_point ;保存当前任务堆栈指针
jmp OS_Sched_jmp04
OS_Sched_jmp05
mov.w free_task_stack_point,sp
jmp OS_Sched_exit
;------------------------------------------------
PUBLIC
OS_Free_Task
;空闲任务
;功能:进行CPU空闲计数
;本函数共有3行代码
;------------------------------------------------
OS_Free_Task_jmp01
inc.w Free_Count ;空闲计数累加
bis.w #OS_FREE_FLAG,Task_Flag ;置上空闲任务标志
jmp OS_Free_Task_jmp01
;------------------------------------------------
PUBLIC
OS_Task_Lock
;禁止任务调度
;本函数共2行代码
;------------------------------------------------
bis.w #OS_TASK_LOCK,Task_Flag
ret
;------------------------------------------------
PUBLIC
OS_Task_Unlock
;允许任务调度
;本函数共2行代码
;------------------------------------------------
bic.w #OS_TASK_LOCK,Task_Flag
ret
;------------------------------------------------
PUBLIC
OS_Task_Wakeup
;功能:唤醒指定优先级的任务
;本函数共有7行代码
;push.w #PRI
;call #OS_Task_Wakeup
;incd.w sp
;------------------------------------------------
push.w SR ;模拟中断发生
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -