79 个解决方案
#1
51的SP只有八位,只能在RAM区
这个很难办,得想办法做这个事
呵呵
Q群里一牛人说的
51不好的地方就是栈区只能在 DATA 区,移植UCOS时,所有任务的栈区都定义在 XDATA 区,要执行任务切换时,先把正在执行任务的栈区数据移到 XDATA 区,再把优先级最高的任务的栈区数据从 XDATA 区搬到 DATA 区再执行这个任务(靠执行中断返回指令)
这个很难办,得想办法做这个事
呵呵
Q群里一牛人说的
51不好的地方就是栈区只能在 DATA 区,移植UCOS时,所有任务的栈区都定义在 XDATA 区,要执行任务切换时,先把正在执行任务的栈区数据移到 XDATA 区,再把优先级最高的任务的栈区数据从 XDATA 区搬到 DATA 区再执行这个任务(靠执行中断返回指令)
#2
。。51还做什么RTOS 都用汇编了
堆栈占用多少RAM,主要看你每个任务的局部变量以及,任务中调用其他函数的次数
堆栈占用多少RAM,主要看你每个任务的局部变量以及,任务中调用其他函数的次数
#3
我就是想知道每一个任务切换时需不需要把每一个任务的R0~R7,ACC,B,PSW,SP,DPTR都放入堆栈,
如果是这样的话,就以51那可怜的RAM来说,可以做多少的任务呢,
何况每一个任务肯定还有自己的变量,这样子就很难搞了
如果是这样的话,就以51那可怜的RAM来说,可以做多少的任务呢,
何况每一个任务肯定还有自己的变量,这样子就很难搞了
#4
51最好的RTOS就是KEIL的RTX-51。51资源太少了,对其它OS而言都是鸡肋。
#5
现在在写程序,一定的时间后发表出来
#6
期待LZ。。
#7
现在写了点东西出来,不是很多,功能也很单一,希望高手指点一下,以不断完善程序;
程序放在下面,有兴趣的同行可以看看,提点意见最好,小弟初学操作系统,还想深入点啊
程序放在下面,有兴趣的同行可以看看,提点意见最好,小弟初学操作系统,还想深入点啊
#8
/**********************************************************
*
* X_OS_51
* X_OS_51 FOR KEIL
* 版权所有:潘 科
* 日期:1-11-08
* 版本:V0.0.1
*
**********************************************************/
NAME HEAD_A51
CLEARING EQU 0
RAM_TOP EQU 80H
EXTRN CODE (START_KERNEL)
EXTRN DATA (STACK_SYS)
PUBLIC HEAD
CSEG AT 0
LJMP HEAD
CSEG AT 26H
HEAD:
IF CLEARING <> 0
MOV R0,#RAM_TOP - 1
?H0001: MOV @R0,#0
DJNZ R0,?H0001
ENDIF
MOV SP,#STACK_SYS
MOV DPTR,#START_KERNEL
MOV A,DPL
PUSH ACC
MOV A,DPH
PUSH ACC
RET
END
/*********************************************************
*
* START_KERNEL AND TASK SWITCH
* 版权所有:潘 科
* 日期:3-11-08
* 版本:V0.0.1
*
*********************************************************/
NAME KERNEL_A51
USER EQU 4//任务数量
FRIST EQU 2//第一个任务编号
PLACE EQU 2//用户堆栈空间
?PR?START_KERNEL?KERNEL SEGMENT CODE//函数(程序)
?PR?TIME_0?INTERRUPT SEGMENT CODE//函数(中断)
?DT?KERNEL SEGMENT DATA//全局变量
PUBLIC START_KERNEL//声明函数
PUBLIC TIME_0
PUBLIC STACK_SYS//声明变量
PUBLIC TASK_NUMBER
PUBLIC CURRENT_TASK
PUBLIC NEXT_TASK
PUBLIC TEMP_TASK_IDH
PUBLIC TEMP_TASK_IDL
RSEG ?DT?KERNEL//全局变量
?DT?KERNEL?BYTE:
STACK_SYS: DS USER * 2 + 1 + PLACE//系统堆栈
TASK_NUMBER: DS 1//任务数目
CURRENT_TASK: DS 1//当前任务
NEXT_TASK: DS 1//下一个任务
TEMP_TASK_IDH: DS 1//地址暂存器(HIGH)
TEMP_TASK_IDL: DS 1//地址暂存器(LOW)
EXTRN CODE (TASKLIST)//任务地址列表
//FUNTION OF START_KERNEL
//描述:初步处理任务地址与堆栈
RSEG ?PR?START_KERNEL?KERNEL//函数(程序)段
USING 0
START_KERNEL:
MOV TASK_NUMBER,#0
MOV SP,#STACK_SYS//设置系统堆栈(任务地址)
MOV DPTR,#TASKLIST//任务地址送入堆栈
?S0001: MOV A,#1
MOVC A,@A + DPTR
PUSH ACC
CLR A
MOVC A,@A + DPTR
PUSH ACC
INC DPTR
INC DPTR
INC TASK_NUMBER//任务数目
MOV A,TASK_NUMBER
CJNE A,#USER,?S0001
MOV CURRENT_TASK,#FRIST//当前任务
MOV A,#FRIST + 1
CJNE A,#USER + 1,?S0002
MOV A,#1
?S0002: MOV NEXT_TASK,A//下一个任务
MOV A,#-1
MOV R0,#FRIST//第一个任务
?S0003: ADD A,#2
DJNZ R0,?S0003
ADD A,#STACK_SYS//计算偏移地址
MOV R0,A
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
MOV TMOD,#01H//定时中断设置
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA
SETB TR0
SETB ET0
RET
//FUNTION OF TIME_0 INTERRUPT
//描述:中断函数切换任务
CSEG AT 0BH
LJMP TIME_0
RSEG ?PR?TIME_0?INTERRUPT
USING 0
TIME_0:
MOV TH0,#3CH
MOV TL0,#0B0H
POP TEMP_TASK_IDH//取出当前任务中断地址
POP TEMP_TASK_IDL
MOV R1,SP
MOV R0,CURRENT_TASK//取得当前任务
MOV A,#STACK_SYS - 2//计算当前任务地址
?T0001: ADD A,#2
DJNZ R0,?T0001
MOV SP,A
PUSH TEMP_TASK_IDL//更新任务中断地址
PUSH TEMP_TASK_IDH
MOV CURRENT_TASK,NEXT_TASK//当前任务更新
MOV A,CURRENT_TASK
INC A
CJNE A,#USER + 1,?T0002
MOV A,#1
?T0002: MOV NEXT_TASK,A//下一个任务更新
MOV A,#STACK_SYS//计算下一个任务地址
MOV R0,CURRENT_TASK
?T0003: ADD A,#2
DJNZ R0,?T0003
MOV SP,A
POP TEMP_TASK_IDL//取出任务地址
POP TEMP_TASK_IDH
MOV SP,R1
PUSH TEMP_TASK_IDH//更新任务
PUSH TEMP_TASK_IDL
RETI
END
/*********************************************************
*
*四个简单的任务,没办法,小弟才疏学浅,很多东西都不是很会啊
*
*********************************************************/
#include"reg52.h"
void USR_1(void)
{
while(1)
{
P0 = ~P0;
}
}
void USR_2(void)
{
while(1)
{
P1 = ~P1;
}
}
void USR_3(void)
{
while(1)
{
P2 = ~P2;
}
}
void USR_4(void)
{
while(1)
{
P3 = ~P3;
}
}
code int TASKLIST[4] = {USR_1,USR_2,USR_3,USR_4};//任务地址列表
*
* X_OS_51
* X_OS_51 FOR KEIL
* 版权所有:潘 科
* 日期:1-11-08
* 版本:V0.0.1
*
**********************************************************/
NAME HEAD_A51
CLEARING EQU 0
RAM_TOP EQU 80H
EXTRN CODE (START_KERNEL)
EXTRN DATA (STACK_SYS)
PUBLIC HEAD
CSEG AT 0
LJMP HEAD
CSEG AT 26H
HEAD:
IF CLEARING <> 0
MOV R0,#RAM_TOP - 1
?H0001: MOV @R0,#0
DJNZ R0,?H0001
ENDIF
MOV SP,#STACK_SYS
MOV DPTR,#START_KERNEL
MOV A,DPL
PUSH ACC
MOV A,DPH
PUSH ACC
RET
END
/*********************************************************
*
* START_KERNEL AND TASK SWITCH
* 版权所有:潘 科
* 日期:3-11-08
* 版本:V0.0.1
*
*********************************************************/
NAME KERNEL_A51
USER EQU 4//任务数量
FRIST EQU 2//第一个任务编号
PLACE EQU 2//用户堆栈空间
?PR?START_KERNEL?KERNEL SEGMENT CODE//函数(程序)
?PR?TIME_0?INTERRUPT SEGMENT CODE//函数(中断)
?DT?KERNEL SEGMENT DATA//全局变量
PUBLIC START_KERNEL//声明函数
PUBLIC TIME_0
PUBLIC STACK_SYS//声明变量
PUBLIC TASK_NUMBER
PUBLIC CURRENT_TASK
PUBLIC NEXT_TASK
PUBLIC TEMP_TASK_IDH
PUBLIC TEMP_TASK_IDL
RSEG ?DT?KERNEL//全局变量
?DT?KERNEL?BYTE:
STACK_SYS: DS USER * 2 + 1 + PLACE//系统堆栈
TASK_NUMBER: DS 1//任务数目
CURRENT_TASK: DS 1//当前任务
NEXT_TASK: DS 1//下一个任务
TEMP_TASK_IDH: DS 1//地址暂存器(HIGH)
TEMP_TASK_IDL: DS 1//地址暂存器(LOW)
EXTRN CODE (TASKLIST)//任务地址列表
//FUNTION OF START_KERNEL
//描述:初步处理任务地址与堆栈
RSEG ?PR?START_KERNEL?KERNEL//函数(程序)段
USING 0
START_KERNEL:
MOV TASK_NUMBER,#0
MOV SP,#STACK_SYS//设置系统堆栈(任务地址)
MOV DPTR,#TASKLIST//任务地址送入堆栈
?S0001: MOV A,#1
MOVC A,@A + DPTR
PUSH ACC
CLR A
MOVC A,@A + DPTR
PUSH ACC
INC DPTR
INC DPTR
INC TASK_NUMBER//任务数目
MOV A,TASK_NUMBER
CJNE A,#USER,?S0001
MOV CURRENT_TASK,#FRIST//当前任务
MOV A,#FRIST + 1
CJNE A,#USER + 1,?S0002
MOV A,#1
?S0002: MOV NEXT_TASK,A//下一个任务
MOV A,#-1
MOV R0,#FRIST//第一个任务
?S0003: ADD A,#2
DJNZ R0,?S0003
ADD A,#STACK_SYS//计算偏移地址
MOV R0,A
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
MOV TMOD,#01H//定时中断设置
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA
SETB TR0
SETB ET0
RET
//FUNTION OF TIME_0 INTERRUPT
//描述:中断函数切换任务
CSEG AT 0BH
LJMP TIME_0
RSEG ?PR?TIME_0?INTERRUPT
USING 0
TIME_0:
MOV TH0,#3CH
MOV TL0,#0B0H
POP TEMP_TASK_IDH//取出当前任务中断地址
POP TEMP_TASK_IDL
MOV R1,SP
MOV R0,CURRENT_TASK//取得当前任务
MOV A,#STACK_SYS - 2//计算当前任务地址
?T0001: ADD A,#2
DJNZ R0,?T0001
MOV SP,A
PUSH TEMP_TASK_IDL//更新任务中断地址
PUSH TEMP_TASK_IDH
MOV CURRENT_TASK,NEXT_TASK//当前任务更新
MOV A,CURRENT_TASK
INC A
CJNE A,#USER + 1,?T0002
MOV A,#1
?T0002: MOV NEXT_TASK,A//下一个任务更新
MOV A,#STACK_SYS//计算下一个任务地址
MOV R0,CURRENT_TASK
?T0003: ADD A,#2
DJNZ R0,?T0003
MOV SP,A
POP TEMP_TASK_IDL//取出任务地址
POP TEMP_TASK_IDH
MOV SP,R1
PUSH TEMP_TASK_IDH//更新任务
PUSH TEMP_TASK_IDL
RETI
END
/*********************************************************
*
*四个简单的任务,没办法,小弟才疏学浅,很多东西都不是很会啊
*
*********************************************************/
#include"reg52.h"
void USR_1(void)
{
while(1)
{
P0 = ~P0;
}
}
void USR_2(void)
{
while(1)
{
P1 = ~P1;
}
}
void USR_3(void)
{
while(1)
{
P2 = ~P2;
}
}
void USR_4(void)
{
while(1)
{
P3 = ~P3;
}
}
code int TASKLIST[4] = {USR_1,USR_2,USR_3,USR_4};//任务地址列表
#9
至少要89S53才能跑ucos,楼主百度一下,大把多。至于堆栈用于保存任务信息,以及一些变量之类的东西了。
#10
支持LZ
偶还没有用汇编写过这么多东西呢
向LZ学习
希望能持续更新,有什么问题大伙讨论,呵呵
谢谢
偶还没有用汇编写过这么多东西呢
向LZ学习
希望能持续更新,有什么问题大伙讨论,呵呵
谢谢
#11
无意中闯入单片机 帮顶
#12
mark 好贴
#13
小弟也是刚开始弄操作系统,很多机制都不是很晓得,当然希望有各位的指点啊,
我这里的堆栈做得应该不是很好,我也在想办法更新,还有那个任务切换,这里只限于一个循环切换,
还是有许多地方要进一步改善啊
我这里的堆栈做得应该不是很好,我也在想办法更新,还有那个任务切换,这里只限于一个循环切换,
还是有许多地方要进一步改善啊
#14
hen hao
#15
支持楼主的汇编与51的钻研精神,不过现在的CPU和操作系统的概念都先进了不少。像ARM就有很多种运行的模式,其实我倒是建议您,先把X86的架构搞明白也比再做51有前途:)
#16
在操作系统里
这个叫非抢占式轮循调度
你再分一下时间片,提高一下响应时间的确定性
呵呵
#17
mark好深奥
#18
根据16L说的,原来这个就是非抢占式轮循调度啊,
我原来也有一点想法的,就是那些任务既然已经是确定了运行顺序的,
那么我可以根据完成每一个任务大概所需要的时间对时间片进行分割,
如任务1:10ms,
任务2:20ms,
任务3:50ms,
...
这样的效果好不好呢?
我原来也有一点想法的,就是那些任务既然已经是确定了运行顺序的,
那么我可以根据完成每一个任务大概所需要的时间对时间片进行分割,
如任务1:10ms,
任务2:20ms,
任务3:50ms,
...
这样的效果好不好呢?
#19
继续关注下~~
#20
LZ再去想想时间片的概念
呵呵
现在我手头上有几个东西,等我空下来
咱们一起玩
呵呵
现在我手头上有几个东西,等我空下来
咱们一起玩
#21
学习学习
#22
继续学习一下...
#23
学习ing...
#24
其实我也是从汇编起家的,呵呵,最基础的东西啊,大家不要小看它啊
对于细节上的处理来说,汇编好做啊,
C语言在现在的优势是比较大的,以后,我会想办法把程序改成C的,
希望现在大家把问题提出来,我好想办法改正,
OS有深度,但是这和难度又不一样,有人觉得难学,有人觉得好学,
其实,我觉得只要你去做,肯思考,就很容易上手的,
再次希望大家提点意见出来
对于细节上的处理来说,汇编好做啊,
C语言在现在的优势是比较大的,以后,我会想办法把程序改成C的,
希望现在大家把问题提出来,我好想办法改正,
OS有深度,但是这和难度又不一样,有人觉得难学,有人觉得好学,
其实,我觉得只要你去做,肯思考,就很容易上手的,
再次希望大家提点意见出来
#25
不错!
学习和关注中!
学习和关注中!
#26
基本上大伙都是从汇编起步的
呵呵
不过,出来后做项目,由于C的项目管理上的优势
偶的汇编渐渐被废掉
嘿嘿
还要回来还得花点时间
如果还有学习的朋友
别轻易把学到的东西丢掉了,怪可惜的
呵呵
不过,出来后做项目,由于C的项目管理上的优势
偶的汇编渐渐被废掉
嘿嘿
还要回来还得花点时间
如果还有学习的朋友
别轻易把学到的东西丢掉了,怪可惜的
#27
好贴,汇编有点看不懂啊
#28
mark
操作系统~~~学习ing
操作系统~~~学习ing
#29
嘿嘿
#30
单片机如果不是对实时性有很高要求用时间片平均分配任务足够
需要很实时的系统还是不要用RTOS的
C51这类资源少的单片机还是用Keil RTX这类小型RTOS足够了
自己弄也可以,但也是越精简越好的
偶就弄有AVR的RTOS用着还OK
需要很实时的系统还是不要用RTOS的
C51这类资源少的单片机还是用Keil RTX这类小型RTOS足够了
自己弄也可以,但也是越精简越好的
偶就弄有AVR的RTOS用着还OK
#31
mark
#32
汇编虽然是在项目当中用得少了,不过对于搞嵌入式的人来说,是不可或缺的知识吧!再顶一下楼主!!
#33
学习
#34
这个嘛,让我再想想
#35
顶
#36
貌似很高深的问题
#37
lihai a
#38
支持LZ
谢谢
谢谢
#39
支持
#40
路过
#41
我们现在正在学单片机,不难吧?
#42
我们现在正在学单片机,不难吧?
#43
路过
#44
学习
顶一下
顶一下
#45
你可以想法把堆栈写到片外内存,这个压力就没有了。
SpAddl equ 08h
SpAddh equ 09h
dplbak equ 0ah
dphbak equ 0bh
main:
mov sp,#40h
mov a,r0
call PushReg
call PopReg
mov r1,a
sjmp $
PushReg:
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
movx @dptr,a ;a 保存要压栈数据
inc dptr
mov SpAddl ,dpl
mov SpAddh ,dph
mov dpl,dplbak
mov dph,dphbak
ret
PopReg:
push psw
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
dec dplbak
jnc PopReg1
dec dphbak
PopReg1:
movx a,@dptr ;a 保存要弹栈数据
mov dpl,dplbak
mov dph,dphbak
pop psw
ret
SpAddl equ 08h
SpAddh equ 09h
dplbak equ 0ah
dphbak equ 0bh
main:
mov sp,#40h
mov a,r0
call PushReg
call PopReg
mov r1,a
sjmp $
PushReg:
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
movx @dptr,a ;a 保存要压栈数据
inc dptr
mov SpAddl ,dpl
mov SpAddh ,dph
mov dpl,dplbak
mov dph,dphbak
ret
PopReg:
push psw
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
dec dplbak
jnc PopReg1
dec dphbak
PopReg1:
movx a,@dptr ;a 保存要弹栈数据
mov dpl,dplbak
mov dph,dphbak
pop psw
ret
#46
我觉得这并不仅仅是一个内外RAM的问题,51实现大容量的堆栈是有点难度的,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
#47
我觉得这并不仅仅是一个内外RAM的问题,51实现大容量的堆栈是有点难度的,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
#48
我觉得这并不仅仅是一个内外RAM的问题,51实现大容量的堆栈是有点难度的,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
#49
大家好!以后得请大家多多指教!
#50
#1
51的SP只有八位,只能在RAM区
这个很难办,得想办法做这个事
呵呵
Q群里一牛人说的
51不好的地方就是栈区只能在 DATA 区,移植UCOS时,所有任务的栈区都定义在 XDATA 区,要执行任务切换时,先把正在执行任务的栈区数据移到 XDATA 区,再把优先级最高的任务的栈区数据从 XDATA 区搬到 DATA 区再执行这个任务(靠执行中断返回指令)
这个很难办,得想办法做这个事
呵呵
Q群里一牛人说的
51不好的地方就是栈区只能在 DATA 区,移植UCOS时,所有任务的栈区都定义在 XDATA 区,要执行任务切换时,先把正在执行任务的栈区数据移到 XDATA 区,再把优先级最高的任务的栈区数据从 XDATA 区搬到 DATA 区再执行这个任务(靠执行中断返回指令)
#2
。。51还做什么RTOS 都用汇编了
堆栈占用多少RAM,主要看你每个任务的局部变量以及,任务中调用其他函数的次数
堆栈占用多少RAM,主要看你每个任务的局部变量以及,任务中调用其他函数的次数
#3
我就是想知道每一个任务切换时需不需要把每一个任务的R0~R7,ACC,B,PSW,SP,DPTR都放入堆栈,
如果是这样的话,就以51那可怜的RAM来说,可以做多少的任务呢,
何况每一个任务肯定还有自己的变量,这样子就很难搞了
如果是这样的话,就以51那可怜的RAM来说,可以做多少的任务呢,
何况每一个任务肯定还有自己的变量,这样子就很难搞了
#4
51最好的RTOS就是KEIL的RTX-51。51资源太少了,对其它OS而言都是鸡肋。
#5
现在在写程序,一定的时间后发表出来
#6
期待LZ。。
#7
现在写了点东西出来,不是很多,功能也很单一,希望高手指点一下,以不断完善程序;
程序放在下面,有兴趣的同行可以看看,提点意见最好,小弟初学操作系统,还想深入点啊
程序放在下面,有兴趣的同行可以看看,提点意见最好,小弟初学操作系统,还想深入点啊
#8
/**********************************************************
*
* X_OS_51
* X_OS_51 FOR KEIL
* 版权所有:潘 科
* 日期:1-11-08
* 版本:V0.0.1
*
**********************************************************/
NAME HEAD_A51
CLEARING EQU 0
RAM_TOP EQU 80H
EXTRN CODE (START_KERNEL)
EXTRN DATA (STACK_SYS)
PUBLIC HEAD
CSEG AT 0
LJMP HEAD
CSEG AT 26H
HEAD:
IF CLEARING <> 0
MOV R0,#RAM_TOP - 1
?H0001: MOV @R0,#0
DJNZ R0,?H0001
ENDIF
MOV SP,#STACK_SYS
MOV DPTR,#START_KERNEL
MOV A,DPL
PUSH ACC
MOV A,DPH
PUSH ACC
RET
END
/*********************************************************
*
* START_KERNEL AND TASK SWITCH
* 版权所有:潘 科
* 日期:3-11-08
* 版本:V0.0.1
*
*********************************************************/
NAME KERNEL_A51
USER EQU 4//任务数量
FRIST EQU 2//第一个任务编号
PLACE EQU 2//用户堆栈空间
?PR?START_KERNEL?KERNEL SEGMENT CODE//函数(程序)
?PR?TIME_0?INTERRUPT SEGMENT CODE//函数(中断)
?DT?KERNEL SEGMENT DATA//全局变量
PUBLIC START_KERNEL//声明函数
PUBLIC TIME_0
PUBLIC STACK_SYS//声明变量
PUBLIC TASK_NUMBER
PUBLIC CURRENT_TASK
PUBLIC NEXT_TASK
PUBLIC TEMP_TASK_IDH
PUBLIC TEMP_TASK_IDL
RSEG ?DT?KERNEL//全局变量
?DT?KERNEL?BYTE:
STACK_SYS: DS USER * 2 + 1 + PLACE//系统堆栈
TASK_NUMBER: DS 1//任务数目
CURRENT_TASK: DS 1//当前任务
NEXT_TASK: DS 1//下一个任务
TEMP_TASK_IDH: DS 1//地址暂存器(HIGH)
TEMP_TASK_IDL: DS 1//地址暂存器(LOW)
EXTRN CODE (TASKLIST)//任务地址列表
//FUNTION OF START_KERNEL
//描述:初步处理任务地址与堆栈
RSEG ?PR?START_KERNEL?KERNEL//函数(程序)段
USING 0
START_KERNEL:
MOV TASK_NUMBER,#0
MOV SP,#STACK_SYS//设置系统堆栈(任务地址)
MOV DPTR,#TASKLIST//任务地址送入堆栈
?S0001: MOV A,#1
MOVC A,@A + DPTR
PUSH ACC
CLR A
MOVC A,@A + DPTR
PUSH ACC
INC DPTR
INC DPTR
INC TASK_NUMBER//任务数目
MOV A,TASK_NUMBER
CJNE A,#USER,?S0001
MOV CURRENT_TASK,#FRIST//当前任务
MOV A,#FRIST + 1
CJNE A,#USER + 1,?S0002
MOV A,#1
?S0002: MOV NEXT_TASK,A//下一个任务
MOV A,#-1
MOV R0,#FRIST//第一个任务
?S0003: ADD A,#2
DJNZ R0,?S0003
ADD A,#STACK_SYS//计算偏移地址
MOV R0,A
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
MOV TMOD,#01H//定时中断设置
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA
SETB TR0
SETB ET0
RET
//FUNTION OF TIME_0 INTERRUPT
//描述:中断函数切换任务
CSEG AT 0BH
LJMP TIME_0
RSEG ?PR?TIME_0?INTERRUPT
USING 0
TIME_0:
MOV TH0,#3CH
MOV TL0,#0B0H
POP TEMP_TASK_IDH//取出当前任务中断地址
POP TEMP_TASK_IDL
MOV R1,SP
MOV R0,CURRENT_TASK//取得当前任务
MOV A,#STACK_SYS - 2//计算当前任务地址
?T0001: ADD A,#2
DJNZ R0,?T0001
MOV SP,A
PUSH TEMP_TASK_IDL//更新任务中断地址
PUSH TEMP_TASK_IDH
MOV CURRENT_TASK,NEXT_TASK//当前任务更新
MOV A,CURRENT_TASK
INC A
CJNE A,#USER + 1,?T0002
MOV A,#1
?T0002: MOV NEXT_TASK,A//下一个任务更新
MOV A,#STACK_SYS//计算下一个任务地址
MOV R0,CURRENT_TASK
?T0003: ADD A,#2
DJNZ R0,?T0003
MOV SP,A
POP TEMP_TASK_IDL//取出任务地址
POP TEMP_TASK_IDH
MOV SP,R1
PUSH TEMP_TASK_IDH//更新任务
PUSH TEMP_TASK_IDL
RETI
END
/*********************************************************
*
*四个简单的任务,没办法,小弟才疏学浅,很多东西都不是很会啊
*
*********************************************************/
#include"reg52.h"
void USR_1(void)
{
while(1)
{
P0 = ~P0;
}
}
void USR_2(void)
{
while(1)
{
P1 = ~P1;
}
}
void USR_3(void)
{
while(1)
{
P2 = ~P2;
}
}
void USR_4(void)
{
while(1)
{
P3 = ~P3;
}
}
code int TASKLIST[4] = {USR_1,USR_2,USR_3,USR_4};//任务地址列表
*
* X_OS_51
* X_OS_51 FOR KEIL
* 版权所有:潘 科
* 日期:1-11-08
* 版本:V0.0.1
*
**********************************************************/
NAME HEAD_A51
CLEARING EQU 0
RAM_TOP EQU 80H
EXTRN CODE (START_KERNEL)
EXTRN DATA (STACK_SYS)
PUBLIC HEAD
CSEG AT 0
LJMP HEAD
CSEG AT 26H
HEAD:
IF CLEARING <> 0
MOV R0,#RAM_TOP - 1
?H0001: MOV @R0,#0
DJNZ R0,?H0001
ENDIF
MOV SP,#STACK_SYS
MOV DPTR,#START_KERNEL
MOV A,DPL
PUSH ACC
MOV A,DPH
PUSH ACC
RET
END
/*********************************************************
*
* START_KERNEL AND TASK SWITCH
* 版权所有:潘 科
* 日期:3-11-08
* 版本:V0.0.1
*
*********************************************************/
NAME KERNEL_A51
USER EQU 4//任务数量
FRIST EQU 2//第一个任务编号
PLACE EQU 2//用户堆栈空间
?PR?START_KERNEL?KERNEL SEGMENT CODE//函数(程序)
?PR?TIME_0?INTERRUPT SEGMENT CODE//函数(中断)
?DT?KERNEL SEGMENT DATA//全局变量
PUBLIC START_KERNEL//声明函数
PUBLIC TIME_0
PUBLIC STACK_SYS//声明变量
PUBLIC TASK_NUMBER
PUBLIC CURRENT_TASK
PUBLIC NEXT_TASK
PUBLIC TEMP_TASK_IDH
PUBLIC TEMP_TASK_IDL
RSEG ?DT?KERNEL//全局变量
?DT?KERNEL?BYTE:
STACK_SYS: DS USER * 2 + 1 + PLACE//系统堆栈
TASK_NUMBER: DS 1//任务数目
CURRENT_TASK: DS 1//当前任务
NEXT_TASK: DS 1//下一个任务
TEMP_TASK_IDH: DS 1//地址暂存器(HIGH)
TEMP_TASK_IDL: DS 1//地址暂存器(LOW)
EXTRN CODE (TASKLIST)//任务地址列表
//FUNTION OF START_KERNEL
//描述:初步处理任务地址与堆栈
RSEG ?PR?START_KERNEL?KERNEL//函数(程序)段
USING 0
START_KERNEL:
MOV TASK_NUMBER,#0
MOV SP,#STACK_SYS//设置系统堆栈(任务地址)
MOV DPTR,#TASKLIST//任务地址送入堆栈
?S0001: MOV A,#1
MOVC A,@A + DPTR
PUSH ACC
CLR A
MOVC A,@A + DPTR
PUSH ACC
INC DPTR
INC DPTR
INC TASK_NUMBER//任务数目
MOV A,TASK_NUMBER
CJNE A,#USER,?S0001
MOV CURRENT_TASK,#FRIST//当前任务
MOV A,#FRIST + 1
CJNE A,#USER + 1,?S0002
MOV A,#1
?S0002: MOV NEXT_TASK,A//下一个任务
MOV A,#-1
MOV R0,#FRIST//第一个任务
?S0003: ADD A,#2
DJNZ R0,?S0003
ADD A,#STACK_SYS//计算偏移地址
MOV R0,A
MOV A,@R0
PUSH ACC
INC R0
MOV A,@R0
PUSH ACC
MOV TMOD,#01H//定时中断设置
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA
SETB TR0
SETB ET0
RET
//FUNTION OF TIME_0 INTERRUPT
//描述:中断函数切换任务
CSEG AT 0BH
LJMP TIME_0
RSEG ?PR?TIME_0?INTERRUPT
USING 0
TIME_0:
MOV TH0,#3CH
MOV TL0,#0B0H
POP TEMP_TASK_IDH//取出当前任务中断地址
POP TEMP_TASK_IDL
MOV R1,SP
MOV R0,CURRENT_TASK//取得当前任务
MOV A,#STACK_SYS - 2//计算当前任务地址
?T0001: ADD A,#2
DJNZ R0,?T0001
MOV SP,A
PUSH TEMP_TASK_IDL//更新任务中断地址
PUSH TEMP_TASK_IDH
MOV CURRENT_TASK,NEXT_TASK//当前任务更新
MOV A,CURRENT_TASK
INC A
CJNE A,#USER + 1,?T0002
MOV A,#1
?T0002: MOV NEXT_TASK,A//下一个任务更新
MOV A,#STACK_SYS//计算下一个任务地址
MOV R0,CURRENT_TASK
?T0003: ADD A,#2
DJNZ R0,?T0003
MOV SP,A
POP TEMP_TASK_IDL//取出任务地址
POP TEMP_TASK_IDH
MOV SP,R1
PUSH TEMP_TASK_IDH//更新任务
PUSH TEMP_TASK_IDL
RETI
END
/*********************************************************
*
*四个简单的任务,没办法,小弟才疏学浅,很多东西都不是很会啊
*
*********************************************************/
#include"reg52.h"
void USR_1(void)
{
while(1)
{
P0 = ~P0;
}
}
void USR_2(void)
{
while(1)
{
P1 = ~P1;
}
}
void USR_3(void)
{
while(1)
{
P2 = ~P2;
}
}
void USR_4(void)
{
while(1)
{
P3 = ~P3;
}
}
code int TASKLIST[4] = {USR_1,USR_2,USR_3,USR_4};//任务地址列表
#9
至少要89S53才能跑ucos,楼主百度一下,大把多。至于堆栈用于保存任务信息,以及一些变量之类的东西了。
#10
支持LZ
偶还没有用汇编写过这么多东西呢
向LZ学习
希望能持续更新,有什么问题大伙讨论,呵呵
谢谢
偶还没有用汇编写过这么多东西呢
向LZ学习
希望能持续更新,有什么问题大伙讨论,呵呵
谢谢
#11
无意中闯入单片机 帮顶
#12
mark 好贴
#13
小弟也是刚开始弄操作系统,很多机制都不是很晓得,当然希望有各位的指点啊,
我这里的堆栈做得应该不是很好,我也在想办法更新,还有那个任务切换,这里只限于一个循环切换,
还是有许多地方要进一步改善啊
我这里的堆栈做得应该不是很好,我也在想办法更新,还有那个任务切换,这里只限于一个循环切换,
还是有许多地方要进一步改善啊
#14
hen hao
#15
支持楼主的汇编与51的钻研精神,不过现在的CPU和操作系统的概念都先进了不少。像ARM就有很多种运行的模式,其实我倒是建议您,先把X86的架构搞明白也比再做51有前途:)
#16
在操作系统里
这个叫非抢占式轮循调度
你再分一下时间片,提高一下响应时间的确定性
呵呵
#17
mark好深奥
#18
根据16L说的,原来这个就是非抢占式轮循调度啊,
我原来也有一点想法的,就是那些任务既然已经是确定了运行顺序的,
那么我可以根据完成每一个任务大概所需要的时间对时间片进行分割,
如任务1:10ms,
任务2:20ms,
任务3:50ms,
...
这样的效果好不好呢?
我原来也有一点想法的,就是那些任务既然已经是确定了运行顺序的,
那么我可以根据完成每一个任务大概所需要的时间对时间片进行分割,
如任务1:10ms,
任务2:20ms,
任务3:50ms,
...
这样的效果好不好呢?
#19
继续关注下~~
#20
LZ再去想想时间片的概念
呵呵
现在我手头上有几个东西,等我空下来
咱们一起玩
呵呵
现在我手头上有几个东西,等我空下来
咱们一起玩
#21
学习学习
#22
继续学习一下...
#23
学习ing...
#24
其实我也是从汇编起家的,呵呵,最基础的东西啊,大家不要小看它啊
对于细节上的处理来说,汇编好做啊,
C语言在现在的优势是比较大的,以后,我会想办法把程序改成C的,
希望现在大家把问题提出来,我好想办法改正,
OS有深度,但是这和难度又不一样,有人觉得难学,有人觉得好学,
其实,我觉得只要你去做,肯思考,就很容易上手的,
再次希望大家提点意见出来
对于细节上的处理来说,汇编好做啊,
C语言在现在的优势是比较大的,以后,我会想办法把程序改成C的,
希望现在大家把问题提出来,我好想办法改正,
OS有深度,但是这和难度又不一样,有人觉得难学,有人觉得好学,
其实,我觉得只要你去做,肯思考,就很容易上手的,
再次希望大家提点意见出来
#25
不错!
学习和关注中!
学习和关注中!
#26
基本上大伙都是从汇编起步的
呵呵
不过,出来后做项目,由于C的项目管理上的优势
偶的汇编渐渐被废掉
嘿嘿
还要回来还得花点时间
如果还有学习的朋友
别轻易把学到的东西丢掉了,怪可惜的
呵呵
不过,出来后做项目,由于C的项目管理上的优势
偶的汇编渐渐被废掉
嘿嘿
还要回来还得花点时间
如果还有学习的朋友
别轻易把学到的东西丢掉了,怪可惜的
#27
好贴,汇编有点看不懂啊
#28
mark
操作系统~~~学习ing
操作系统~~~学习ing
#29
嘿嘿
#30
单片机如果不是对实时性有很高要求用时间片平均分配任务足够
需要很实时的系统还是不要用RTOS的
C51这类资源少的单片机还是用Keil RTX这类小型RTOS足够了
自己弄也可以,但也是越精简越好的
偶就弄有AVR的RTOS用着还OK
需要很实时的系统还是不要用RTOS的
C51这类资源少的单片机还是用Keil RTX这类小型RTOS足够了
自己弄也可以,但也是越精简越好的
偶就弄有AVR的RTOS用着还OK
#31
mark
#32
汇编虽然是在项目当中用得少了,不过对于搞嵌入式的人来说,是不可或缺的知识吧!再顶一下楼主!!
#33
学习
#34
这个嘛,让我再想想
#35
顶
#36
貌似很高深的问题
#37
lihai a
#38
支持LZ
谢谢
谢谢
#39
支持
#40
路过
#41
我们现在正在学单片机,不难吧?
#42
我们现在正在学单片机,不难吧?
#43
路过
#44
学习
顶一下
顶一下
#45
你可以想法把堆栈写到片外内存,这个压力就没有了。
SpAddl equ 08h
SpAddh equ 09h
dplbak equ 0ah
dphbak equ 0bh
main:
mov sp,#40h
mov a,r0
call PushReg
call PopReg
mov r1,a
sjmp $
PushReg:
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
movx @dptr,a ;a 保存要压栈数据
inc dptr
mov SpAddl ,dpl
mov SpAddh ,dph
mov dpl,dplbak
mov dph,dphbak
ret
PopReg:
push psw
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
dec dplbak
jnc PopReg1
dec dphbak
PopReg1:
movx a,@dptr ;a 保存要弹栈数据
mov dpl,dplbak
mov dph,dphbak
pop psw
ret
SpAddl equ 08h
SpAddh equ 09h
dplbak equ 0ah
dphbak equ 0bh
main:
mov sp,#40h
mov a,r0
call PushReg
call PopReg
mov r1,a
sjmp $
PushReg:
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
movx @dptr,a ;a 保存要压栈数据
inc dptr
mov SpAddl ,dpl
mov SpAddh ,dph
mov dpl,dplbak
mov dph,dphbak
ret
PopReg:
push psw
mov dplbak,dpl
mov dphbak,dph
mov dpl, SpAddl
mov dph,SpAddh
dec dplbak
jnc PopReg1
dec dphbak
PopReg1:
movx a,@dptr ;a 保存要弹栈数据
mov dpl,dplbak
mov dph,dphbak
pop psw
ret
#46
我觉得这并不仅仅是一个内外RAM的问题,51实现大容量的堆栈是有点难度的,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
#47
我觉得这并不仅仅是一个内外RAM的问题,51实现大容量的堆栈是有点难度的,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
#48
我觉得这并不仅仅是一个内外RAM的问题,51实现大容量的堆栈是有点难度的,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
但这仅仅是一个过程,现在要做的工作应该是如何在有限的空间内,
把各种的资源分配给系统与用户,这才是主要的,
对于以后的嵌入式来说,RAM的问题可以得到比较好的解决,
所以问题的重点是在于分配资源的过程,任务的选择,
#49
大家好!以后得请大家多多指教!