amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 18605|回复: 128

感谢Lisuwei<简易多任务OS设计>一文,我也写出了我的RaysRTOS(光芒实

[复制链接]
发表于 2010-7-12 10:53:27 | 显示全部楼层 |阅读模式
首先上51版本
keil3编译版本,89c52单片机运行,仿真proteus7.5sp3ourdev_567245VTCPKX.rar(文件大小:59K) (原文件名:RaysRTOS-89C52keil.rar)

由于是优先级抢占式调度,建立了两个任务,占用ram稍微较大,flash占用还可以,占用情况如下:
Program Size: data=92.0 xdata=0 code=950
下面是系统函数声明
/*--------------------------------------------------------------------------------------+
|系统函数声明                                                           |
+---------------------------------------------------------------------------------------*/
void RAYS_TaskCreate(void (*Task)(void),INT8U *Stack,INT8U t_Prio);//创建任务
void RAYS_Start(void);                        //系统启动函数
void RAYS_TaskResume(INT8U prio);                 //任务恢复函数
void RAYS_TaskSuspend(INT8U prio);                //任务挂起函数
void OSSched(void);                                //汇编调度函数
void RAYS_TimeDelay(INT16U ticks);                 //任务延时函数
void Idle_Task(void);
void RAYS_Init(void);                                //系统初始化
void TickIntHook(void);                         //系统节拍钩子函数



再上avr版本
用winavr20060421编译,ide选择的是Eclipse,也可以用winavr编译,仿真同样是proteus7.5sp3,调度在16兆只用10us(avrstudio软测)ourdev_567246HOADLD.rar(文件大小:47K) (原文件名:RaysRTOS-Eclipse.rar)
单片机型号分别测试了mega128 和mega8,都可以运行,但程序如果大于64k的话调度部分pc需要改动一下
由于是优先级抢占式调度,建立了3个任务,占用情况如下:

Program:    1178 bytes (14.4% Full)
(.text + .data + .bootloader)

Data:        225 bytes (22.0% Full)
(.data + .bss + .noinit)
默认优先级0s
/*--------------------------------------------------------------------------------------+
|系统函数声明                                                           |
+---------------------------------------------------------------------------------------*/
void RAYS_TaskCreate(void (*Task)(void),INT8U *Stack,INT8U t_Prio);//创建任务
void RAYS_Start(void);                        //系统启动函数
void RAYS_TaskResume(INT8U prio);                 //任务恢复函数
void RAYS_TaskSuspend(INT8U prio);                //任务挂起函数
void OSSched(void);                                //汇编调度函数
void RAYS_TimeDelay(INT16U ticks);                 //任务延时函数
void Idle_Task(void);
void RAYS_Init(void);                                //系统初始化
void TickIntHook(void);                         //系统节拍钩子函数

最后来stm8s105c6版本,本人手上只有这个小小的discovery板子,100块买的,所以先拿它做的测试,很稳定!

(原文件名:未命名.JPG)
编译器选择的是IAR,因为它里边支持c语言是用的模拟寄存器!!!!stvd好像用的是堆栈,导致在stvd上做系统几乎不可能
stm8工程,是stm8s105c6版本,仿真是硬件仿真,因为proteus不支持stm8:(ourdev_567253FKWHEQ.rar(文件大小:44K) (原文件名:RaysRTOS-STM8IAR.rar)
flash和ram占用情况如下:
  941 bytes of readonly  code memory
  132 bytes of readonly  data memory
  499 bytes of readwrite data memory
我感觉ram占用有点大,后来我编写了个什么都没有的main函数,ram占用是272B,所以本系统ram占用应该是499-272=227B
优化级别选则balance.
/*--------------------------------------------------------------------------------------+
|系统函数声明                                                           |
+---------------------------------------------------------------------------------------*/
void RAYS_TaskCreate(void (*Task)(void),INT8U *Stack,INT8U t_Prio);//创建任务
void RAYS_Start(void);                                //系统启动函数
void RAYS_TaskResume(INT8U prio);                 //任务恢复函数
void RAYS_TaskSuspend(INT8U prio);                //任务挂起函数
void OSSched(void);                                //汇编调度函数
void RAYS_TimeDelay(INT16U ticks);                 //任务延时函数
void Idle_Task(void);
void RAYS_Init(void);                                //系统初始化
void TickIntHook(void);                         //系统节拍钩子函数


欢迎大家测试,我是新手,难免有很多bug,三种版本90%代码都一样,与cpu最相关的RaysRTOS_ASM文件差异较大,不过格式也一样.
我的qq 771992497
最后还想来个版本,就是lisuwei的那个版本的修改版,2440平台,因为它的那个版本没有初始化mmu,所以导致只能在nor里运行,这个修改版是在ram或者nand里边运行的,和正常的2440_test什么的程序一样,通过boot下载到nand 0x000地址或者ram的0x30000000地址都可以运行!!!
考虑到开发2440习惯,有人熟悉ads,有人喜欢keil4,所以我修改成了两个版本,都可以跑,希望大家测试
ads1.2版本工程ourdev_567269TVNLE3.rar(文件大小:51K) (原文件名:SIMPLE_2440.rar)
keil4版本工程ourdev_567270UBQ2B1.rar(文件大小:324K) (原文件名:SIMPLE_2440_RV.rar)


最后再感谢lisuwei把我带入rtos大门,还要感谢上官兄,没他的代码我不会stm8汇编
发表于 2010-7-12 11:00:55 | 显示全部楼层
沙发,置COOL前留爪印
发表于 2010-7-12 11:02:26 | 显示全部楼层
支持
发表于 2010-7-12 11:15:54 | 显示全部楼层
mark
发表于 2010-7-12 12:46:45 | 显示全部楼层
mark
发表于 2010-7-12 13:11:44 | 显示全部楼层
good
发表于 2010-7-12 13:24:01 | 显示全部楼层
mark
发表于 2010-7-12 13:55:12 | 显示全部楼层
学习
发表于 2010-7-12 14:50:51 | 显示全部楼层
good
发表于 2010-7-12 14:56:37 | 显示全部楼层
cool
发表于 2010-7-12 16:53:58 | 显示全部楼层
牛叉!晚上回去加你。
 楼主| 发表于 2010-7-12 17:24:18 | 显示全部楼层
大家测试过程中出现什么bug或者不稳定情况,请及时反馈给我.(*^__^*) 嘻嘻……
我想先把内核跑好了再做任务间通信的东东.
还希望莫大给条"裤子"

有些人编写avr喜欢用avrstudio,我修改了studio的版本,用avrstudio的编译mega88上的,并带有ptoteus7.5sp3仿真文件
点击此处下载 ourdev_567367SIPKCM.rar(文件大小:35K) (原文件名:RaysRTOS-avrstudioMega88.rar)
发表于 2010-7-12 17:45:15 | 显示全部楼层
先顶帖子再说!~
发表于 2010-7-12 18:15:53 | 显示全部楼层
先顶再猫咳
发表于 2010-7-12 19:01:02 | 显示全部楼层
mark
发表于 2010-7-12 21:35:20 | 显示全部楼层
这样的是该加酷了
发表于 2010-7-12 22:00:11 | 显示全部楼层
还不错
 楼主| 发表于 2010-7-13 08:38:22 | 显示全部楼层
自己顶一下
大家还有什么性价比高的单片机推荐,我可以做移植,我手头只有这三种单片机.
其实写出来之后才知道操作系统也不难:)
发表于 2010-7-13 11:46:55 | 显示全部楼层
mark!~~
发表于 2010-7-14 11:31:38 | 显示全部楼层
看起来不错,学习一下
发表于 2010-7-14 12:23:12 | 显示全部楼层
nicie :)
 楼主| 发表于 2010-7-19 10:21:23 | 显示全部楼层
自己顶!!!!!!!!!!!
发表于 2010-7-19 10:25:46 | 显示全部楼层
帮顶,呵呵,谁说我们学校不出强人
发表于 2010-7-19 14:16:02 | 显示全部楼层
mk
发表于 2010-7-21 16:19:03 | 显示全部楼层
非常不错
发表于 2010-7-24 00:28:32 | 显示全部楼层
MARK
 楼主| 发表于 2010-7-24 11:47:01 | 显示全部楼层
希望都帮我顶起来啊,我这边抓紧测试系统稳定性以及调度时间
发表于 2010-7-24 15:40:39 | 显示全部楼层
mark
 楼主| 发表于 2010-8-14 14:40:12 | 显示全部楼层
还有哪款单片机用途广泛?考虑移植一下
发表于 2010-8-14 14:51:35 | 显示全部楼层
freescale 用途是很多的  楼主可以考虑下
发表于 2010-8-14 15:05:31 | 显示全部楼层
MARK
发表于 2010-8-14 15:36:48 | 显示全部楼层
MARK!
发表于 2010-8-18 17:05:34 | 显示全部楼层
MARK
发表于 2010-8-21 09:48:35 | 显示全部楼层
mark
发表于 2010-8-21 09:52:03 | 显示全部楼层
感谢LZ ,
发表于 2010-8-21 09:54:49 | 显示全部楼层
说实话,你这个简单的OS和uCOSII思路差不多,基本上就是一个简化版本。
发表于 2010-8-21 09:56:56 | 显示全部楼层
牛人啊,顶一火
发表于 2010-8-21 17:23:27 | 显示全部楼层
发表于 2010-8-21 20:10:16 | 显示全部楼层
路过顶帖!
发表于 2010-8-21 20:13:56 | 显示全部楼层
好东西 利害
发表于 2010-8-21 22:01:22 | 显示全部楼层
这是我们学校的牛人,顶顶顶
发表于 2010-8-22 00:06:20 | 显示全部楼层
mark
发表于 2010-8-22 07:39:18 | 显示全部楼层
mark
发表于 2010-8-22 11:05:18 | 显示全部楼层
学习了。
发表于 2010-8-22 13:22:11 | 显示全部楼层
MARK
发表于 2010-8-22 13:37:15 | 显示全部楼层
下载 玩玩~~~
发表于 2010-8-30 21:44:03 | 显示全部楼层
下载试试~~
发表于 2010-9-3 07:08:18 | 显示全部楼层
mark
发表于 2010-9-4 08:46:39 | 显示全部楼层
mark
发表于 2010-9-21 17:37:58 | 显示全部楼层
修改了一下,同时开启16个任务,效果不错
 楼主| 发表于 2010-9-22 08:20:03 | 显示全部楼层
回复【49楼】wmm20031015
-----------------------------------------------------------------------
我正想办法添加堆栈统计功能
发表于 2010-9-22 10:39:13 | 显示全部楼层
mark
发表于 2010-9-24 11:16:13 | 显示全部楼层
期待楼主的改进,使用堆栈统计,进行动态分配
发表于 2010-9-24 13:54:39 | 显示全部楼层
Cool!
发表于 2010-9-25 13:00:58 | 显示全部楼层
同mask~!
发表于 2010-11-11 14:17:52 | 显示全部楼层
Mark!
发表于 2010-11-27 18:51:23 | 显示全部楼层
mark
发表于 2011-4-21 19:17:41 | 显示全部楼层
mark
发表于 2011-4-26 13:57:43 | 显示全部楼层
mark!
发表于 2011-4-28 18:35:53 | 显示全部楼层
好好
发表于 2011-4-28 19:16:34 | 显示全部楼层
mark!!!!!
发表于 2011-4-28 20:12:56 | 显示全部楼层
留爪印
发表于 2011-4-28 20:51:10 | 显示全部楼层
标记一下,以后有用
发表于 2011-5-5 15:20:50 | 显示全部楼层
发表于 2011-6-24 15:34:18 | 显示全部楼层
感谢分享!!!
发表于 2011-6-24 17:22:37 | 显示全部楼层
MARK  牛人
发表于 2011-7-11 16:09:00 | 显示全部楼层
呵呵,只有这个OS内核才能看懂,谢谢!
发表于 2011-7-12 13:52:31 | 显示全部楼层
下下来了,以后学习!
 楼主| 发表于 2011-7-13 11:04:20 | 显示全部楼层
回复【66楼】skype
-----------------------------------------------------------------------

看到您的回复我很欣慰,我希望有更多的人去看的懂,去完全理解,其实小型OS也不那么神秘。
小弟保证,看懂之后,单片机知识狂涨一大截!
发表于 2011-7-13 12:42:16 | 显示全部楼层
mark
发表于 2011-7-13 20:07:49 | 显示全部楼层
回复【68楼】avr-arm 光芒电子
回复【66楼】skype  
-----------------------------------------------------------------------
看到您的回复我很欣慰,我希望有更多的人去看的懂,去完全理解,其实小型os也不那么神秘。
小弟保证,看懂之后,单片机知识狂涨一大截!
-----------------------------------------------------------------------

昨天晚上看到2点才睡,才正真看懂。
今天上班后找了51单片机的书,重点看了PC、堆栈、SP、子程序调用及RET/RETI。
有了这些基础,才能看明白你的这个OS.
发表于 2011-7-13 20:12:54 | 显示全部楼层
好东西,顶
发表于 2011-7-27 13:26:18 | 显示全部楼层
mark
发表于 2011-8-2 13:39:06 | 显示全部楼层
收藏学习
发表于 2011-8-2 16:28:43 | 显示全部楼层
记号
发表于 2011-8-4 09:46:58 | 显示全部楼层
MARK  牛人
发表于 2011-8-4 10:37:22 | 显示全部楼层
呵呵,在LZ的基础上加了一点东西,并在CPU_ASM.ASM文件中做了注释。
LZ可以把系统做完善些,也让我们这些菜鸟学习学习。
/*--------------------------------------------------------------------------------------+
|任务结构体TCB                                                                          |
+---------------------------------------------------------------------------------------*/
struct TaskCtrBlock                                                                     // 任务控制块数据结构
{
        INT8U        OSTCBStkTop;                                                                 // 保存任务的堆栈底
        INT8U        OSTCBStkBom;                                                                 // 保存任务的堆栈顶
    INT8U        OSTCBStkLen;                                                                // 数据在人工任务堆栈的长度
        INT16U        OSTCBDly;                                                                         // 任务延时时钟
};//单个结构占5个字节空间

/*
+---------------------------------------------------------------------------------------+
|函数名称:  OS_TaskCreate                                                                            |
|---------------------------------------------------------------------------------------|
|函数功能:  建立任务                                                                    |
|入口参数:  *Task:任务函数地址;*Stack:任务栈顶指针;Prio:任务优先级                  |
+---------------------------------------------------------------------------------------+
*/
void  OS_TaskCreate(void (*p_Task)(void), INT8U *p_Stack, INT8U t_Prio)
{
        TCB[t_Prio].OSTCBStkTop = TCB[t_Prio].OSTCBStkBom = (INT8U)p_Stack;        //获取任务堆栈地址
        *(  p_Stack) = (unsigned int)p_Task & 0xff;        // 函数入口
        *(++p_Stack) = (unsigned int)p_Task>>8;            // 函数入口
        *(++p_Stack) = 0;//ACC   
        *(++p_Stack) = 0;//B   
        *(++p_Stack) = 0;//DPH   
        *(++p_Stack) = 0;//DPL   
        *(++p_Stack) = 0;//PSW   
        *(++p_Stack) = 0;//R0                  
        *(++p_Stack) = 1;//R1   
        *(++p_Stack) = 2;//R2   
        *(++p_Stack) = 3;//R3   
        *(++p_Stack) = 4;//R4   
        *(++p_Stack) = 5;//R5   
        *(++p_Stack) = 6;//R6
        *(++p_Stack) = 7;//R7                                                                                  // 除pc外保存13个寄存器                                      
        TCB[t_Prio].OSTCBStkTop = (INT8U)p_Stack;                                        // 将人工堆栈的栈顶地址,保存到堆栈的数组中
        TCB[t_Prio].OSTCBStkLen = TCB[t_Prio].OSTCBStkTop - TCB[t_Prio].OSTCBStkBom;
        TCB[t_Prio].OSTCBDly = 0;                                                                          // 初始化任务延时
        OSSetPrioRdy(t_Prio);                                                                                // 在任务就绪表中登记,OSRdyTbl对应位为1,同时确定了任务的优先级
}


//
; /*****************************************************************************************  
;  *  8051 CPU相关ASM文件
;  *
;  *  Copyright (C) 2010  苑臣芒
;  *
;  *  2010-07-09  RaysRTOS
;  *****************************************************************************************/
$NOMOD51
#include "REG52.INC"

NAME        CPU_ASM


?PR?OSSched?CPU_ASM    SEGMENT CODE
?PR?Timer0ISR?CPU_ASM  SEGMENT CODE

        EXTRN        CODE (TickIntHook)
        EXTRN        DATA (TCB)
        EXTRN        DATA (OSPrioCur)
        EXTRN        DATA (OSPrioHighRdy)

        EXTRN        DATA (OSTICK_R)

        PUBLIC        Timer0ISR
        PUBLIC        OSSched

        RSEG  ?PR?OSSched?CPU_ASM
OSSched:
        CLR          EA
        MOV          A,OSPrioHighRdy
        XRL          A,OSPrioCur
        JZ           ?C0001
         PUSH ACC        
         PUSH B
         PUSH DPH
         PUSH DPL
         PUSH PSW
         USING        0
         PUSH AR0             
         PUSH AR1
         PUSH AR2
         PUSH AR3
         PUSH AR4
         PUSH AR5
         PUSH AR6   
         PUSH AR7   
        ;人工栈顶
        MOV          A,OSPrioCur
        MOV          B,#05H                ;此处何值看单个结构体TCB所点的空间
        MUL          AB
        ADD          A,#LOW (TCB)        ;获取栈顶地址
        MOV          R0,A
        MOV          @R0,SP
        ;获取栈底地址
        INC        A
        MOV        R0,A
        ;获取栈长度存储器地址
        INC        A
        MOV        R1,A
        ;本次入栈了多少个字节,即栈的深度
        MOV        A,SP
        SUBB        A,@R0
        MOV        @R1,A                ;写入栈深度


        MOV          OSPrioCur,OSPrioHighRdy

        MOV          A,OSPrioCur
        MOV          B,#05H                ;此处何值看单个结构体TCB所点的空间
        MUL          AB
        ADD          A,#LOW (TCB)
        MOV          R0,A
        MOV          A,@R0
        MOV          SP,A
         POP AR7
         POP AR6
         POP AR5
         POP AR4
         POP AR3
         POP AR2
         POP AR1
         POP AR0
         POP PSW
         POP DPL
         POP DPH
         POP B
         POP ACC
?C0001:
        SETB         EA
        RET




; /*
; +---------------------------------------------------------------------------------------+
; |函数名称:        Timer0ISR                                                                                                                                        |
; |---------------------------------------------------------------------------------------|
; |函数原型:        void Timer0ISR(prio)                                                                                                                |
; |                                                                                                                                                                                |
; |函数功能:        中断级切换函数                                                                                                                                    |                                                                                                                                                                                |
; +---------------------------------------------------------------------------------------+
; */

CSEG        AT        0000BH
        LJMP        Timer0ISR

        RSEG  ?PR?Timer0ISR?CPU_ASM
        USING        0
Timer0ISR:
        CLR          EA
        MOV          TH0,OSTICK_R
        PUSH         ACC
        PUSH         B
        PUSH         DPH
        PUSH         DPL
        PUSH         PSW

        USING        0
        MOV          PSW,#00H
         PUSH AR0             
         PUSH AR1
         PUSH AR2
         PUSH AR3
         PUSH AR4
         PUSH AR5
         PUSH AR6   
         PUSH AR7          
        LCALL        TickIntHook
        ;人工栈顶
        MOV          A,OSPrioCur
        MOV          B,#05H                        ;此处何值看单个结构体TCB所点的空间
        MUL          AB
        ADD          A,#LOW (TCB)                ;获取栈顶地址
        MOV          R0,A
        MOV          @R0,SP                        ;存SP地址
        ;获取栈底地址
        INC        A
        MOV        R0,A
        ;获取栈长度存储器地址
        INC        A
        MOV        R1,A
        ;本次入栈了多少个字节,即栈的深度
        MOV        A,SP
        SUBB        A,@R0
        MOV        @R1,A                ;写入栈深度


        MOV          OSPrioCur,OSPrioHighRdy

        MOV          A,OSPrioCur
        MOV          B,#05H                        ;此处何值看单个结构体TCB所点的空间
        MUL          AB
        ADD          A,#LOW (TCB)
        MOV          R0,A
        MOV          A,@R0
        MOV          SP,A
;从此处到RETI返回后共出栈15个字节,
         POP AR7
         POP AR6
         POP AR5
         POP AR4
         POP AR3
         POP AR2
         POP AR1
         POP AR0
        POP          PSW
        POP          DPL
        POP          DPH
        POP          B
        POP          ACC
        SETB         EA
        RETI

        END
发表于 2011-8-4 11:12:31 | 显示全部楼层
mark!
 楼主| 发表于 2011-8-4 21:07:24 | 显示全部楼层
回复【76楼】skype
-----------------------------------------------------------------------

十分感谢,添加了栈检查功能,谢谢,我好好研究一下代码
发表于 2011-8-4 22:04:36 | 显示全部楼层

强烈支持...
发表于 2011-8-4 22:12:27 | 显示全部楼层
过来标记学习,谢谢分享~
发表于 2011-8-28 17:37:14 | 显示全部楼层
顶LZ,增加信号量

#include "Serial.h"
#include "Easy51RTOS.h"
#include "Sem.h"
INT8U  idata Task0Stack[30];
INT8U  idata Task1Stack[30];
INT8U  idata Task2Stack[30];



/************************************************************************************************************************
函数名称:        void Task0(void)
函数原型:        void Task0(void)
函数功能:        任务0
入口参数:        无
出口参数:        无
有关说明:       
创建时间:        2007年3月3日
修改时间:       
************************************************************************************************************************/
void Task0(void)
{
        INT8U i;
        OSSemCreat(0,1);        //使用共享资源
        while(1)
        {
                OSSemPend(0,0xffff);                //请求信号量
        //        OS_ENTER_CRITICAL();
                SendString("TASK0 任务在使用串口\r\n", 0);
                SendString("TASK0 任务使用了任务栈的", 0);
                i = TCB[OSPrioCur].OSTCBStkLen;
                SendCharacter(i / 10 + 0x30);
                SendCharacter(i % 10 + 0x30);
                SendString("个字节\r\n\r\n", 0);
        //        OS_EXIT_CRITICAL();
                OSSemPost(0);
                OS_TimeDelay(5);
        }
}

/************************************************************************************************************************
函数名称:        void Task1(void)
函数原型:        void Task1(void)
函数功能:        任务1
入口参数:        无
出口参数:        无
有关说明:       
创建时间:        2007年3月3日
修改时间:       
************************************************************************************************************************/
void Task1(void)
{
        INT8U i;
        while(1)
        {
                OSSemPend(0,0xffff);                //请求信号量
        //        OS_ENTER_CRITICAL();
                SendString("task1 任务在使用串口\r\n", 0);
                SendString("task1 任务使用了任务栈的", 0);
                i = TCB[OSPrioCur].OSTCBStkLen;
                SendCharacter(i / 10 + 0x30);
                SendCharacter(i % 10 + 0x30);
                SendString("个字节\r\n\r\n", 0);
        //        OS_EXIT_CRITICAL();
                OSSemPost(0);
                OS_TimeDelay(2);
        }
}

/************************************************************************************************************************
函数名称:        void Task2(void)
函数原型:        void Task2(void)
函数功能:        任务2
入口参数:        无
出口参数:        无
有关说明:       
创建时间:        2007年3月3日
修改时间:       
************************************************************************************************************************/
void Task2(void)
{
        while(1)
        {
                OS_TimeDelay(20);
        }
}
/****************主函数***************/
int main(void)
{
         OS_Init();         
         Uart_1T_INIT();
         OS_TaskCreate(Task0, Task0Stack, 0);
         OS_TaskCreate(Task1, Task1Stack, 1);
         OS_TaskCreate(Task2, Task2Stack, 2);
         OS_Start();                                                         //此函数执行完系统即发生调度
         while(1);
}


(原文件名:QQ截图未命名.jpg)
发表于 2011-8-28 17:38:15 | 显示全部楼层
/*****************************************************************************************  
*  RaysRTOS 总体头文件
*
*  Copyright (C) 2011  
*
*  2010-07-09  RaysRTOS
*****************************************************************************************/
#ifndef        _Sem_H_                //防止被重复引用
#define _Sem_H_

#include "CPU_CFG.h"
#ifndef NOT_OK
#define NOT_OK      255                                 /* 参数错误                                     */
#endif

#define OS_SEM_NOT_OK 4                                 /* 无信号                                       */
#define OS_SEM_TMO    2                                 /* 超时到                                       */
#define OS_SEM_OK     1                                 /* 操作成功                                     */
#define OS_MAX_SEMS             2           /* 最大信号量数目                                           */
//信号量
struct SemBlk
{
        INT8U OSEventType;     //型号 0,信号量独占型;1信号量共享型  
        INT8U OSTaskPendTbl;   //等待信号量的任务列表
};

extern         struct SemBlk Sem[OS_MAX_SEMS];

extern INT8U OSSemCreat(INT8U Index,INT8U Data);
extern INT8U OSSemPend(INT8U Index, INT8U Tick);
extern INT8U OSSemAccept(INT8U Index);
extern INT8U OSSemIntPost(INT8U Index);
extern INT8U OSSemPost(INT8U Index);
extern INT8U OSSemQuery(INT8U Index);
#endif
发表于 2011-8-28 17:38:49 | 显示全部楼层
#include "Easy51RTOS.h"
#include "Sem.h"

struct SemBlk Sem[OS_MAX_SEMS];

/*********************************************************************************************************
** 函数名称: OSSemCreate
** 功能描述: 初始化消息队列
** 输 入: Index:信号量索引
**         data:信号量初始值
** 输 出: NOT_OK:没有这个信号量
**         OS_SEM_OK:成功
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
INT8U OSSemCreat(INT8U Index,INT8U Data)
{
        OS_ENTER_CRITICAL();
        if (Index < OS_MAX_SEMS)
        {
                Sem[Index].OSEventType=Data;                        /* 计数器置初值 */
                Sem[Index].OSTaskPendTbl=0;                                /*初始化时任务等待列表为空*/
                OS_EXIT_CRITICAL();
                return OS_SEM_OK;
        }

        OS_EXIT_CRITICAL();
        return NOT_OK;
}


/*********************************************************************************************************
** 函数名称: OSSemPend
** 功能描述: 等待一个信号量
** 输 入: Index:信号量索引
**         Tick:等待时间
** 输 出: NOT_OK:参数错误
**         OS_SEM_OK:得到信号量
**         OS_SEM_TMO:超时到
**         OS_SEM_NOT_OK:没有得到信号量
** 全局变量: 无
** 调用模块: OSRunningTaskID,OSClearSignal,OSSched,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2002年10月20日
**-------------------------------------------------------------------------------------------------------*/
INT8U OSSemPend(INT8U Index, TICKS_TypeDef Tick)
{
    if (Index >= OS_MAX_SEMS)
    {
        return 0;
    }

        OS_ENTER_CRITICAL();
        TCB[OSPrioCur].OSTCBDly = Tick;                                        // 设置任务延时节拍数
    Sem[Index].OSTaskPendTbl |= 0x01<<OSPrioCur;        /* 把任务加入等待任务队列 */

        while (Sem[Index].OSEventType == 0)                                /* 信号量是否有效 */
        {         /* 信号量无效 */
                OSRdyTbl &= ~(0x01<<OSPrioCur);                                /*从任务就绪表中去除        */
                OSSched();                                                  /* 运行下一个任务 */
                if(TCB[OSPrioCur].OSTCBDly==0 )                        /*超时,未能拿到资源        */
                {
                        break;
                }
        }

        Sem[Index].OSTaskPendTbl &= ~(0x01<<OSPrioCur);        /*从等待表中去除                        */
        /* 判断信号量是否有效。有效,信号量计数器减一 */
        if (Sem[Index].OSEventType > 0)
        {
                Sem[Index].OSEventType--;
        OS_EXIT_CRITICAL();
        return OS_SEM_OK;
    }
    else
    {
        /* 无信号返回信号无效 */
        OS_EXIT_CRITICAL();
        return OS_SEM_TMO;
    }
}

/*********************************************************************************************************
** 函数名称: OSSemAccept
** 功能描述: 无等待请求信号量
** 输 入: Index:信号量索引
** 输 出: NOT_OK:参数错误
**         OS_SEM_OK:得到信号量
**         OS_SEM_TMO:超时到
**         OS_SEM_NOT_OK:没有得到信号量
** 全局变量: 无
** 调用模块: OSClearSignal,OSSched,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------*/
INT8U OSSemAccept(INT8U Index)
{

    if (Index >= OS_MAX_SEMS)
    {
        return 0;
    }
    OS_ENTER_CRITICAL();
    /* 判断信号量是否有效。有效,信号量计数器减一 */
        if (Sem[Index].OSEventType > 0)
        {
                Sem[Index].OSEventType--;
        OS_EXIT_CRITICAL();
        return OS_SEM_OK;
    }
    else
    {
        /* 无信号返回信号无效 */
        OS_EXIT_CRITICAL();
        return OS_SEM_NOT_OK;
    }
}

/*********************************************************************************************************
** 函数名称: OSSemIntPost
** 功能描述: 中断中发送一个信号量
** 输 入: Index:信号量索引
** 输 出: NOT_OK:参数错误
**         OS_SEM_OK:发送成功
** 全局变量: 无
** 调用模块: OSIntSendSignal,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------*/
INT8U OSSemIntPost(INT8U Index)
{
    INT8U i;
    if (Index >= OS_MAX_SEMS)
    {
        return NOT_OK;
    }


    OS_ENTER_CRITICAL();
        /* 信号量计数器加一 */
        if (Sem[Index].OSEventType < 0xff)
        {
                Sem[Index].OSEventType++;
        }

        /* 察看信号量的等待任务队列 */
        i=0;
        while ((i < OS_MAX_TASKS) && (!(Sem[Index].OSTaskPendTbl & (0x01<<i))))
        {
                i++;
                /*
                        找出信号量等待列表中任务优先级最高的任务
                */
        }
        if(i < OS_MAX_TASKS)                                                                /*如果有任务需要                        */
        {
                Sem[Index].OSTaskPendTbl &= ~(0x01<<i);                        /*从等待表中去除                        */
                OSRdyTbl |= 0x01<<i;                                                        /*任务就绪                                        */
        }
    OS_EXIT_CRITICAL();
    return OS_SEM_OK;
}

/*********************************************************************************************************
** 函数名称: OSSemPost
** 功能描述: 发送一个信号量
** 输 入: Index:信号量索引
** 输 出: NOT_OK:参数错误
**         OS_SEM_OK:发送成功
** 全局变量: 无
** 调用模块: OSSemIntPost,OSSched
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------*/
INT8U OSSemPost(INT8U Index)
{
    if (OSSemIntPost(Index) == OS_SEM_OK)
    {
        OSSched();
        return OS_SEM_OK;
    }
    else
    {
        return NOT_OK;
    }
}

/*********************************************************************************************************
** 函数名称: OSSemQuery
** 功能描述: 查询信号量
** 输 入: Index:信号量索引
** 输 出: 信号量的值
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2002年10月26日
**-------------------------------------------------------------------------------------------------------*/
INT8U OSSemQuery(INT8U Index)
{
    if (Index >= OS_MAX_SEMS)
    {
        return 0;
    }

    return Sem[Index].OSEventType;
}
 楼主| 发表于 2011-8-29 10:49:41 | 显示全部楼层
回复【84楼】skype
-----------------------------------------------------------------------

感谢skype兄带过来的经典代码,我抽时间将代码整理一下,发带信号量版本。
最近忙一些别的事情焦头烂额
匿名  发表于 1970-1-1 08:00:00
post_deleted
发表于 2011-9-8 19:59:43 | 显示全部楼层
mark
发表于 2011-10-9 22:43:33 | 显示全部楼层
呵呵,OS
 楼主| 发表于 2011-10-10 09:59:35 | 显示全部楼层
回复【88楼】ken ly
-----------------------------------------------------------------------

谢谢捧场
发表于 2011-10-16 21:47:32 | 显示全部楼层
好东西  要顶
发表于 2011-10-18 01:52:40 | 显示全部楼层
谢过楼主
发表于 2011-11-3 12:41:35 | 显示全部楼层
mark
发表于 2011-11-3 13:00:08 | 显示全部楼层
MARK!
发表于 2011-11-9 14:35:09 | 显示全部楼层
mark
发表于 2011-11-19 09:53:57 | 显示全部楼层
stvd好像用的是堆栈,导致在stvd上做系统几乎不可能

  最近用上了STM8,STVD不能上OS???
发表于 2011-11-19 10:12:45 | 显示全部楼层
学习下
发表于 2011-11-28 23:05:15 | 显示全部楼层
我顶!!!
发表于 2011-11-29 08:13:30 | 显示全部楼层
mark~
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 公安备案:44190002001997(交互式论坛) 工信部备案:粤ICP备09047143号 )

GMT+8, 2020-2-25 17:20

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表