帮助看看这个RTOS 是什么原理?

小黄人软件
博客专家认证
2012-12-25 08:53:39
;********************************************
;RTOS 用定时器0的多任务处理程序
;项目增加方式使用。
;程序不影响其它数据,目前程序的前后段不能进行参数传递 。 最多可以同时运行8个任务,
;执行时使用定时器0,定时时间根据初始化时的参数确定,一般为10mS。
;当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。
;占用24H个内存单元。
;如果程序不可再入,需要设定 RWZT 的标志位。调用前先检查相应位。
;如果定时数设置过大,会引起一直在中断中,不能执行外部程序。如果任务执行时间过长,会引起堆栈溢出。
;18.432MHz,单时钟周期模式。不用任务单取反,输出频率 1.3MHz ,指令周期 384 nS 。速度是带系统的 100 倍。
;8个任务,只对管脚取反,T0=FEF0H,输出 2.8K 频率,为最高频率。执行周期不受任务影响。18.432MHz,单时钟周期模式。
;1个任务,只对管脚取反,T0=FFE1H,输出 12K 频率,为最高频率。执行周期受任务影响。每次调度时间为42US。
;*********************************************
;------------------------------------------------------------- 示例程序
;extern RTOS(unsigned char priority,time,unsigned int *add);
;extern RTOS_INI(unsigned int count);
;extern RTOS();
;sbit P1_0=P1^0;
;void deng(void)
;{
; P1_0=!P1_0;
; JMP(0,100,deng);
;}
; main()
;{
; JMP(0,100,deng);
; while(1)
; {
; RTOS();
; }
;}
;***********************************************
NAME RTOS_C ;程序段名
?PR?RTOS?RTOS_C SEGMENT CODE
?DT?RTOS?RTOS_C SEGMENT DATA
?ID?RTOS?RTOS_C SEGMENT IDATA

PUBLIC RTOS
PUBLIC _RTOS_WAIT
PUBLIC _RTOS_INIT
;---------------------------------------------
;BANBH EQU 0A3H ;版本号 101221
;定义数据地址
;----------------------------------------------
RSEG ?DT?RTOS?RTOS_C
;RWZT EQU 29H ;任务状态,0为停止,1为正在执行
TL: DS 1 ;EQU 30H ;RTOS定时器值,C=FFFFH-ft
TH: DS 1 ;EQU 31H ;18.432MHz(12周期)=C400H
RWB: DS 1 ;EQU 33H ;任务表


RSEG ?ID?RTOS?RTOS_C
RWDZ: DS 16 ;任务堆栈
; EQU 80H ;任务地址
; EQU 8FH
RWS: DS 8 ;任务数
; EQU 90H ;任务定时数
; EQU 97H
;*********************************************
CSEG AT 0BH ;TO入口
JMP RTOS
;*********************************************
RSEG ?PR?RTOS?RTOS_C

_RTOS_INIT: ;任务初始化
;-------------------------------------------- 在 R6 R7 中,设置定时值
;RTOS定时器值,C=FFFFH-ft,18.432MHz(12周期)=C400H,40MHz(12周期)=7DC9H
;定时器0定时程序,18.432MHz,10MS,方式1
ORL TMOD,#01H ;定时10MS ;定时器0初始化,设置TMOD
MOV TL0,R7
MOV TL,R7 ;设置TL
MOV TH0,R6
MOV TH,R6 ;设置TH
MOV RWB,#0 ;任务表清0
SETB TR0 ;启动定时器
SETB ET0 ;打开中断
SETB EA ;打开总中断
RET ;等待中断
;********************************************** 等待函数,优先级为最低 0 级,等待时间放入 R7 中
; 目前函数不能传递参数
_RTOS_WAIT: MOV A,R7 ;接收参数
MOV R5,A ;接收的数存在R5
MOV R7,#0 ;R7清零
CALL YXJSZ ;??计数值?
CJNE R7,#8,RWSZ ;R7如果不等 于8,则任务设置
MOV R7,#0FFH ;返回值0xff
RET ;返回
;---------------------------------------------
RWSZ: MOV A,R7 ;送任务数
ADD A,#RWS
MOV R0,A
MOV A,R5
MOV @R0,A

MOV A,R7 ;送地址
RL A
ADD A,#RWDZ
MOV R0,A
POP ACC ;跳转地址,在堆栈中
POP B
MOV @R0,B ;低地址在低字节
INC R0
MOV @R0,A

MOV B,R7 ;设置任务列表
CLR A ; 当前正在执行的程序如果被中断,并且中断中使用了此任务位,则此次任务将会丢失。
INC B ;可以关中断来解决此问题。
SETB C
RWSZ2: RLC A
DJNZ B,RWSZ2
ORL RWB,A
RET
;--------------------------
YXJSZ: MOV B,R7 ;0
INC B ;B++ 1
MOV A,RWB ;0
CLR C ;0
YXJ2: RRC A ;RRC是带进位的循环右移指令
DJNZ B,YXJ2 ;如果B不等于0, b=0
YXJ4: JNC YXJ3 ;C=0 ,则
RRC A ;
INC R7 ;
JMP YXJ4 ;
YXJ3: RET ;返回

;------------------------------- 中断程序
RTOS: MOV TH0,TH
MOV TL0,TL
JB PSW.3,RTOS1
JB PSW.4,RTOS2
PUSH 0
PUSH 1
PUSH 2
PUSH 3
PUSH 4
PUSH 5
PUSH 6
PUSH 7
JMP RTOS0
RTOS1: JB PSW.4,RTOS3
PUSH 8
PUSH 9
PUSH 10
PUSH 11
PUSH 12
PUSH 13
PUSH 14
PUSH 15
JMP RTOS0
RTOS2:
PUSH 10H
PUSH 11H
PUSH 12H
PUSH 13H
PUSH 14H
PUSH 15H
PUSH 16H
PUSH 17H
JMP RTOS0
RTOS3: PUSH 18H
PUSH 19H
PUSH 1AH
PUSH 1BH
PUSH 1CH
PUSH 1DH
PUSH 1EH
PUSH 1FH

RTOS0: PUSH PSW
PUSH ACC
PUSH B
PUSH DPL
PUSH DPH
CALL RWDD0
POP DPH
POP DPL
POP B
POP ACC
POP PSW
JB PSW.3,RTOS01
JB PSW.4,RTOS02
POP 7
POP 6
POP 5
POP 4
POP 3
POP 2
POP 1
POP 0
RETI
RTOS01: JB PSW.4,RTOS3
POP 15
POP 14
POP 13
POP 12
POP 11
POP 10
POP 9
POP 8
RETI
RTOS02:
POP 17H
POP 16H
POP 15H
POP 14H
POP 13H
POP 12H
POP 11H
POP 10H
RETI
RTOS03: POP 1FH
POP 1EH
POP 1DH
POP 1CH
POP 1BH
POP 1AH
POP 19H
POP 18H
RETI
;----------------------------- 中断任务调度
RWDD0: MOV B,#7 ;任务号
MOV R0,#RWS+7
MOV R1,#0FFH ;执行任务号
MOV A,RWB
JNZ RWDD3
RET
RWDD3: CLR C
RLC A
JNC RWDD6
CJNE @R0,#0,RWDD2
RWDD4: CJNE R1,#0FFH,RWDD6
MOV R1,B
RWDD6: DEC R0
DEC B
JNZ RWDD3
CJNE R1,#0FFH,RWCL
RET
RWDD2: DEC @R0
CJNE @R0,#0,RWDD6
JMP RWDD4
;---------------------------------
RWDD: MOV R1,#7
MOV R0,#RWS+7
MOV A,RWB
JNZ RWDD03
RET
RWDD03: CLR C
RLC A
JNC RWDD06
CJNE @R0,#0,RWDD06
JMP RWCL
RWDD06: DEC R0
DEC R1
JNZ RWDD03
RET
;--------------------------------------
RWCL: MOV DPTR,#RWDD ;任务处理?
PUSH DPL
PUSH DPH
MOV A,R1
RL A
ADD A,#RWDZ
MOV R0,A
MOV A,@R0
PUSH ACC ;低地址在低字节
INC R0
MOV ACC,@R0
PUSH ACC

MOV A,#0FFH ;清除任务列表 当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,
INC R1 ;可以加入一个执行标志 RWZT 来解决此问题。
CLR C
RWCL22: RLC A
DJNZ R1,RWCL22
ANL RWB,A
RETI
;***********************************
END
...全文
1009 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
小黄人软件 2013-12-27
  • 打赏
  • 举报
回复
[code=Assembler][/code] ;******************************************** ;RTOS 用定时器0的多任务处理程序 ;项目增加方式使用。 ;程序不影响其它数据,目前程序的前后段不能进行参数传递 。 最多可以同时运行8个任务, ;执行时使用定时器0,定时时间根据初始化时的参数确定,一般为10mS。 ;当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。 ;占用24H个内存单元。 ;如果程序不可再入,需要设定 RWZT 的标志位。调用前先检查相应位。 ;如果定时数设置过大,会引起一直在中断中,不能执行外部程序。如果任务执行时间过长,会引起堆栈溢出。 ;18.432MHz,单时钟周期模式。不用任务单取反,输出频率 1.3MHz ,指令周期 384 nS 。速度是带系统的 100 倍。 ;8个任务,只对管脚取反,T0=FEF0H,输出 2.8K 频率,为最高频率。执行周期不受任务影响。18.432MHz,单时钟周期模式。 ;1个任务,只对管脚取反,T0=FFE1H,输出 12K 频率,为最高频率。执行周期受任务影响。每次调度时间为42US。 ;********************************************* ;------------------------------------------------------------- 示例程序 ;*********************************************** NAME RTOS_C ;程序段名 ?PR?RTOS?RTOS_C SEGMENT CODE ;代码段 ; 段名 SEGMENT 段类型 ?DT?RTOS?RTOS_C SEGMENT DATA ?ID?RTOS?RTOS_C SEGMENT IDATA PUBLIC RTOS PUBLIC _RTOS_WAIT PUBLIC _RTOS_INIT ;--------------------------------------------- ;BANBH EQU 0A3H ;版本号 101221 ;定义数据地址 ;---------------------------------------------- RSEG ?DT?RTOS?RTOS_C ;RWZT EQU 29H ;任务状态,0为停止,1为正在执行 TL: DS 1 ;EQU 30H ;RTOS定时器值,C=FFFFH-ft TH: DS 1 ;EQU 31H ;18.432MHz(12周期)=C400H RWB: DS 1 ;EQU 33H ;任务表 RSEG ?ID?RTOS?RTOS_C RWDZ: DS 16 ;任务堆栈 ; EQU 80H ;任务地址 ; EQU 8FH RWS: DS 8 ;任务数 ; EQU 90H ;任务定时数 ; EQU 97H ;********************************************* CSEG AT 0BH ;TO入口 JMP RTOS ;********************************************* RSEG ?PR?RTOS?RTOS_C _RTOS_INIT: ;任务初始化 ;-------------------------------------------- 在 R6 R7 中,设置定时值 ;RTOS定时器值,C=FFFFH-ft,18.432MHz(12周期)=C400H,40MHz(12周期)=7DC9H ;定时器0定时程序,18.432MHz,10MS,方式1 ORL TMOD,#01H ;定时10MS ;定时器0初始化,设置TMOD MOV TL0,R7 MOV TL,R7 ;设置TL MOV TH0,R6 MOV TH,R6 ;设置TH MOV RWB,#0 ;任务表清0 SETB TR0 ;启动定时器 SETB ET0 ;打开中断 SETB EA ;打开总中断 RET ;等待中断 ;********************************************** 等待函数,优先级为最低 0 级,等待时间放入 R7 中 ; 目前函数不能传递参数 _RTOS_WAIT: MOV A,R7 ;接收参数 MOV R5,A ;接收的数存在R5 MOV R7,#0 ;R7清零 CALL YXJSZ ;优先级设置 CJNE R7,#8,RWSZ ;R7如果不等 于8,则任务设置 MOV R7,#0FFH ;返回值0xff 当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。 RET ;返回 ;--------------------------------------------- RWSZ: MOV A,R7 ;送任务数 ADD A,#RWS ; MOV R0,A ;任务数保存到R0 MOV A,R5 ;R5上是什么 定时时间 MOV @R0,A ;保存定时时间数到【R7+RWS】位置 MOV A,R7 ;送 RL A ; ADD A,#RWDZ MOV R0,A POP ACC ;跳转地址,在堆栈中 POP B MOV @R0,B ;低地址在低字节 INC R0 MOV @R0,A MOV B,R7 ;设置任务列表 CLR A ; 当前正在执行的程序如果被中断,并且中断中使用了此任务位,则此次任务将会丢失。 INC B ;可以关中断来解决此问题。 SETB C RWSZ2: RLC A DJNZ B,RWSZ2 ORL RWB,A RET ;-------------------------- YXJSZ: MOV B,R7 ;0 ;优先级设置 INC B ;B++ 1 MOV A,RWB ;0 CLR C ;0 YXJ2: RRC A ;RRC是带进位的循环右移指令 DJNZ B,YXJ2 ;如果B不等于0, b=0 YXJ4: JNC YXJ3 ;C=0 ,则 RRC A ; INC R7 ; JMP YXJ4 ; YXJ3: RET ;返回 ;------------------------------- 中断程序 把所有相关寄存器内容压入堆栈 任务调度完后 再弹出来 RTOS: MOV TH0,TH ;重载定时数 MOV TL0,TL ; JB PSW.3,RTOS1 ;RS0==1 用于选择当前工作寄存器区。8051有8个8位寄存器R0~R7 JB PSW.4,RTOS2 ;RS1==1 PUSH 0 ;RS0=0,RS1=0; 第一组寄存器区 PUSH 1 PUSH 2 PUSH 3 PUSH 4 PUSH 5 PUSH 6 PUSH 7 ;存入椎栈第一组寄存器上的内容 JMP RTOS0 ;都跳到RTOS0 RTOS1: JB PSW.4,RTOS3 ; PUSH 8 ;RS0=1,RS1=0; 第三组寄存器区 PUSH 9 PUSH 10 PUSH 11 PUSH 12 PUSH 13 PUSH 14 PUSH 15 JMP RTOS0 ; RTOS2: PUSH 10H ;RS0=0,RS1=1; 第二组寄存器区 PUSH 11H PUSH 12H PUSH 13H PUSH 14H PUSH 15H PUSH 16H PUSH 17H JMP RTOS0 RTOS3: PUSH 18H ;RS0=1,RS1=1; 第四组寄存器区 PUSH 19H PUSH 1AH PUSH 1BH PUSH 1CH PUSH 1DH PUSH 1EH PUSH 1FH RTOS0: PUSH PSW ;入栈 PUSH ACC ; PUSH B PUSH DPL PUSH DPH CALL RWDD0 ;任务调度 POP DPH ;出栈 POP DPL POP B POP ACC POP PSW JB PSW.3,RTOS01 JB PSW.4,RTOS02 POP 7 POP 6 POP 5 POP 4 POP 3 POP 2 POP 1 POP 0 ;弹出第一组寄存器区上的变量 RETI ;中断返回 RTOS01: JB PSW.4,RTOS3 POP 15 POP 14 POP 13 POP 12 POP 11 POP 10 POP 9 POP 8 RETI RTOS02: POP 17H POP 16H POP 15H POP 14H POP 13H POP 12H POP 11H POP 10H RETI RTOS03: POP 1FH POP 1EH POP 1DH POP 1CH POP 1BH POP 1AH POP 19H POP 18H RETI ;----------------------------- 中断任务调度 RWDD0: MOV B,#7 ;任务号 MOV R0,#RWS+7 ; MOV R1,#0FFH ;执行任务号 MOV A,RWB JNZ RWDD3 RET RWDD3: CLR C RLC A JNC RWDD6 CJNE @R0,#0,RWDD2 RWDD4: CJNE R1,#0FFH,RWDD6 MOV R1,B RWDD6: DEC R0 DEC B JNZ RWDD3 CJNE R1,#0FFH,RWCL RET RWDD2: DEC @R0 CJNE @R0,#0,RWDD6 JMP RWDD4 ;--------------------------------- RWDD: MOV R1,#7 MOV R0,#RWS+7 MOV A,RWB JNZ RWDD03 RET RWDD03: CLR C RLC A JNC RWDD06 CJNE @R0,#0,RWDD06 JMP RWCL RWDD06: DEC R0 DEC R1 JNZ RWDD03 RET ;-------------------------------------- RWCL: MOV DPTR,#RWDD ;任务处理? PUSH DPL PUSH DPH MOV A,R1 RL A ADD A,#RWDZ MOV R0,A MOV A,@R0 PUSH ACC ;低地址在低字节 INC R0 MOV ACC,@R0 PUSH ACC MOV A,#0FFH ;清除任务列表 当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级, INC R1 ;可以加入一个执行标志 RWZT 来解决此问题。 CLR C RWCL22: RLC A DJNZ R1,RWCL22 ANL RWB,A RETI ;*********************************** END
小黄人软件 2013-01-04
  • 打赏
  • 举报
回复
我准备实时仿真一下。
zhujinqiang 2013-01-04
  • 打赏
  • 举报
回复
引用 23 楼 chenhao0568 的回复:
我准备实时仿真一下。
++ 等有结果了来说说哦
小黄人软件 2012-12-31
  • 打赏
  • 举报
回复
;********************************************
;RTOS		用定时器0的多任务处理程序
;项目增加方式使用。
;程序不影响其它数据,目前程序的前后段不能进行参数传递 。 最多可以同时运行8个任务,
;执行时使用定时器0,定时时间根据初始化时的参数确定,一般为10mS。
;当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。
;占用24H个内存单元。
;如果程序不可再入,需要设定 RWZT 的标志位。调用前先检查相应位。
;如果定时数设置过大,会引起一直在中断中,不能执行外部程序。如果任务执行时间过长,会引起堆栈溢出。
;18.432MHz,单时钟周期模式。不用任务单取反,输出频率 1.3MHz ,指令周期 384 nS 。速度是带系统的 100 倍。
;8个任务,只对管脚取反,T0=FEF0H,输出 2.8K 频率,为最高频率。执行周期不受任务影响。18.432MHz,单时钟周期模式。
;1个任务,只对管脚取反,T0=FFE1H,输出 12K 频率,为最高频率。执行周期受任务影响。每次调度时间为42US。
;*********************************************
;-------------------------------------------------------------	示例程序

;***********************************************
	NAME	RTOS_C    ;程序段名
	?PR?RTOS?RTOS_C		SEGMENT	CODE  
	?DT?RTOS?RTOS_C		SEGMENT DATA
	?ID?RTOS?RTOS_C		SEGMENT IDATA
	
	PUBLIC	RTOS
	PUBLIC	_RTOS_WAIT
	PUBLIC	_RTOS_INIT
;---------------------------------------------
;BANBH	EQU	0A3H	;版本号 101221
;定义数据地址
;----------------------------------------------
RSEG	?DT?RTOS?RTOS_C
;RWZT		EQU	29H	;任务状态,0为停止,1为正在执行
TL:	DS 1	;EQU	30H	;RTOS定时器值,C=FFFFH-ft
TH:	DS 1	;EQU	31H	;18.432MHz(12周期)=C400H
RWB:	DS 1	;EQU	33H	;任务表


RSEG	?ID?RTOS?RTOS_C
RWDZ:	DS 16	        ;任务堆栈
;	EQU	80H	;任务地址
;	EQU	8FH
RWS:	DS 8		;任务数
;	EQU	90H	;任务定时数
;	EQU	97H
;*********************************************
        CSEG  AT   0BH         ;TO入口
        JMP     RTOS	
;*********************************************
RSEG	?PR?RTOS?RTOS_C

_RTOS_INIT:			;任务初始化
;-------------------------------------------- 在 R6 R7 中,设置定时值
;RTOS定时器值,C=FFFFH-ft,18.432MHz(12周期)=C400H,40MHz(12周期)=7DC9H
;定时器0定时程序,18.432MHz,10MS,方式1
	  ORL    TMOD,#01H   ;定时10MS  ;定时器0初始化,设置TMOD
          MOV    TL0,R7
          MOV	 TL,R7	     ;设置TL
          MOV    TH0,R6
          MOV	 TH,R6       ;设置TH
          MOV	 RWB,#0	     ;任务表清0
          SETB   TR0   	     ;启动定时器
          SETB   ET0	     ;打开中断
          SETB   EA	     ;打开总中断
          RET                ;等待中断
;********************************************** 等待函数,优先级为最低 0 级,等待时间放入 R7 中
;	目前函数不能传递参数
_RTOS_WAIT:	MOV	A,R7 	;接收参数
	MOV	R5,A		;接收的数存在R5
	MOV	R7,#0		;R7清零
	CALL	YXJSZ		;??计数值?
	CJNE	R7,#8,RWSZ	;R7如果不等 于8,则任务设置
	MOV	R7,#0FFH	;返回值0xff
	RET			;返回
;---------------------------------------------	
RWSZ:	MOV	A,R7		;送任务数
	ADD	A,#RWS		;
	MOV	R0,A		;任务数保存到R0
	MOV	A,R5		;R5上是什么
	MOV	@R0,A   	;
	
	MOV	A,R7		;送地址
	RL	A		;
	ADD	A,#RWDZ
	MOV	R0,A
	POP	ACC		;跳转地址,在堆栈中
	POP	B
	MOV	@R0,B		;低地址在低字节
	INC	R0
	MOV	@R0,A
	
	MOV	B,R7		;设置任务列表 
	CLR	A		; 当前正在执行的程序如果被中断,并且中断中使用了此任务位,则此次任务将会丢失。
	INC	B		;可以关中断来解决此问题。
	SETB	C
RWSZ2:	RLC	A
	DJNZ	B,RWSZ2
	ORL	RWB,A
	RET
;--------------------------
YXJSZ:	MOV	B,R7	;0
	INC	B	;B++ 1
	MOV	A,RWB	;0
	CLR	C	;0
YXJ2:	RRC	A	;RRC是带进位的循环右移指令
	DJNZ	B,YXJ2 	;如果B不等于0,  b=0
YXJ4:	JNC	YXJ3	;C=0 ,则 
	RRC	A	;
	INC	R7	;
	JMP	YXJ4    ;
YXJ3:	RET 		;返回 

;------------------------------- 中断程序   把所有相关寄存器内容压入堆栈  任务调度完后 再弹出来
RTOS:	MOV    TH0,TH		;重载定时数
	MOV    TL0,TL		;
	JB	PSW.3,RTOS1	;RS0==1 用于选择当前工作寄存器区。8051有8个8位寄存器R0~R7
	JB	PSW.4,RTOS2	;RS1==1 
	PUSH	0		;RS0=0,RS1=0;  第一组寄存器区
	PUSH	1
	PUSH	2
	PUSH	3
	PUSH	4
	PUSH	5
	PUSH	6
	PUSH	7		;存入椎栈第一组寄存器上的内容
	JMP	RTOS0		;都跳到RTOS0
RTOS1:	JB	PSW.4,RTOS3	;
	PUSH	8		;RS0=1,RS1=0;  第三组寄存器区
	PUSH	9
	PUSH	10
	PUSH	11
	PUSH	12
	PUSH	13
	PUSH	14
	PUSH	15
	JMP	RTOS0		;
RTOS2:	
	PUSH	10H		;RS0=0,RS1=1;  	第二组寄存器区
	PUSH	11H
	PUSH	12H
	PUSH	13H
	PUSH	14H
	PUSH	15H
	PUSH	16H
	PUSH	17H
	JMP	RTOS0
RTOS3:	PUSH	18H		;RS0=1,RS1=1;	第四组寄存器区
	PUSH	19H
	PUSH	1AH
	PUSH	1BH
	PUSH	1CH
	PUSH	1DH
	PUSH	1EH
	PUSH	1FH

RTOS0:	PUSH	PSW 		;入栈
	PUSH	ACC		;
	PUSH	B
	PUSH	DPL
	PUSH	DPH
	CALL	RWDD0		;任务调度
	POP	DPH		;出栈
	POP	DPL
	POP	B		
	POP	ACC
	POP	PSW
	JB	PSW.3,RTOS01
	JB	PSW.4,RTOS02
	POP	7
	POP	6
	POP	5
	POP	4
	POP	3
	POP	2
	POP	1
	POP	0		;弹出第一组寄存器区上的变量
	RETI			;中断返回
RTOS01:	JB	PSW.4,RTOS3
	POP	15
	POP	14
	POP	13
	POP	12
	POP	11
	POP	10
	POP	9
	POP	8
	RETI
RTOS02:	
	POP	17H
	POP	16H
	POP	15H
	POP	14H
	POP	13H
	POP	12H
	POP	11H
	POP	10H
	RETI
RTOS03:	POP	1FH
	POP	1EH
	POP	1DH
	POP	1CH
	POP	1BH
	POP	1AH
	POP	19H
	POP	18H
	RETI
;-----------------------------	中断任务调度
RWDD0:	MOV	B,#7		;任务号
	MOV	R0,#RWS+7	;
	MOV	R1,#0FFH	;执行任务号
	MOV	A,RWB
	JNZ	RWDD3
	RET
RWDD3:	CLR	C
	RLC	A
	JNC	RWDD6
	CJNE	@R0,#0,RWDD2
RWDD4:	CJNE	R1,#0FFH,RWDD6
	MOV	R1,B
RWDD6:	DEC	R0
	DEC	B
	JNZ	RWDD3
	CJNE	R1,#0FFH,RWCL
	RET
RWDD2:	DEC	@R0
	CJNE	@R0,#0,RWDD6
	JMP	RWDD4
;---------------------------------
RWDD:	MOV	R1,#7
	MOV	R0,#RWS+7
	MOV	A,RWB
	JNZ	RWDD03
	RET
RWDD03:	CLR	C
	RLC	A
	JNC	RWDD06
	CJNE	@R0,#0,RWDD06
	JMP	RWCL
RWDD06:	DEC	R0
	DEC	R1
	JNZ	RWDD03
	RET
;--------------------------------------
RWCL:	MOV	DPTR,#RWDD   ;任务处理?
	PUSH	DPL
	PUSH	DPH
	MOV	A,R1
	RL	A
	ADD	A,#RWDZ
	MOV	R0,A
	MOV	A,@R0
	PUSH	ACC		;低地址在低字节
	INC	R0
	MOV	ACC,@R0
	PUSH	ACC

	MOV	A,#0FFH		;清除任务列表  当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,
	INC	R1		;可以加入一个执行标志 RWZT 来解决此问题。
	CLR	C
RWCL22:	RLC	A
	DJNZ	R1,RWCL22
	ANL	RWB,A
	RETI
;***********************************
	END
wk59121 2012-12-29
  • 打赏
  • 举报
回复
学习了...
lr2131 2012-12-27
  • 打赏
  • 举报
回复
呵呵,对硬件感兴趣(一白菜),主要还是搞软件的。
hbzyaxiu520 2012-12-27
  • 打赏
  • 举报
回复
引用 15 楼 lr2131 的回复:
引用 13 楼 hbzyaxiu520 的回复:引用 12 楼 hbzyaxiu520 的回复:CooCox CoOS 是一款针对ARM Cortex-M系列芯片而设计的实时系统内核。 CoOS特征: 免费并开源 ARM Cortex M3及M0定制操作系统 高度可裁剪性,最小系统内核仅974Byte 支持优先级抢占和时间片轮转 自适应任务调度算法 中断延时……
哈哈,兄台是硬件的吗?有空多交流呀!
zhujinqiang 2012-12-26
  • 打赏
  • 举报
回复
引用 17 楼 chenhao0568 的回复:
我再看看 。
从设计思想上面看,这个程序接近KEIL的RTX-51TINY 是一个基于定时器0的时间片轮询的任务调度,不过它汇编实现的比起RTX-51TINY粗糙很多. 参考:实时多任务操作系统RTX-51TINY 的应用 h t t p://read.pudn.com/downloads90/doc/344377/%E5%AE%9E%E6%97%B6%E5%A4%9A%E4%BB%BB%E5%8A%A1%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9FRTX-51TINY%E7%9A%84%E5%BA%94%E7%94%A8.pdf 基于分时系统的原理: 参考:基于MCS_51的实时多任务程序设计采用分时系统的原理 ht tp://www.ccf.org.cn/resources/1190201776262/2010/07/12/h0481080047.pdf
小黄人软件 2012-12-26
  • 打赏
  • 举报
回复
我再看看 。
zhujinqiang 2012-12-26
  • 打赏
  • 举报
回复
看来是一个基于定时器0的中断按中断周期来调度时间片的切换, 任务要在一个中断周期里面完成,
;RWZT        EQU    29H    ;任务状态,0为停止,1为正在执行

 当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,
    ;可以加入一个执行标志 RWZT 来解决此问题。
也就是当前正在执行的程序如果在定时器0的一个中断周期里面未执行完,下次再执行的时候需要检查 RWZT的标志位.
lr2131 2012-12-26
  • 打赏
  • 举报
回复
引用 13 楼 hbzyaxiu520 的回复:
引用 12 楼 hbzyaxiu520 的回复:CooCox CoOS 是一款针对ARM Cortex-M系列芯片而设计的实时系统内核。 CoOS特征: 免费并开源 ARM Cortex M3及M0定制操作系统 高度可裁剪性,最小系统内核仅974Byte 支持优先级抢占和时间片轮转 自适应任务调度算法 中断延时时间趋近于零 堆栈溢出检测 信号量、邮箱、队……
不错,等把UCOS2搞定了,下一个就是你了。
zhujinqiang 2012-12-25
  • 打赏
  • 举报
回复
陈明计有本书的 我在这下了一本 ht t p://u.xunzai.com/fileview_149233.html
小黄人软件 2012-12-25
  • 打赏
  • 举报
回复
是啊,一战成名。关于上面的程序???
zhujinqiang 2012-12-25
  • 打赏
  • 举报
回复
Small RTOS 陈明计的大作,后来给广州周立功收编了.
小黄人软件 2012-12-25
  • 打赏
  • 举报
回复
这后这一段了。
;-----------------------------	中断任务调度
RWDD0:	MOV	B,#7		;任务号
	MOV	R0,#RWS+7	;
	MOV	R1,#0FFH	;执行任务号
	MOV	A,RWB
	JNZ	RWDD3
	RET
RWDD3:	CLR	C
	RLC	A
	JNC	RWDD6
	CJNE	@R0,#0,RWDD2
RWDD4:	CJNE	R1,#0FFH,RWDD6
	MOV	R1,B
RWDD6:	DEC	R0
	DEC	B
	JNZ	RWDD3
	CJNE	R1,#0FFH,RWCL
	RET
RWDD2:	DEC	@R0
	CJNE	@R0,#0,RWDD6
	JMP	RWDD4
;---------------------------------
RWDD:	MOV	R1,#7
	MOV	R0,#RWS+7
	MOV	A,RWB
	JNZ	RWDD03
	RET
RWDD03:	CLR	C
	RLC	A
	JNC	RWDD06
	CJNE	@R0,#0,RWDD06
	JMP	RWCL
RWDD06:	DEC	R0
	DEC	R1
	JNZ	RWDD03
	RET
;--------------------------------------
RWCL:	MOV	DPTR,#RWDD   ;任务处理?
	PUSH	DPL
	PUSH	DPH
	MOV	A,R1
	RL	A
	ADD	A,#RWDZ
	MOV	R0,A
	MOV	A,@R0
	PUSH	ACC		;低地址在低字节
	INC	R0
	MOV	ACC,@R0
	PUSH	ACC

	MOV	A,#0FFH		;清除任务列表  当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,
	INC	R1		;可以加入一个执行标志 RWZT 来解决此问题。
	CLR	C
RWCL22:	RLC	A
	DJNZ	R1,RWCL22
	ANL	RWB,A
	RETI
;***********************************
	END
小黄人软件 2012-12-25
  • 打赏
  • 举报
回复
都是汇编,上面一点C是注释。我又翻译了一点,我也是,别人写的,现在程序要升级了,我要改用这个系统“基于80C51单片机源码公开的Small RTOS V1.20.3版”,我得知道原程序的意思啊。求援啊!!
;********************************************
;RTOS		用定时器0的多任务处理程序
;项目增加方式使用。
;程序不影响其它数据,目前程序的前后段不能进行参数传递 。 最多可以同时运行8个任务,
;执行时使用定时器0,定时时间根据初始化时的参数确定,一般为10mS。
;当指定优先级被占用时自动向高优先级调整,在R7中返回实际优先级,当所有高优先级都被占用时返回 0FFH,任务将被忽略。
;占用24H个内存单元。
;如果程序不可再入,需要设定 RWZT 的标志位。调用前先检查相应位。
;如果定时数设置过大,会引起一直在中断中,不能执行外部程序。如果任务执行时间过长,会引起堆栈溢出。
;18.432MHz,单时钟周期模式。不用任务单取反,输出频率 1.3MHz ,指令周期 384 nS 。速度是带系统的 100 倍。
;8个任务,只对管脚取反,T0=FEF0H,输出 2.8K 频率,为最高频率。执行周期不受任务影响。18.432MHz,单时钟周期模式。
;1个任务,只对管脚取反,T0=FFE1H,输出 12K 频率,为最高频率。执行周期受任务影响。每次调度时间为42US。
;*********************************************
;-------------------------------------------------------------	示例程序

;***********************************************
	NAME	RTOS_C    ;程序段名
	?PR?RTOS?RTOS_C		SEGMENT	CODE  
	?DT?RTOS?RTOS_C		SEGMENT DATA
	?ID?RTOS?RTOS_C		SEGMENT IDATA
	
	PUBLIC	RTOS
	PUBLIC	_RTOS_WAIT
	PUBLIC	_RTOS_INIT
;---------------------------------------------
;BANBH	EQU	0A3H	;版本号 101221
;定义数据地址
;----------------------------------------------
RSEG	?DT?RTOS?RTOS_C
;RWZT		EQU	29H	;任务状态,0为停止,1为正在执行
TL:	DS 1	;EQU	30H	;RTOS定时器值,C=FFFFH-ft
TH:	DS 1	;EQU	31H	;18.432MHz(12周期)=C400H
RWB:	DS 1	;EQU	33H	;任务表


RSEG	?ID?RTOS?RTOS_C
RWDZ:	DS 16	        ;任务堆栈
;	EQU	80H	;任务地址
;	EQU	8FH
RWS:	DS 8		;任务数
;	EQU	90H	;任务定时数
;	EQU	97H
;*********************************************
        CSEG  AT   0BH         ;TO入口
        JMP     RTOS	
;*********************************************
RSEG	?PR?RTOS?RTOS_C

_RTOS_INIT:			;任务初始化
;-------------------------------------------- 在 R6 R7 中,设置定时值
;RTOS定时器值,C=FFFFH-ft,18.432MHz(12周期)=C400H,40MHz(12周期)=7DC9H
;定时器0定时程序,18.432MHz,10MS,方式1
	  ORL    TMOD,#01H   ;定时10MS  ;定时器0初始化,设置TMOD
          MOV    TL0,R7
          MOV	 TL,R7	     ;设置TL
          MOV    TH0,R6
          MOV	 TH,R6       ;设置TH
          MOV	 RWB,#0	     ;任务表清0
          SETB   TR0   	     ;启动定时器
          SETB   ET0	     ;打开中断
          SETB   EA	     ;打开总中断
          RET                ;等待中断
;********************************************** 等待函数,优先级为最低 0 级,等待时间放入 R7 中
;	目前函数不能传递参数
_RTOS_WAIT:	MOV	A,R7 	;接收参数
	MOV	R5,A		;接收的数存在R5
	MOV	R7,#0		;R7清零
	CALL	YXJSZ		;??计数值?
	CJNE	R7,#8,RWSZ	;R7如果不等 于8,则任务设置
	MOV	R7,#0FFH	;返回值0xff
	RET			;返回
;---------------------------------------------	
RWSZ:	MOV	A,R7		;送任务数
	ADD	A,#RWS		;
	MOV	R0,A		;任务数保存到R0
	MOV	A,R5		;R5上是什么
	MOV	@R0,A   	;
	
	MOV	A,R7		;送地址
	RL	A		;
	ADD	A,#RWDZ
	MOV	R0,A
	POP	ACC		;跳转地址,在堆栈中
	POP	B
	MOV	@R0,B		;低地址在低字节
	INC	R0
	MOV	@R0,A
	
	MOV	B,R7		;设置任务列表 
	CLR	A		; 当前正在执行的程序如果被中断,并且中断中使用了此任务位,则此次任务将会丢失。
	INC	B		;可以关中断来解决此问题。
	SETB	C
RWSZ2:	RLC	A
	DJNZ	B,RWSZ2
	ORL	RWB,A
	RET
;--------------------------
YXJSZ:	MOV	B,R7	;0
	INC	B	;B++ 1
	MOV	A,RWB	;0
	CLR	C	;0
YXJ2:	RRC	A	;RRC是带进位的循环右移指令
	DJNZ	B,YXJ2 	;如果B不等于0,  b=0
YXJ4:	JNC	YXJ3	;C=0 ,则 
	RRC	A	;
	INC	R7	;
	JMP	YXJ4    ;
YXJ3:	RET 		;返回 

;------------------------------- 中断程序   把所有相关寄存器内容压入堆栈  任务调度完后 再弹出来
RTOS:	MOV    TH0,TH		;重载定时数
	MOV    TL0,TL		;
	JB	PSW.3,RTOS1	;RS0==1 用于选择当前工作寄存器区。8051有8个8位寄存器R0~R7
	JB	PSW.4,RTOS2	;RS1==1 
	PUSH	0		;RS0=0,RS1=0;  第一组寄存器区
	PUSH	1
	PUSH	2
	PUSH	3
	PUSH	4
	PUSH	5
	PUSH	6
	PUSH	7		;存入椎栈第一组寄存器上的内容
	JMP	RTOS0		;都跳到RTOS0
RTOS1:	JB	PSW.4,RTOS3	;
	PUSH	8		;RS0=1,RS1=0;  第三组寄存器区
	PUSH	9
	PUSH	10
	PUSH	11
	PUSH	12
	PUSH	13
	PUSH	14
	PUSH	15
	JMP	RTOS0		;
RTOS2:	
	PUSH	10H		;RS0=0,RS1=1;  	第二组寄存器区
	PUSH	11H
	PUSH	12H
	PUSH	13H
	PUSH	14H
	PUSH	15H
	PUSH	16H
	PUSH	17H
	JMP	RTOS0
RTOS3:	PUSH	18H		;RS0=1,RS1=1;	第四组寄存器区
	PUSH	19H
	PUSH	1AH
	PUSH	1BH
	PUSH	1CH
	PUSH	1DH
	PUSH	1EH
	PUSH	1FH

RTOS0:	PUSH	PSW 		;入栈
	PUSH	ACC		;
	PUSH	B
	PUSH	DPL
	PUSH	DPH
	CALL	RWDD0		;任务调度
	POP	DPH		;出栈
	POP	DPL
	POP	B		
	POP	ACC
	POP	PSW
	JB	PSW.3,RTOS01
	JB	PSW.4,RTOS02
	POP	7
	POP	6
	POP	5
	POP	4
	POP	3
	POP	2
	POP	1
	POP	0		;弹出第一组寄存器区上的变量
	RETI			;中断返回
RTOS01:	JB	PSW.4,RTOS3
	POP	15
	POP	14
	POP	13
	POP	12
	POP	11
	POP	10
	POP	9
	POP	8
	RETI
RTOS02:	
	POP	17H
	POP	16H
	POP	15H
	POP	14H
	POP	13H
	POP	12H
	POP	11H
	POP	10H
	RETI
RTOS03:	POP	1FH
	POP	1EH
	POP	1DH
	POP	1CH
	POP	1BH
	POP	1AH
	POP	19H
	POP	18H
	RETI
;-----------------------------	中断任务调度
RWDD0:	MOV	B,#7		;任务号
	MOV	R0,#RWS+7	;
	MOV	R1,#0FFH	;执行任务号
	MOV	A,RWB
	JNZ	RWDD3
	RET
RWDD3:	CLR	C
	RLC	A
	JNC	RWDD6
	CJNE	@R0,#0,RWDD2
RWDD4:	CJNE	R1,#0FFH,RWDD6
	MOV	R1,B
RWDD6:	DEC	R0
	DEC	B
	JNZ	RWDD3
	CJNE	R1,#0FFH,RWCL
	RET
RWDD2:	DEC	@R0
	CJNE	@R0,#0,RWDD6
	JMP	RWDD4
;---------------------------------
RWDD:	MOV	R1,#7
	MOV	R0,#RWS+7
	MOV	A,RWB
	JNZ	RWDD03
	RET
RWDD03:	CLR	C
	RLC	A
	JNC	RWDD06
	CJNE	@R0,#0,RWDD06
	JMP	RWCL
RWDD06:	DEC	R0
	DEC	R1
	JNZ	RWDD03
	RET
;--------------------------------------
RWCL:	MOV	DPTR,#RWDD   ;任务处理?
	PUSH	DPL
	PUSH	DPH
	MOV	A,R1
	RL	A
	ADD	A,#RWDZ
	MOV	R0,A
	MOV	A,@R0
	PUSH	ACC		;低地址在低字节
	INC	R0
	MOV	ACC,@R0
	PUSH	ACC

	MOV	A,#0FFH		;清除任务列表  当前正在执行的程序如果在下一个中断到来时还未执行完, 它的优先级将变为最低优先级,
	INC	R1		;可以加入一个执行标志 RWZT 来解决此问题。
	CLR	C
RWCL22:	RLC	A
	DJNZ	R1,RWCL22
	ANL	RWB,A
	RETI
;***********************************
	END
lr2131 2012-12-25
  • 打赏
  • 举报
回复
你这个是RTOS吗,怎么看了感觉只是有个简单的线程调度,而且流程上也不太规范。几乎大部分都是汇编,看起来难度不小,也没看出来是什么CPU的汇编,是51的吗? RTOS除了线程调度需要用汇编,其他的部分要么可以用纯C/C++写,要么可以用汇编调用C、C调用汇编来写。
小黄人软件 2012-12-25
  • 打赏
  • 举报
回复
操作系统耶 很牛的哦,可惜看不懂,唉!
zhujinqiang 2012-12-25
  • 打赏
  • 举报
回复
汇编啊很久不写了
Binzo 2012-12-25
  • 打赏
  • 举报
回复
一般都是时间轮换。我猜。
加载更多回复(5)

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧