avr-arm 发表于 2010-7-12 10:53:27

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

首先上51版本./emotion/em001.gif
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版本./emotion/em001.gif
用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块买的,所以先拿它做的测试,很稳定!
http://cache.amobbs.com/bbs_upload782111/files_30/ourdev_567250APXFN6.JPG
(原文件名:未命名.JPG)
编译器选择的是IAR,因为它里边支持c语言是用的模拟寄存器!!!!stvd好像用的是堆栈,导致在stvd上做系统几乎不可能
stm8工程,是stm8s105c6版本,仿真是硬件仿真,因为proteus不支持stm8:(ourdev_567253FKWHEQ.rar(文件大小:44K) (原文件名:RaysRTOS-STM8IAR.rar)
flash和ram占用情况如下:
941 bytes of readonlycode memory
132 bytes of readonlydata 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);                         //系统节拍钩子函数

./emotion/em048.gif
欢迎大家测试,我是新手,难免有很多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)

./emotion/em035.gif
最后再感谢lisuwei把我带入rtos大门,还要感谢上官兄,没他的代码我不会stm8汇编

my_avr 发表于 2010-7-12 11:00:55

沙发,置COOL前留爪印

fshunj 发表于 2010-7-12 11:02:26

支持

tangwei039 发表于 2010-7-12 11:15:54

mark

xjf20072608 发表于 2010-7-12 12:46:45

mark

cargle 发表于 2010-7-12 13:11:44

good

quzegang 发表于 2010-7-12 13:24:01

mark

S81250 发表于 2010-7-12 13:55:12

学习

avrmk 发表于 2010-7-12 14:50:51

good

bad_fpga 发表于 2010-7-12 14:56:37

cool

undeadhuman 发表于 2010-7-12 16:53:58

牛叉!晚上回去加你。

avr-arm 发表于 2010-7-12 17:24:18

大家测试过程中出现什么bug或者不稳定情况,请及时反馈给我.(*^__^*) 嘻嘻……
我想先把内核跑好了再做任务间通信的东东.
还希望莫大给条"裤子"./emotion/em209.gif

有些人编写avr喜欢用avrstudio,我修改了studio的版本,用avrstudio的编译mega88上的,并带有ptoteus7.5sp3仿真文件
点击此处下载 ourdev_567367SIPKCM.rar(文件大小:35K) (原文件名:RaysRTOS-avrstudioMega88.rar)

liujunjie 发表于 2010-7-12 17:45:15

先顶帖子再说!~

bluejay 发表于 2010-7-12 18:15:53

先顶再猫咳

yqlomg 发表于 2010-7-12 19:01:02

mark

AVR_shaofeng 发表于 2010-7-12 21:35:20

这样的是该加酷了

eworker 发表于 2010-7-12 22:00:11

还不错

avr-arm 发表于 2010-7-13 08:38:22

自己顶一下
大家还有什么性价比高的单片机推荐,我可以做移植,我手头只有这三种单片机.
其实写出来之后才知道操作系统也不难:)

ljt8015 发表于 2010-7-13 11:46:55

mark!~~

laodaok 发表于 2010-7-14 11:31:38

看起来不错,学习一下

Jason022 发表于 2010-7-14 12:23:12

nicie :)

avr-arm 发表于 2010-7-19 10:21:23

自己顶!!!!!!!!!!!

yl604922959 发表于 2010-7-19 10:25:46

帮顶,呵呵,谁说我们学校不出强人

allen-green 发表于 2010-7-19 14:16:02

mk

laodaok 发表于 2010-7-21 16:19:03

非常不错

shouqiang_zhang 发表于 2010-7-24 00:28:32

MARK

avr-arm 发表于 2010-7-24 11:47:01

希望都帮我顶起来啊,我这边抓紧测试系统稳定性以及调度时间

bsz84 发表于 2010-7-24 15:40:39

mark

avr-arm 发表于 2010-8-14 14:40:12

还有哪款单片机用途广泛?考虑移植一下

chenhnu 发表于 2010-8-14 14:51:35

freescale 用途是很多的楼主可以考虑下

qfmcu 发表于 2010-8-14 15:05:31

MARK

Swallow 发表于 2010-8-14 15:36:48

MARK!

sn2101 发表于 2010-8-18 17:05:34

MARK

Spunky 发表于 2010-8-21 09:48:35

mark

jackiezeng 发表于 2010-8-21 09:52:03

感谢LZ ,

Spunky 发表于 2010-8-21 09:54:49

说实话,你这个简单的OS和uCOSII思路差不多,基本上就是一个简化版本。

sz_zz 发表于 2010-8-21 09:56:56

牛人啊,顶一火

pengliang983 发表于 2010-8-21 17:23:27

lv998127 发表于 2010-8-21 20:10:16

路过顶帖!

gdmfq 发表于 2010-8-21 20:13:56

好东西 利害

chenao 发表于 2010-8-21 22:01:22

这是我们学校的牛人,顶顶顶

fy024 发表于 2010-8-22 00:06:20

mark

yinglively 发表于 2010-8-22 07:39:18

mark

mcu_lover 发表于 2010-8-22 11:05:18

学习了。

PXJ_520 发表于 2010-8-22 13:22:11

MARK

boy364100 发表于 2010-8-22 13:37:15

下载 玩玩~~~

liumoz 发表于 2010-8-30 21:44:03

下载试试~~

way2888 发表于 2010-9-3 07:08:18

mark

tangwei039 发表于 2010-9-4 08:46:39

mark

wmm20031015 发表于 2010-9-21 17:37:58

修改了一下,同时开启16个任务,效果不错

avr-arm 发表于 2010-9-22 08:20:03

回复【49楼】wmm20031015
-----------------------------------------------------------------------
我正想办法添加堆栈统计功能

pengliang983 发表于 2010-9-22 10:39:13

mark

wmm20031015 发表于 2010-9-24 11:16:13

期待楼主的改进,使用堆栈统计,进行动态分配

guoying329 发表于 2010-9-24 13:54:39

Cool!

dgtg 发表于 2010-9-25 13:00:58

同mask~!

YL_L 发表于 2010-11-11 14:17:52

Mark!

yilichen 发表于 2010-11-27 18:51:23

mark

Bati-Gol 发表于 2011-4-21 19:17:41

mark

summerstar 发表于 2011-4-26 13:57:43

mark!

wzq666 发表于 2011-4-28 18:35:53

好好

lixupeng 发表于 2011-4-28 19:16:34

mark!!!!!

oxalis 发表于 2011-4-28 20:12:56

留爪印

woodlynn 发表于 2011-4-28 20:51:10

标记一下,以后有用

nihaowubin 发表于 2011-5-5 15:20:50

zhanglu1990 发表于 2011-6-24 15:34:18

感谢分享!!!

stely 发表于 2011-6-24 17:22:37

MARK牛人

skype 发表于 2011-7-11 16:09:00

呵呵,只有这个OS内核才能看懂,谢谢!

mugua3695458 发表于 2011-7-12 13:52:31

下下来了,以后学习!

avr-arm 发表于 2011-7-13 11:04:20

回复【66楼】skype
-----------------------------------------------------------------------

看到您的回复我很欣慰,我希望有更多的人去看的懂,去完全理解,其实小型OS也不那么神秘。
小弟保证,看懂之后,单片机知识狂涨一大截!./emotion/em025.gif

ijlc1314 发表于 2011-7-13 12:42:16

mark

skype 发表于 2011-7-13 20:07:49

回复【68楼】avr-arm 光芒电子
回复【66楼】skype
-----------------------------------------------------------------------
看到您的回复我很欣慰,我希望有更多的人去看的懂,去完全理解,其实小型os也不那么神秘。
小弟保证,看懂之后,单片机知识狂涨一大截!
-----------------------------------------------------------------------

昨天晚上看到2点才睡,才正真看懂。
今天上班后找了51单片机的书,重点看了PC、堆栈、SP、子程序调用及RET/RETI。
有了这些基础,才能看明白你的这个OS.

dahai168 发表于 2011-7-13 20:12:54

好东西,顶

gloryzkl 发表于 2011-7-27 13:26:18

mark

xooogo 发表于 2011-8-2 13:39:06

收藏学习

AVR_DIY 发表于 2011-8-2 16:28:43

记号

farmer 发表于 2011-8-4 09:46:58

MARK牛人

skype 发表于 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:任务优先级                  |
+---------------------------------------------------------------------------------------+
*/
voidOS_TaskCreate(void (*p_Task)(void), INT8U *p_Stack, INT8U t_Prio)
{
        TCB.OSTCBStkTop = TCB.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.OSTCBStkTop = (INT8U)p_Stack;                                        // 将人工堆栈的栈顶地址,保存到堆栈的数组中
        TCB.OSTCBStkLen = TCB.OSTCBStkTop - TCB.OSTCBStkBom;
        TCB.OSTCBDly = 0;                                                                          // 初始化任务延时
        OSSetPrioRdy(t_Prio);                                                                                // 在任务就绪表中登记,OSRdyTbl对应位为1,同时确定了任务的优先级
}


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

NAME        CPU_ASM


?PR?OSSched?CPU_ASM    SEGMENT CODE
?PR?Timer0ISR?CPU_ASMSEGMENT 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

nicksean 发表于 2011-8-4 11:12:31

mark!

avr-arm 发表于 2011-8-4 21:07:24

回复【76楼】skype
-----------------------------------------------------------------------

十分感谢,添加了栈检查功能,谢谢,我好好研究一下代码

Iron_Man 发表于 2011-8-4 22:04:36

./emotion/em059.gif
强烈支持...

liangerfan 发表于 2011-8-4 22:12:27

过来标记学习,谢谢分享~

skype 发表于 2011-8-28 17:37:14

顶LZ,增加信号量

#include "Serial.h"
#include "Easy51RTOS.h"
#include "Sem.h"
INT8Uidata Task0Stack;
INT8Uidata Task1Stack;
INT8Uidata Task2Stack;



/************************************************************************************************************************
函数名称:        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.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.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);
}

http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_672039X5409G.jpg
(原文件名:QQ截图未命名.jpg)

skype 发表于 2011-8-28 17:38:15

/*****************************************************************************************
*RaysRTOS 总体头文件
*
*Copyright (C) 2011
*
*2010-07-09RaysRTOS
*****************************************************************************************/
#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;

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

skype 发表于 2011-8-28 17:38:49

#include "Easy51RTOS.h"
#include "Sem.h"

struct SemBlk Sem;

/*********************************************************************************************************
** 函数名称: 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.OSEventType=Data;                        /* 计数器置初值 */
                Sem.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.OSTCBDly = Tick;                                        // 设置任务延时节拍数
    Sem.OSTaskPendTbl |= 0x01<<OSPrioCur;        /* 把任务加入等待任务队列 */

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

        Sem.OSTaskPendTbl &= ~(0x01<<OSPrioCur);        /*从等待表中去除                        */
        /* 判断信号量是否有效。有效,信号量计数器减一 */
        if (Sem.OSEventType > 0)
        {
                Sem.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.OSEventType > 0)
        {
                Sem.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.OSEventType < 0xff)
        {
                Sem.OSEventType++;
        }

        /* 察看信号量的等待任务队列 */
        i=0;
        while ((i < OS_MAX_TASKS) && (!(Sem.OSTaskPendTbl & (0x01<<i))))
        {
                i++;
                /*
                        找出信号量等待列表中任务优先级最高的任务
                */
        }
        if(i < OS_MAX_TASKS)                                                                /*如果有任务需要                        */
        {
                Sem.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.OSEventType;
}

avr-arm 发表于 2011-8-29 10:49:41

回复【84楼】skype
-----------------------------------------------------------------------

感谢skype兄带过来的经典代码,我抽时间将代码整理一下,发带信号量版本。
最近忙一些别的事情焦头烂额

gloryzkl 发表于 2011-9-8 19:59:43

mark

ken_ly 发表于 2011-10-9 22:43:33

呵呵,OS

avr-arm 发表于 2011-10-10 09:59:35

回复【88楼】ken ly
-----------------------------------------------------------------------

谢谢捧场

cpholr1 发表于 2011-10-16 21:47:32

好东西要顶

zuzuzu 发表于 2011-10-18 01:52:40

谢过楼主

saluo 发表于 2011-11-3 12:41:35

mark

xf331785508 发表于 2011-11-3 13:00:08

MARK!

levary 发表于 2011-11-9 14:35:09

mark

fkueawuk 发表于 2011-11-19 09:53:57

stvd好像用的是堆栈,导致在stvd上做系统几乎不可能

最近用上了STM8,STVD不能上OS???

hwg_LDW 发表于 2011-11-19 10:12:45

学习下

jacky2011 发表于 2011-11-28 23:05:15

我顶!!!

voval 发表于 2011-11-29 08:13:30

mark~

usingavr 发表于 2011-11-29 11:38:23

mark

hanzmts 发表于 2011-11-29 12:12:57

mark

zgkfw520 发表于 2011-11-29 13:42:58

学习学习中
页: [1] 2
查看完整版本: 感谢Lisuwei&lt;简易多任务OS设计&gt;一文,我也写出了我的RaysRTOS(光芒实