📄 rtos.s43
字号:
;========================================================================================
;
; 实时多任务操作系统源代码
;
; M430/OS V1.10
;
;
; 文件名:RTOS.S43
;
; 作 者:刘兵 public_rtos@163.com 2002年11月27日
;
;----------------------------------------------------------------------------------------
;
; 注 释:
;
; 本操作系统用的是抢占先式内核,如果一个优先级比较低的任务正在运行,另一个优先级高的
; 任务就绪时,系统就把优先级低的任务的现场保存,再切到优先级高的任务运行;优先级高的
; 任务运行完之后,再切到优先级低的任务的断点处继续执行。
;
;----------------------------------------------------------------------------------------
;
; 每个任务必须是以下结构:
;
; /--------------\
; ( 开 始 )
; \--------------/
; |
; V
; |----------------------|
; | 任务本身数据初始化 |
; |----------------------|
; |
; |<-------------------------\
; | |
; V |
; |------------------| |
; | 任务执行代码 | |
; |------------------| |
; | |
; V |
; |----------------------------------------| |
; | 调用OS_Time_Dly进行延时,这时系统会 | |
; | 把延时的这段时间切到其它任务来运行 | |
; |----------------------------------------| |
; | |
; \--------------------------/
;
;
; 每个任务都是一个无限循环,只有开始,没有结束。
;
;----------------------------------------------------------------------------------------
;
; 本操作系统包括7个函数(共86行可执行代码):
;
; 1. OS_Init
; 功能:初始化多任务环境,然后直接切到优先级最高的任务。
;
; 2. OS_Sched
; 功能:进行任务调度、任务切换。
;
; 3. OS_Time_Dly
; 功能:任务延时函数。
;
; 4. OS_Free_Task
; 功能:空闲任务。
;
; 5. OS_Task_Lock
; 功能:禁止任务调度。
;
; 6. OS_Task_Unlock
; 功能:允许任务调度。
;
; 7. OS_Task_Wakeup
; 功能:唤醒指定优先级的任务
;
;========================================================================================
NAME RTOS(16)
#include <msp430x14x.h>
#include "include.h"
Task_Count DEFINE 06h ;任务数目
Task_Data_Count DEFINE 06h ;每个任务要保存的现场数目(单位:字)
FREE_STACK_SIZE DEFINE (Task_Data_Count+02h)
SOFTCLOCK_STACK_SIZE DEFINE 10h ;软时钟任务的堆栈大小(单位:字)
TASK1_STACK_SIZE DEFINE 11h ;任务1的堆栈大小(单位:字)
TASK2_STACK_SIZE DEFINE 12h ;任务2的堆栈大小(单位:字)
TASK3_STACK_SIZE DEFINE 13h ;任务3的堆栈大小(单位:字)
TASK4_STACK_SIZE DEFINE 14h ;任务4的堆栈大小(单位:字)
LED_STACK_SIZE DEFINE FREE_STACK_SIZE+2 ;LED指示灯的堆栈大小(单位:字)
#include "rtos.h"
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
EXTERN softclock
EXTERN task1
EXTERN task2
EXTERN task3
EXTERN task4
EXTERN taskled
ORG (0a00h - (SYSTEM_RAM_SIZE + TASK_STACK_SIZE))
Current_Task DW 0000h ;当前运行的任务的指针
Task_Flag DW 0000h ;任务状态(是否允许调度、是否允许计数等)
Free_Count DW 0000h ;空闲任务计数
Task_SP DS (Task_Count*2+2) ;每个任务的堆栈SP指针位置
Task_Tick DS (Task_Count*2+2) ;每个任务的延时计数
DS (TASK_STACK_SIZE) ;任务栈
ORG 0ffech
dw OS_Sched
ORG 3000h
;------------------------------------------------
PUBLIC
OS_Init
;功能:初始多任务数据、环境、任务栈,并启动最高优先级的任务
;调用方法:call #OS_Init,多任务就启动开了
;本函数共有26行代码
;------------------------------------------------
clr.w Current_Task
clr.w Task_Flag
clr.w Free_Count
bis.w #(TASSEL1+TACLR+MC_1),&TACTL
mov.w 2(sp),&CCR0
bis.w #CCIE,&CCTL0
eint
mov.w SR,r13
dint
mov.w #09feh,r11
mov.w #OS_Task_Table,r12
clr.w r10
OS_Init_for01
cmp.w #(Task_Count*2+2),r10
jz OS_Init_endfor01
clr.w Task_Tick(r10) ;清0时钟滴嗒数
mov.w 0(r12),0(r11) ;把任务地址压入堆栈
mov.w r13,-2(r11) ;把标志寄存器放入任务栈
mov.w r11,Task_SP(r10)
sub.w #(Task_Data_Count*2+2),Task_SP(r10) ;SP位置放入堆栈
sub.w Stack_Size_Table(r10),r11 ;指向下一个任务
incd.w r12
incd.w r10
jmp OS_Init_for01
OS_Init_endfor01
clr.w Task_Flag
clr.w Current_Task
clr.w Free_Count
mov.w #09feh,sp
eint
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
;功能:任务调度
;本函数共有39行代码
;------------------------------------------------
push.w r10
#ifndef debug
mov.w #WDTPW+WDTCNTCL,&WDTCTL
#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+3),r10
jge ERROR_USER_PROGRAM
tst.w Task_Tick(r10) ;检查是否有任务就绪
jz OS_Sched_Task_Switch ;有,则跳转到任务切换
incd.w r10
jmp OS_Sched_for02
OS_Sched_Task_Switch
cmp.w Current_Task,r10 ;比较就绪任务是不是当前运行的任务
jz OS_Sched_exit ;如果是,转向下一处
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) ;保存当前任务堆栈指针
mov.w r10,Current_Task ;就绪任务指针保存为当前任务指针
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
;------------------------------------------------
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
Stack_Size_Table: ;每个任务栈的大小
DW (SOFTCLOCK_STACK_SIZE*2)
DW (TASK1_STACK_SIZE*2)
DW (TASK2_STACK_SIZE*2)
DW (TASK3_STACK_SIZE*2)
DW (TASK4_STACK_SIZE*2)
DW (LED_STACK_SIZE*2)
DW (FREE_STACK_SIZE*2)
OS_Task_Table:
DW softclock ;软时钟任务
DW task1 ;任务1
DW task2 ;任务2
DW task3 ;任务3
DW task4 ;任务4
DW taskled ;指示灯任务
DW OS_Free_Task ;空闲任务
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -