myOS51
所属分类:处理器开发
开发工具:C/C++
文件大小:91KB
下载次数:6
上传日期:2010-10-03 03:31:57
上 传 者:
zhenghw
说明: 本多年前,使用C8051F120,模仿small rtos, uCOS,DIY自己一个微型操作系统,一是学习,二时可以随意地裁剪成可以达到自己的功能的并且最小的一个操作系统.
(Keil C, C8051F120, small rtos, uCOS,DIY,My51Os,MyOs51)
文件列表:
doc\C51.doc (65536, 2010-10-03)
doc\TaskInt_bak.txt (3234, 2005-11-21)
doc\堆栈示意图.txt (5734, 2008-11-11)
inc\C8051F120.INC (17413, 2005-10-21)
inc\includes.inc (749, 2010-10-03)
inc\OS_Cfg.INC (979, 2010-10-03)
inc\OS_CPU.inc (571, 2010-10-03)
inc\OS_Decl.inc (642, 2010-10-03)
inc\OS_Def.inc (8850, 2010-10-03)
inc\OS_Sem.inc (3179, 2010-10-03)
inc\OS_Sig.inc (563, 2010-10-03)
inc\OS_Stack.inc (1852, 2010-10-03)
inc\OS_Sys.inc (608, 2010-10-03)
inc\OS_Task.inc (7055, 2010-10-03)
inc\OS_Test.INC (2209, 2010-10-03)
inc\OS_Time.inc (3848, 2010-10-03)
inc\OS_Var.inc (2259, 2010-10-03)
inc\proSerial.inc (1061, 2010-10-03)
inc\proTask1.inc (627, 2010-10-03)
inc\proUtilityMacro.inc (4617, 2010-10-03)
inc\proUtilMacr.inc (5331, 2010-10-03)
src\OS_CPU.asm (5469, 2010-10-03)
src\OS_Sem.asm (10001, 2010-10-03)
src\OS_Sig.asm (2543, 2010-10-03)
src\OS_Stack.asm (1685, 2010-10-03)
src\OS_Sys.asm (2850, 2010-10-03)
src\OS_Task.asm (14386, 2010-10-03)
src\OS_Time.asm (5528, 2010-10-03)
src\OS_Var.asm (3475, 2010-10-03)
src\proInitDevice.asm (1038, 2006-03-27)
src\proMain.asm (1752, 2010-10-03)
src\proSerial.asm (4456, 2010-10-03)
src\proTask1.asm (2059, 2010-10-03)
src\proVectTable.asm (2664, 2010-10-03)
clear.bat (326, 2005-10-19)
clearTmp.bat (53, 2005-10-21)
mRTOSDemo.m51 (58056, 2005-11-10)
mRTOSDemo.Opt (6755, 2004-06-02)
mRTOSDemo.plg (16494, 2005-11-10)
mRTOSDemo.Uv2 (3503, 2006-03-28)
... ...
;------------------------------------------------------------------------------
; Micro OS(51)
; The Real-Time Kernel(For Keil 51)
; (c) Copyright 2005-2006, zhenghw
; All Rights Reserved
; V0.0.1
;------------------------------------------------------------------------------
; 开发环境:
; 1.目标板: C8051F120学习板,U-EC2编程器
; 2.编程操作系统:Win2000
; 3.开发工具:Silicon Laboratories IDE, Silicon Configration Wizard 2
中断页码: 140/314
指令集: 113/314
Mem: 117/314
SFR: 131/314
//-----------------------------------------------------------------------------------
; 函数名以_的头,是了为让C语言可以调用。
; 在汇编语言内,在用宏包含以_开头的函数,遵循汇编程序的规范格式
; 对系统变量,遵循汇编程序的规范,外部C语言并可读,但对需要的留接口函数
目的是:
学习C8051F120单片编程
//-----------------------------------------------------------------------------------
关于函数参数使用风格说明
; 为了方便函数间的调用,减少文件大小,
;
; 输入参数,以及函数返回值:
; 单字节参数:使用 A 传递
; 双字节参数:使用 A,B 传递
; 四字节,R7R6R5R4, R3R2R1R0
; 单字节指针参数:使用 R0 传递,在IData,PData区
; 双字节指针参数:使用 R0,R1 传递,在IData,PData区
; 双字节指针参数:使用 DPTR,关于是取XData区,还是取Code区,有C决定
; 对于多参数,剩下的参数使用顺序以次为R7到R0,
; 单字节,以后的参数可为R7,R6,R5,R4,R3.R2,R1,R0
; 双字节,R7R6, R5R4, R3R2, R1R0
; 四字节,R7R6R5R4, R3R2R1R0
; 单字节指针参数:使用 R0 传递,在IData,PData区
; 双字节指针参数:使用 R0,R1 传递,在IData,PData区
; 双字节指针参数:使用 DPTR,关于是取XData区,还是取Code区,有C决定
//-----------------------------------------------------------------------------------
关于读取与设置PC,
是通过lcall调用而入栈的,然后jmp去处理堆栈切换,
用ret,设置PC值
关于堆栈:
任务的堆栈位置固定,大小可以设置,
以栈底可以设置在外部内存XDATA的最高位置,从上到下以次为任务0,1,2,3....
系统堆栈为共用,起始位置为所以变量定义后最后一个位置IDATA
在调用 OSTaskSchedule时,先保存寄存器环境,以不改变调用它的外部函数使用的存器
这样外部函数还可以使用A,B,Rn .不过,当需要切换任务时,才用到A,R0,R7,PSW(C),
所以没有必要一开始就全入栈,可以先部份入栈,以省几个时钟,不过暂时先全保存.
| |
Task_X_Top -->+-------+ <--.
| | | 长度 | |
SP-->+-------+ <<----------------------->> |-------| |长
|切换时 | |切换时 | |度
|保存的 | |保存的 | |
|寄存器 | |寄存器 | |
| | | | |
SP-->+-------+ |-------| |
| | | | |
| 任务 | | 任务 | |
| 已用 | | 已用 | |
| 堆栈 | | 堆栈 | |
| | | | |
STACK-->|-------| <<------------------------>> |-------| <--.
| 变量区| | |
| | | |
| |
| |
| |
+-------+< StackBottom
| |
| |
| | Task0Size
| |
|-------+<-Task0SP
| | 堆栈使用情况
| | ..
| | Task1Size ..
| | | .. |
|-------+<-Task1SP |-----|
| | | PSW |
| | | DPL |
| | Task2Size | DPH |
| | | B |
|-------+<-Task2SP | ACC |
| | | PCH |
| | Task3Size | PCL |
| | +-----+
|-------+<-Task3SP
| |
2006-3-3
原操作系统想做一个只4任务的操作系统,但4个实在没有什么意义
再则现在单片都有XRAM,如果函数没有重入性,多任务也没法调用,要对
函数临时变量的保护,就要入栈,一般内部RAM太少,太受限了.
现在做操作系统任务的个数不受限制.自定义堆栈大小,堆栈使用外
XRAM. 功能防Tiny51,有延时和发信号,等待信号功能
对任务的状态等标志变量,放在内部RAM中.
系统控制需要保存的数据是
1.任务状态.
任务状态使用一个8位字节数组保存,方便查找
2.任务节拍计时器.
计时器,加1,溢出到0时为溢出.使用8位或16位数据保存.
其中Timer0或Timer1中的中断中调用,
关于任务堆栈,保存在XData中,所以可以做重入函数.
需要配置用户任务堆栈的栈顶位置,及每个任务的堆栈大小.
任务大小数值不要跳跃,要按大小顺序.
需要定义的常量有
任务个数
用户任务堆栈的栈顶位置,
每个任务的堆栈大小, 为数组,在XCode区
需要定义的变量有
任务状态[任务个数]
任务计数器[任务个数]
当前工作任务号
系统任务状态:1个任务用1个字节,
OS_TCB_STATE
+-----------------------+
| 状态 |
+-----------------------+
+-----------------------+
+-----------------------+
+-----------------------+
.................
7 6 5 4 3 2 1 0
+--+--+--+--+--+--+--+--+
| | | | | | | | | 1 / 0
+--+--+--+--+--+--+--+--+ | |
| | | V V
| | +---: 创建/未创建 删除 睡眠 B_ACTIVE EQU 5
| +------: 就绪/未就绪 B_READY EQU 4
+---------: 运行/挂起 等待
其它的用于以后拓展
OS_TCB_TIMER
+-----------------------+
| 任务延时计数 |
+-----------------------+
+-----------------------+
+-----------------------+
+-----------------------+
.................
; byte mask definitions
K_SIG EQU 1
K_TMO EQU 2
SIG_EVENT EQU 4
TMO_EVENT EQU 8
K_READY EQU 16
K_ACTIVE EQU 32
K_ROBIN EQU ***
K_IVL EQU 128 ; not a task state bit; only used in os_wait
RDY_EVENT EQU 128 ; READY status flag
K_RDY EQU 128 ; READY status flag
; bit position definitions
B_WAITSIG EQU 0
B_WAITTIM EQU 1
B_SIGNAL EQU 2
B_TIMEOUT EQU 3
B_READY EQU 4
B_ACTIVE EQU 5
B_ROBIN EQU 6
B_IVL EQU 7 ; not a task state bit; only used in os_wait
B_RDY EQU 7 ; READY status flag
1.关于延时功能实现
在Timer0或Timer1中的中断中调用
当任务状态有计时器标志时,
在该任务计数器中加1,
当加到溢出到0时,算定时到
则设置任务就绪
(调用任务切换)
Delay(uint nTicks)
2.关于等待发送信号
char Send(uint nTaskID):发送信号:
设置nTaskID任务就绪
切换任务
返回值: NOT_OK,-1,0XFFH:为任务号不存在
OK,0:信号发送成功
char Wait(uint nTicks):等待信号,其用到延迟功能:
设置自己挂起,
nTicks为等待本任务的信号的最延迟时间,
当时间溢出时,就自动把自己设为就绪
当nTicks = 0 时,就一直等待信号.没有超时设置.
切换任务
返回值: SIG_EVENT:等待到了一个信号
TMO_EVENT:等待到了时钟溢出
NOT_OK: 错误
功能模块设计:
1. 模块:
project name(项目名称)
--bin 执行文件
ぁ--log 日志文件
--lib 库文件:引用的公共库文件
--inc 头文件:inc、mac、cfg等头文件
--src 源程序:asm主程序,函数库文件
--tmp 编译中间文件
--dat 数据文件
--doc 相关文档资料文件
--readme.txt 自述文件,目录、文件说明
;------------------------------------------------------------------------------
; 宏定义名:
;-----------------------------------------------------------------------------
; 功能:
; 堆栈:
; 资源:
; 返回: 无
; 输入: 无
; 输出: 无
; 描述:
;-----------------------------------------------------------------------------
;------------------------------------------------------------------------------
; 函数名:
;-----------------------------------------------------------------------------
; 功能:
; 堆栈:
; 资源:
; 返回: 无
; 输入: 无
; 输出: 无
; 描述:
;-----------------------------------------------------------------------------
所有任务使用公用系统堆栈,
而任务堆栈区,只是为了保证函数的重入性,以及能保存原来的程序位置
对主动调用函数,只需保存:PCL,PCH,PSW,SP ,以及能保存原来的程序位置
对中断函数,要保存以上4个字节外,还要保存A,B,DPL,DPH,还有R0---R7
对于4个基本任务使用寄存器组,所以不用保存R0--R7,
对于某个任务可以指定存器组,可以指定不用,即ENUM_REG_BLANK_NOTHING EQU 4
2005-11-17:
1.在中断中保存全部寄存器变量PCL,PCH, A,B,DPL,DPH,还有R0---R7,PSW
在中断中不可切换任务,不可等待信号,但可以发信号,不会切换任务
在中断中可以使用除0外1.2.3寄存器组,这样可以不保存R0--R7了,
返回来时一定要换回来,不过由最先PSW弹回,就自动返回了,
而0组由系统任务使用
2.由于全是主动切换,所以任务切换时,只需保存PCL,PCH
3.现在函数不具有重入性,中断不可剥夺,
以后可以考虑,函数中可以定义局部变量,在堆栈中.SP -X
OSTaskIntEnter:
关中断
OSIntNesting++
if (OSIntNesting == 1 )
{ 保存:A,B,DPL,DPH
保存:R0---R7:如果需要
保存:PCL,PCH,PSW,SP
}
清中断,(若许重入)
开中断
ret
中间为用户的ISR程序
OSTaskIntExit:
关中断
恢复变量
if (OSIntNesting > 0 )
{
OSIntNesting --
}
if (OSIntNesting == 0 && OSLockNesting == 0)
{
查找是否有更改优先级
OSIntCtxSw()
}
开中断
ret
执行中断返回指令RETI
;---------------------------------------------
在中断结束时,才查找下一个是否有更高优选级的程序,
有则切换,=》1.保存堆栈,2.并加标记为中断中切换任务标志。3.恢复另一个任务的堆栈,4.RETI切换
否则可以直接返回了。
在任务恢复时,如检查到该任务是在中断中切换的,则恢复更多的寄存器,恢复后,可以清掉标志了。
; 在任务切换前后不能有压栈出栈,,因为任务切换只保存PC值,
; 所以压栈的寄存器变量可能恢复不回来,
; 关于,这个问题,之后可以把堆栈保存在片外XRAM中
; 由于不能在中断中调用,所以只设置状态,之后在空闲任务调度
;===========================================================
/*
; 1.取当前运行任务堆栈区 栈顶,到R0
mov A, OS_nCurrTaskID
mov DPTR,#TBL_TASK_SPTOP
movc A,@A+DPTR ; 当前运行任务堆栈区 栈顶
mov R0, A
; 2. R1 <= sp- 4 调用处OSTaskCtxCW的PC值 SP - 2
mov A, SP ; A <= SP - #5
subb A, #5
mov R1, A
; 3. 保存到 当前运行任务堆栈
mov A, @R1 ; MemCurrTask <= SP - #5
mov @R0, A
inc R0 ; MemCurrTask+1 <= SP - #5 +1
inc R1
mov A, @R1
mov @R0, A
/* inc R0
mov @R0, PSW ; PSW; 保存寄存器组,
; 如果在中断中运行 并且 不是休闲任务#OS_MAX_TASKS
;OS_mcrGetTcb OS_nCurrTaskID, R1
OS_mcrGetTcb OS_nCurrTaskID
anl A, #ENUM_TASK_STATE_INTRUNNING
jnz lblOSTaskCtxCW_LoadNextTask
mov A, OS_nCurrTaskID
SUBB A, #OS_MAX_TASKS
jz lblOSTaskCtxCW_LoadNextTask
; {
inc R0
mov @R0, A ;
inc R0
mov @R0, B ;
inc R0
mov @R0, DPL ;
inc R0
mov @R0, DPH ;
; }
*/
lblOSTaskCtxCW_LoadNextTask:
; 4.取下一个要运行任务堆栈区 栈顶,到R0
mov A, OS_nNextTaskID
mov DPTR,#TBL_TASK_SPTOP
movc A,@A+DPTR ; 当前运行任务堆栈区 栈顶
mov R0, A
; 5.恢复 下一个要运行任务堆栈
mov B, @R0 ; B <= MemNextTask_SP
inc R0
mov A, @R0 ; A <= MemNextTask_SP + 1
mov @R1, A ; SP - #4 +1 <= MemNextTask_SP + 1
dec R1
mov @R1, B ; SP - #4 <= MemNextTask_SP
/*
inc R0
mov PSW, @R0 ; PSW; 改变寄存器组,
; 如果在中断中运行 并且 不是休闲任务#OS_MAX_TASKS
;???????????判断任务状态,此处不对??????????????????
OS_mcrGetTcb OS_nNextTaskID
anl A, #ENUM_TASK_STATE_INTRUNNING
jnz lblOSTaskCtxCW_LoadNextTask
mov A, OS_nNextTaskID
SUBB A, #OS_MAX_TASKS
jz lblOSTaskCtxCW_ChangTaskID
; {
inc R0
mov A, @R0
inc R0
mov B, @R0 ;
inc R0
mov DPL, @R0;
inc R0
mov DPH, @R0;
; }
*/
lblOSTaskCtxCW_ChangTaskID:
; 5. 更改当前运行任务ID,OK
mov OS_nCurrTaskID, OS_nNextTaskID
;endof OSTaskCtxCW
*/
近期下载者:
相关文件:
收藏者: