tabc_123 发表于 2014-11-15 22:46:52

开源:类OS的调度器

此调度器,结合本论坛各位高手的代码,及Protothreads,加上自己的理解,及实际在项目中的使用情况不断修改而成,
在这里要感谢各位坛友的代码;
本调度器共3个文件
schedule.h
schedule.c
sch_cfg.h

本调度器特点:
1,仿OS编程方式
2,代码优化等级不能过高
3,适用于前后台及OS的系统中
4,占用一个CPU一个定时器
5,支持信号量
6,支持邮箱

代码如下:
schedule.h
#ifndef _SCH_H
#define _SCH_H

#ifdef __cplusplus
extern "C" {
#endif

/**********************************************************************************************************
*                                       schedule 版本号
**********************************************************************************************************/

#defineSCH_VERSION               02100u            

/**********************************************************************************************************
*                                        包含头文件
**********************************************************************************************************/

#include <sch_cfg.h>
   
#ifndefSCH_GLOBALS
#defineSCH_EXTextern
#else
#defineSCH_EXT
#endif

/**********************************************************************************************************
*                                        数据结构定义
**********************************************************************************************************/
typedef struct {                                        //任务TCB数据类型定义
        SCH_TICKS                TaskDly;
        INT8U                        SpawnExitFlag;
} SCH_TCB;

typedef SCH_TICKS        SEM;                        //信号量数据类型定义
typedef struct {                                        //邮箱数据类型定义
        SCH_TICKS Dly;
        void *pMbox;
} MBOX;

/**********************************************************************************************************
*                                       全局变量定义
**********************************************************************************************************/
SCH_EXT SCH_TCB         TaskTcb;                        //任务状态数据结构
SCH_EXT INT8U                CurRunTaskId;                                        //当前运行任务的ID号


/**********************************************************************************************************
*                                       系统状态定义
**********************************************************************************************************/
#define SCH_ERR_NONE                     0u
#define SCH_ERR_TIMEOUT               10u

/**************************************************************************************************************
************任务相关宏
【1】任务创建按实例创建:
void Task_xxx(void)
{
        SCH_TaskBegin();
        while(1) {
                //用户代码
                SCH_TimeDly(SCH_TICKS_PER_SEC/100);                //根据任务实际周期进行延时
        }
        SCH_TaskEnd();
}
【注意】
        1,任务必须是无限循环,不能返回;
        2,任务中必须有延时函数或等待信号量,便于任务出让CPU使用权;
        3,任务函数中使用的非静态局部变量会在任务出让CPU后,变量消失,因此要想某个变量不消失,则要使用静态变量

【2】任务调度,按以下实例
SCH_TaskRun(Task_xxx,0);
【注意】
        1,各任务的ID不能相同
**************************************************************************************************************/


//@任务开始宏,在任务函数的变量声明后引用
#define SCH_TaskBegin()        static INT16U _lc=0u; switch(_lc){case 0:
                                               
//@任务结束宏,在任务尾引用
#define SCH_TaskEnd() }                               

//@任务调用宏,在主循环中调用
//@ TaskName:任务名
//@ TaskID:任务ID,最大值不能超过"SCH_MAX_TASKS"值,且每个任务的ID不能相同
#define SCH_TaskRun(TaskName,TaskID) \
    do { \
                CurRunTaskId = TaskID; \
      if(TaskTcb.TaskDly==0) { \
            TaskName(); \
      } \
    } while(0);

       
/**************************************************************************************************************
************子任务相关宏
【1】子任务创建按实例创建:
void SubTask_xxx(void)
{
        SCH_SubTaskBegin();
        //用户代码
        SCH_TimeDly(SCH_TICKS_PER_SEC/100);                //根据任务实际周期进行延时
        SCH_SubTaskEnd();
}
【注意】
        1,子任务不可以是无限循环,否则子任务后面程序无法执行;
        2,子任务可以带参数;
        3,子任务中必须有延时函数或等待信号量,便于任务出让CPU使用权;
        4,子任务函数中使用的非静态局部变量会在任务出让CPU后,变量消失,因此要想某个变量不消失,则要使用静态变量

【2】子任务调度,按以下实例
        SCH_CallSubTask(SubTask_xxx());
**************************************************************************************************************/

//@子任务开始宏,在子任务函数的变量声明后引用
#define SCH_SubTaskBegin() static INT16U _lc=0u;TaskTcb.SpawnExitFlag=1u;switch(_lc){case 0u:
       
//@子任务结束宏,在子任务函数尾引用
#define SCH_SubTaskEnd() }_lc=0;TaskTcb.SpawnExitFlag=0u;return

//@子任务调用宏,在任务中调用,允许多层嵌套
//@ SubTaskName:子任务名
//@ p_arg:子线程函数输入参数
#define SCH_CallSubTask(SubTaskFun)        \
        while(1) { \
                _lc=(__LINE__%65535);return;case(__LINE__%65535): { \
                        SubTaskFun; \
                } \
                if(TaskTcb.SpawnExitFlag==0u) { \
                        break; \
                } \
        }
       



/**************************************************************************************************************
************延时宏定义
**************************************************************************************************************/

//@延时宏,在任务开始宏和结束宏之间的任意位置引用;
//@【注】由于此调度器运用了C语言的行号的宏代码,因此此宏定义最好放在一行代码中,不能拆分此宏定义,防止行号返回出错
//@ ticks:延时时间
#define SCH_TimeDly(ticks)         do{_lc=(__LINE__%65535);TaskTcb.TaskDly=ticks;return;}while(0);case (__LINE__%65535):

/**************************************************************************************************************
************信号量相关调用宏定义
**************************************************************************************************************/
//@信号量创建
#define SCH_SemCreate(Sem) Sem = 1

//@w信号量等待
//@        sem--等待信号量;
//@        timeout--等待超时时间,0--直到成功等待信号量;
//@        err--等待信号状态,SCH_ERR_NONE-等待成功,SCH_ERR_TIMEOUT-等待超时
#define SCH_SemPend(sem,timeout,err) \
    do { \
                if(sem==0) { \
                        sem = 1; \
                        err = SCH_ERR_NONE; \
                } else { \
                        sem = timeout + 1; \
                        SCH_TimeDly(0); \
                        if(timeout==0) { \
                                if(sem>0) { \
                                        TaskTcb.TaskDly = 0; \
                                        return; \
                                } \
                                sem = 1; \
                                err = SCH_ERR_NONE; \
                        } else { \
                                if(sem>1) { \
                                        sem --; \
                                        TaskTcb.TaskDly = 1; \
                                        return; \
                                } else if(sem==1) { \
                                        err = SCH_ERR_TIMEOUT; \
                                } else { \
                                        sem = 1; \
                                        err = SCH_ERR_NONE; \
                                } \
                        } \
                } \
    } while(0)

//@ 发出一个信号量
#define SCH_SemPost(Sem) \
    do { \
      Sem = 0; \
    } while(0)
       
/**************************************************************************************************************
************邮箱相关调用宏定义
**************************************************************************************************************/
#if SCH_MBOX_EN > 0u
       
//@创建邮箱
#define SCH_MboxCreate(mbox) do{mbox.Dly = 1;mbox.pMbox = (void*)0;}while(0)

//@ 邮箱等待
//@        mbox--等待邮箱;
//@ pmsg--等待成功后接收邮箱数据指针;
//@        timeout--等待邮箱超时时间,0--直到成功等待邮箱;
//@        err--等待邮箱状态,SCH_ERR_NONE-等待成功,SCH_ERR_TIMEOUT-等待超时
#define SCH_MboxPend(mbox,pmsg,timeout,err) \
    do { \
                if(mbox.pMbox!=(void*)0) { \
                        pmsg = mbox.pMbox; \
                        mbox.pMbox = (void*)0; \
                        err = SCH_ERR_NONE; \
                } else { \
                        mbox.Dly = timeout + 1; \
                        SCH_TimeDly(0); \
                        if(timeout==0) { \
                                if(mbox.pMbox==(void*)0) { \
                                        TaskTcb.TaskDly = 0; \
                                        return; \
                                } \
                                pmsg = mbox.pMbox; \
                                mbox.pMbox = (void*)0; \
                                err = SCH_ERR_NONE; \
                        } else { \
                                if(mbox.pMbox!=(void*)0) { \
                                        pmsg = mbox.pMbox; \
                                        mbox.pMbox = (void*)0; \
                                        err = SCH_ERR_NONE; \
                                } else { \
                                        if(mbox.Dly>1) { \
                                                mbox.Dly --; \
                                                TaskTcb.TaskDly = 1; \
                                                return; \
                                        } else if(mbox.Dly==1) { \
                                                pmsg = (void*)0; \
                                                mbox.pMbox = (void*)0; \
                                                err = SCH_ERR_TIMEOUT; \
                                        } \
                                } \
                        } \
                } \
    } while(0)

//@ 发出一个邮箱
#define SCH_MobxPost(mbox,pmsg) \
    do { \
      mbox.Dly = 0; \
                mbox.pMbox = (void*)pmsg; \
    } while(0)
       
       
#endif
       
       
       
/*************************************
                        函数申明
*************************************/
void SCH_Init(void);
void SCH_TimeTick(void);



#endif       


schedule.c
#defineSCH_GLOBALS
#include<schedule.h>


/********************************************************************************************************
** 函数名:        SCH_Init
** 输入:        无
** 输出:        无
** 功能说明:调度器初始化函数,任务运行前调用
*********************************************************************************************************/
void SCH_Init(void)       
{
        INT8U i;
       
        CurRunTaskId = 0;
        for(i=SCH_MAX_TASKS;i>0;i--) {
                TaskTcb.TaskDly = 0;
                TaskTcb.SpawnExitFlag = 0;
        }
}

/********************************************************************************************************
** 函数名:        SCH_TimeTick
** 输入:        无
** 输出:        无
** 功能说明:调度器时钟节拍函数,在定时中断中调用
*********************************************************************************************************/
void SCH_TimeTick(void)       
{
        INT8U i;
        for(i=SCH_MAX_TASKS;i>0;i--) {      
      if(TaskTcb.TaskDly>0) {      //任务延时时间处理
            TaskTcb.TaskDly --;
      }
        }
}
       


sch_cfg.h
#ifndef SCH_CFG_H
#define SCH_CFG_H

#define SCH_MAX_TASKS         10                  //最大任务数量,可以增加,最大255个
#define SCH_MBOX_EN             1                            // Enable (1) or Disable (0) 邮箱


#define SCH_TICKS_PER_SEC       1000              //1秒钟多少个系统时钟数




/**********************************************************************************************************
*                                              与编译器相关数据类型定义
**********************************************************************************************************/
typedef unsigned charBOOLEAN;
typedef unsigned charINT8U;                  /* Unsigned8 bit quantity                           */
typedef signed   charINT8S;                  /* Signed    8 bit quantity                           */
typedef unsigned short INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   short INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned int   INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   int   INT32S;                   /* Signed   32 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                  */
typedef double         FP64;                     /* Double precision floating point                  */

typedef unsigned int   SCH_TICKS;                //定义延时时钟数据类型




#endif

测试代码
#include "includes.h"
#include "app_cfg.h"

SEM Sem1,Sem2;                                        //
MBOX mbox1,mbox2;

/********************************************************************************************************
** 函数名:        App_FunSemCreate
** 输入:
** 输出:
** 功能说明:信号量创建函数
*********************************************************************************************************/
static void App_FunSemCreate (void)
{
        INT8U                os_err;
       
        SCH_SemCreate(Sem1);       
        SCH_SemCreate(Sem2);
        SCH_MboxCreate(mbox1);
        SCH_MboxCreate(mbox2);
}


void Ledred(void)
{
        SCH_TaskBegin();
        while(1) {
                LEDOn(RED_LED);
                SCH_TimeDly(SCH_TICKS_PER_SEC/2);
                LEDOff(RED_LED);
                SCH_TimeDly(SCH_TICKS_PER_SEC/2);
        }
        SCH_TaskEnd();
       
}

void Ledgreen(void)
{
        SCH_TaskBegin();
        while(1) {
                LEDOff(GREEN_LED);
                SCH_TimeDly(SCH_TICKS_PER_SEC/2);
                LEDOn(GREEN_LED);
                SCH_TimeDly(SCH_TICKS_PER_SEC/2);
        }
        SCH_TaskEnd();
}

void Delay(void)
{
        static uint8_t        i;
       
        SCH_TaskBegin();
        while(1) {
                for(i=0;i<5;i++) {
                        printf("Delay Cnt = %d\r\n",i);
                        SCH_TimeDly(SCH_TICKS_PER_SEC/2);
                }
                printf("Delay exit\r\n");
        }
        SCH_TaskEnd();
}

void Task_Sem1Test(void)
{
        uint8_t        err;
       
        SCH_TaskBegin();
        while(1) {
                printf("Sem1 等待置位...\r\n");
                SCH_SemPend(Sem1,0,err);
                printf("Sem1 等待成功...\r\n");
        }
        SCH_TaskEnd();
}

void Task_Sem2Test(void)
{
        uint8_t        err;
       
        SCH_TaskBegin();
        while(1) {
                printf("Sem2 等待置位,1秒钟超时...\r\n");
                SCH_SemPend(Sem2,SCH_TICKS_PER_SEC*10,err);
                if(err==SCH_ERR_TIMEOUT) {
                        printf("【Sem2】 等待超时...\r\n");
                } else {
                        printf("Sem2 等待成功...\r\n");
                }
        }
        SCH_TaskEnd();
}

void Task_Mbox1Test(void)
{
        uint8_t        err;
        char         *p;
       
        SCH_TaskBegin();
        while(1) {
                printf("mbox1 等待置位,1秒超时...\r\n");
                SCH_MboxPend(mbox1,p,SCH_TICKS_PER_SEC*5,err);
                if(err==SCH_ERR_TIMEOUT) {
                        printf("【mbox1】 等待超时...\r\n");
                } else {
                        printf("mbox1 等待成功...\r\n");
                        printf("mbox=[%s]\r\n",p);
                }
        }
        SCH_TaskEnd();
}

void Task_Swap(void *p_arg)
{
        static uint8_t         i;
       
        SCH_SubTaskBegin();

        for(i=0;i<5;i++) {
                printf("swap cnt = %d\r\n",i);
                SCH_TimeDly(SCH_TICKS_PER_SEC*2);
        }
       
        printf("Task_Swap Exit\r\n");
        SCH_SubTaskEnd();
       
}

void Task_Swap1(void *p_arg)
{
        static uint8_t         i;
        uint8_t                xx;
       
        SCH_SubTaskBegin();
       
        //SCH_CallSubTask(Task_Swap(NULL));
       
        printf("swap exit \r\n");
        for(i=0;i<5;i++) {
                printf("swap1 cnt = %d\r\n",i);
                SCH_TimeDly(SCH_TICKS_PER_SEC*2);
        }
       
        printf("Task_Swap1 Exit\r\n");
        SCH_SubTaskEnd();
}


void Task_SwapTest(void)
{
        uint8_t        err;
        void         *p;
       
        int                test;
          
        SCH_TaskBegin();
        while(1) {
                printf("子任务调用测试...\r\n");
                SCH_CallSubTask(Task_Swap1(NULL));
               
                printf("子任务调用测试完成,延时2秒...\r\n");
                SCH_TimeDly(SCH_TICKS_PER_SEC*2);
        }
        SCH_TaskEnd();
}

/********************************************************************************************************
** 函数名:main
** 输入:
** 输出:
** 功能说明:main函数
*********************************************************************************************************/
int main (void)
{       
       
        uint32_t        i = 0;
        uint32_t        ConnectTime;
       
        uint8_t                AppDownload = FALSE;
        uint8_t                buf;
       
        uint32_t        Test = 0,Test2 = 0;
       
        uint8_t                ConnectStatus = FALSE;
        char            GetKey;
       
        /*=========初始化核心代码=========*/
        SCH_Init();                                                                //调度器初始化
       
        //初始化全局应用变量
        GlobalTime = 998;                                //计数器

        App_FunSemCreate();
       
    BSP_GPIOConfiguration();                             //GPIO配置
        BSP_CpuPeriphInit();                                         //CPU相关硬件初始化
       
        BSP_WDT_HardInit();                                                //看门狗初始化
       
        LEDOff(GREEN_LED);
        LEDOff(RED_LED);
       
        BSP_WDTHardReset();               
       
        while(1) {
               
                SCH_TaskRun(Ledred,0);               
                //SCH_TaskRun(Delay,1);
               
                //SCH_TaskRun(Task_Sem1Test,2);
                //SCH_TaskRun(Task_Sem2Test,3);
                //SCH_TaskRun(Task_Mbox1Test,4);
                Task_Swap(NULL);
                SCH_TaskRun(Task_SwapTest,4);

                GetKey = _getkey();
      if(GetKey!=-1) {
                        if(GetKey=='x') {
                                printf("Test Sem1\r\n");
                                SCH_SemPost(Sem1);
                        } else if(GetKey=='y') {
                                printf("Test Sem2\r\n");
                                SCH_SemPost(Sem2);
                        } else if(GetKey=='m') {
                                printf("Test mobx1\r\n");
                                sprintf((char*)buf,"Test mobx1\r\n");
                                SCH_MobxPost(mbox1,buf);
                        }
      }
        }
}



/**
* @briefReports the name of the source file and the source line number
*         where the assert_param error has occurred.
* @paramfile: pointer to the source file name
* @paramline: assert_param error line source number
* @retval None
*/
#ifdefUSE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
    static char str1;
        static uint32_t temp;
       
        memcpy((void*)str1,(const void*)file,strlen((const char*)file));
        temp = line;
/* User can add his own implementation to report the file name and line number,
   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
        //my_printf("Worng parameters value:file%s on line %d\r\n",file,line);
       
        /* Infinite loop */
        while(1) {       
        }
}
#endif
/*************************************************end of file********************************************/


使用说明:
1,定时器中调用函数:SCH_TimeTick()
2,main函数开关调用SCH_Init()

=========================分割线==========================================

错误不合理之处,望大家指正,修改,一起完善。

tabc_123 发表于 2014-11-15 22:47:44

占楼            

hkjabcd 发表于 2014-11-15 23:03:42

顶起,楼主能否解释下思路?

mint 发表于 2014-11-15 23:24:37

这个宏用的,飞起啊~~~

lize91 发表于 2014-11-15 23:38:29

mark
好好拜读下

68336016 发表于 2014-11-15 23:47:10

也不能使用 switch语句?

dgtg 发表于 2014-11-16 10:30:57

mark!!!楼主讲一讲思路嘛....

summarize 发表于 2014-11-16 11:02:06

支持LZ不断改进,造福坛友.

haowei029 发表于 2014-11-16 12:34:04

不错
学习学习

lushanlq 发表于 2014-11-16 20:00:46

支持一下,好像是Protothreads修改的。

ycping 发表于 2014-11-17 08:20:43

解说一下呗,

aming2046 发表于 2014-11-17 09:33:50

能否提供完整的工程文件啊,谢谢了啊

jungleyang 发表于 2014-11-17 16:23:30

太复杂了,看到这么多宏,头大了!

天涯沦人 发表于 2014-11-17 16:26:02

mark! 学习了。。

eddia2012 发表于 2014-11-17 19:46:20

这个OS很适用,顶顶顶!{:smile:}

RainKing 发表于 2014-11-19 15:41:34

一个思路,学习了.............

minier 发表于 2015-2-5 22:25:51

很牛!!!试用一下看看

guhaijun 发表于 2015-2-10 15:37:08

mark一下

videofun 发表于 2015-5-16 12:02:38

能否提供完整的工程文件啊,谢谢了啊

tabc_123 发表于 2015-5-18 10:23:16

不知道,1楼的帖子怎么编辑,现将最新版本的程序给出



app.c为测试例子

foxpro2005 发表于 2015-6-28 00:16:59

tabc_123 发表于 2015-5-18 10:23
不知道,1楼的帖子怎么编辑,现将最新版本的程序给出




LZ升级扩展得不错, 感谢分享, 有时间试试

graycker 发表于 2015-6-28 11:22:17

好帖子,赞一个

guolun 发表于 2015-7-3 10:18:35

研究一下调度器

shouqiang_zhang 发表于 2015-7-4 05:56:21

谢谢楼主, 学习了.

nuncle 发表于 2015-7-6 23:00:22

mark'dddff

zhuzi1441 发表于 2015-7-21 15:38:55

请问一下,这个调度器是不是没有优先级了,哪位明白的,给说一下,谢谢。

tabc_123 发表于 2015-7-21 20:23:55

zhuzi1441 发表于 2015-7-21 15:38
请问一下,这个调度器是不是没有优先级了,哪位明白的,给说一下,谢谢。 ...

还是有优先级的,而且任务的优先级不允许相同

zhuzi1441 发表于 2015-7-21 20:47:36

非常感谢楼主的回复,有穵试月子,感觉很不错。

leibwell 发表于 2015-7-21 20:56:26

mark,谢了

zd0305 发表于 2015-7-27 15:39:58

2015最新版SCH_TimeDly(Ticks) MPLAB X + XC8环境 编译报错:constant expression required

tabc_123 发表于 2015-7-27 22:31:12

zd0305 发表于 2015-7-27 15:39
2015最新版SCH_TimeDly(Ticks) MPLAB X + XC8环境 编译报错:constant expression required

我这没有这种编译器,无法测试,你在仔细研究一下,如果问题解决,希望你说下解决方法

zd0305 发表于 2015-7-28 10:40:45

经测试:
#define SCH_TimeDly(ticks)         do{_lc=(__LINE__%65535);TaskTcb.TaskDly=ticks;TaskTcb.SubExitFlag=1u;return;}while(0);case (__LINE__%65535):
中的case (__LINE__%65535):这一语句编译不过,错误提示:case 语句需要常量;
临时解决办法:
#define SCH_TimeDly(ticks)         do{_lc=(__LINE__);TaskTcb.TaskDly=ticks;TaskTcb.SubExitFlag=1u;return;}while(0);case (__LINE__):

qiguibao 发表于 2015-8-2 09:51:13

楼主,这个调度器不支持高优先级抢占,这样高优先级的任务实时性不能保证吧~

tabc_123 发表于 2015-8-2 16:30:49

zd0305 发表于 2015-7-28 10:40
经测试:
#define SCH_TimeDly(ticks)         do{_lc=(__LINE__%65535);TaskTcb.TaskDly=ticks;Tas ...

可能是编译器不一样,应该这种表达示是在预编译时处理的,可能你的编译器是将此类表达示放在程序运行中处理的,这是我的理解

tabc_123 发表于 2015-8-2 16:35:38

qiguibao 发表于 2015-8-2 09:51
楼主,这个调度器不支持高优先级抢占,这样高优先级的任务实时性不能保证吧~ ...

这种调度器与RTOS是有区别的,不能进行抢占,只能说任务编号越小,提前执行而已

eddia2012 发表于 2015-8-13 08:14:49

这个调度器很好用。{:smile:}

tabc_123 发表于 2015-8-13 09:16:05

eddia2012 发表于 2015-8-13 08:14
这个调度器很好用。

谢谢使用,使用过程中有任何问题,请指出

yick 发表于 2015-8-15 12:10:37

mark,又是一个关于timer定时器的

wofei3344 发表于 2015-8-16 15:52:12

有时间了再来验证,谢谢分享~

luozhongchao123 发表于 2015-8-16 16:07:19

已经经过修改用在小产品上了!谢谢楼主的开源!

tabc_123 发表于 2015-8-16 16:44:08

luozhongchao123 发表于 2015-8-16 16:07
已经经过修改用在小产品上了!谢谢楼主的开源!

能否分开修改部分的代码,一起将此代码修改得更加完善。。。。。

wxlcj 发表于 2015-8-30 22:54:55

楼主,求一个stm8完整工程。

tabc_123 发表于 2015-8-30 23:39:00

wxlcj 发表于 2015-8-30 22:54
楼主,求一个stm8完整工程。

前面的例子,不用CPU的,直接可以使用

weiwei4 发表于 2015-11-24 21:59:26

不错,学习

wangyy@dianzi 发表于 2016-6-27 22:32:01

很好,支持

闲鱼翻身 发表于 2016-6-28 08:49:46

感谢分享,好东西

eddia2012 发表于 2016-8-11 10:56:23

{:smile:}借用楼主的思想,已用在好多工程中了。

four_zhg 发表于 2016-9-3 17:47:45

好好学习楼主的思想试试看

rube 发表于 2016-9-6 14:31:42

tabc_123 发表于 2015-5-18 10:23
不知道,1楼的帖子怎么编辑,现将最新版本的程序给出




能否将getkey()函数发上来,学习你是怎么写的。{:smile:}
我以前都是状态机方式。

tabc_123 发表于 2016-9-7 09:03:44

本帖最后由 tabc_123 于 2016-9-7 09:14 编辑

rube 发表于 2016-9-6 14:31
能否将getkey()函数发上来,学习你是怎么写的。
我以前都是状态机方式。 ...

我理解错了,getkey()只是一个串口数据接收函数

rube 发表于 2016-9-7 11:32:57

tabc_123 发表于 2016-9-7 09:03
我理解错了,getkey()只是一个串口数据接收函数

哦,谢谢

int 发表于 2016-10-21 13:32:22

学习一个,纯C的调度器太巧妙了,使用调度器管理可以极大地减少阻塞

HalenYU 发表于 2016-10-24 20:29:24

支持创新

jorry 发表于 2016-12-17 22:27:03

学习一下,谢谢!@!

shunli1014 发表于 2017-1-5 11:02:46

{:smile:},谢谢分享;学习了

王二小 发表于 2024-6-28 09:47:06

该类OS还有维护吗,可否用于产品上?

summarize 发表于 2024-6-28 19:39:50

王二小 发表于 2024-6-28 09:47
该类OS还有维护吗,可否用于产品上?
(引用自56楼)

无维护,喜欢可以用于产品上。

王二小 发表于 2024-7-2 20:13:56

本帖最后由 王二小 于 2024-7-2 20:15 编辑

summarize 发表于 2024-6-28 19:39
无维护,喜欢可以用于产品上。
(引用自57楼)
大神,最近有用你的那个类OS做产品,有遇到问题,可以跟你沟通吗?VX:stm3206

王二小 发表于 2024-7-3 21:42:48

王二小 发表于 2024-7-2 20:13
大神,最近有用你的那个类OS做产品,有遇到问题,可以跟你沟通吗?VX:stm3206 ...
(引用自58楼)

可以把这个头文件做成库吗,我想加密
页: [1]
查看完整版本: 开源:类OS的调度器