amwox 发表于 2007-11-19 12:01:59

我写的嵌入式操作系统,现在传上来与大家共同探讨!

看过几个的嵌入式操作系统,汇编的精巧,移植难,看明白也不容易.C的庞大,吃内存.我想要一个综合两者的优先点系统,于是DIY一方,尝试了一下.
编译器-IAR,CPU-M64,最高级优化,
只含定时器,两个跑马灯任务,CODE 1400Byte,RAM 269Byte,不含中断嵌套,可以关闭内核堆栈,加入信号量,互斥体,邮箱后,任务堆栈,函数调用深度堆栈(RSTACK)都要增加点击此处下载ourdev_181833.rar(文件大小:143K)
一个信号量,一个互斥体,一个邮箱,三个小任务,CODE 2717Byte,RAM 465Byte,含允许一级中断嵌套的内核堆栈点击此处下载ourdev_181834.rar(文件大小:166K)
一个信号量                     两个小任务,CODE 1947Byte,RAM 320Byte 关闭中断嵌套的内核堆栈点击此处下载ourdev_181835.rar(文件大小:152K)
一个互斥体                     两个小任务,CODE 1991Byte,RAM 322Byte 关闭中断嵌套的内核堆栈点击此处下载ourdev_181836.rar(文件大小:153K)
一个邮箱                     三个小任务,CODE 1991Byte,RAM 405Btye 关闭中断嵌套的内核堆栈点击此处下载ourdev_181837.rar(文件大小:152K)
基本上是用C写的,用汇编部分只是对寄存器进行出栈,入栈,中断出入.

抢先式调度,同优先级的按FCFS原则进行调度

看到最后生成的代码,和内存占用量,离最初的目标还好远.

发代码时又有了一个新的想法:如果信号量,互斥体,邮箱不使用超时机制,代码量应该可以更小,但是不用超时机制会怎样,怎样应用呢?

不使用超时机制一个信号量,一个互斥体,一个邮箱,三个小任务,CODE 1918Byte,RAM 404Byte,不允许一级中断嵌套的内核堆栈点击此处下载ourdev_181955.rar(文件大小:152K)


欢迎各位验证,拍砖,找虫,打压(尽可能生也更小的代码和内存占用量),共同探讨嵌入式操作系统及应用(应用是最终目的^_^)

ATmega32 发表于 2007-11-19 12:04:40

强。有没有OS讨论群?

我也想裁减一下usmartx,或者结合small rtos和usmartx,以适合更小行MCU(4KRAM,256字节RAM)。

amwox 发表于 2007-11-19 12:41:28

我的QQ还开不了群,有兴趣加我156388624,发消息MircoROS

ATmega32 发表于 2007-11-19 13:01:31

我认为在小型MCU,特别是小RAM的MCU,没必要用抢先式调度,并且给每个任务都分配堆栈。
任务多了,RAM占用量是很大的。
不如用协作式,也不必给任务单独分配堆栈。占用RAM量将减小很多。

ATmega32 发表于 2007-11-19 13:12:13

#define OS_ENTER_CRITICAL()         {cpu_sreg = SREG;OS_DISABLE_INTERRUPT();}//OS_DISABLE_INTERRUPT()//
#define OS_EXIT_CRITICAL()            {SREG = cpu_sreg;}//OS_ENABLE_INTERRUPT()//
嵌套的话,会不会有危险?

amwox 发表于 2007-11-19 13:25:43

协作式的任务是不能返回的,所以在程序时有很多限制,只能使用状态机制进行流程控制.如果采用时间片也和抢占式的一样要占用不少的RAM.


#define OS_ENTER_CRITICAL()         {cpu_sreg = SREG;OS_DISABLE_INTERRUPT();}//OS_DISABLE_INTERRUPT()//
#define OS_EXIT_CRITICAL()            {SREG = cpu_sreg;}//OS_ENABLE_INTERRUPT()//
在嵌套时是不会有危险的,可以放心使用的

tanyang 发表于 2007-11-19 13:31:24

强人,我一直想用一个,可是自己写不出来,终于。。。。

amwox 发表于 2007-11-19 13:33:14

下面我贴一个协作式的处理方法,没有信号量,互斥体和邮箱:
并非我原创.
____________________________sch.h____________________________

typedef struct
{
        void (*Function)(void);
        UINT32 Delay;
        UINT16 Period;
        UINT16 RunMe;
}TASK;

#ifndef NULL
#define NULL 0
#endif

#define REPORT_ERRORS0

#define TICKS_PER_SEC100
#define SCH_MAX_TASKS3

#define NORMAL                                        (0)
#define OK                                          (1)
#define IGNORE                                        (2)
#define ABOUT                                       (3)
#define CANCEL                                        (4)
#define TIMEOUT                                       (5)

#define ERROR_TOO_MANY_TASKS                        (21)
#define ERROR_CANNOT_DELETE_TASK                      (22)

#define INEXISTENCE                                 (255)

#define __BIT_MASK(BIT)                               (0x0001<<BIT)
#define __BIT_NMASK(BIT)                              (~(1<<BIT))
#define ClrBit(PORT,MSK)                              PORT &= ~(MSK)
#define SetBit(PORT,MSK)                              PORT |= MSK

#ifdef __SYSTEM_C
#define SYS_EXTERN
#else
#define SYS_EXTERN extern
#endif

SYS_EXTERN TASK gTask;
SYS_EXTERN UINT32 gErrorCode;
SYS_EXTERN UINT32 gLastErrorCode;
SYS_EXTERN UINT32 gErrorTickCnt;

void SchedulerInit (void);
void SchedulerStart(void);
void SchedulerDispatchTask(void);
void ReportStatus(void);
void GoToSleep(void);
UINT8 AddTask(void (*Fnc)(void),UINT32 Del,UINT32 Per);
BOOL DeleteTask(UINT8 Task_Index);
_____________________________________sch.c__________________________________________

/*
*************************************************************************************
**
**                           时间触发调度器
**
** 文   件   名: scheduler.c
**
** 版      本: 1.0
**
** 日      期: 2005/02/09
**
** 描      述: 参考<时间嵌入式系统设计模式>的混合式调度器的设计思想,应用到AVR系统上来.支持多个
**               合作式调度的任务支持一个抢式任务(可以中断合作式任务)
**
** 历 史 记录:
**    1. 日期: 2005/02/09
**       作者:
**       修改: 创建
**
*************************************************************************************
*/

#define __SYSTEM_C
#include "system.h"


void TickISR(void);




voidSchedulerInit (void)
{
        UINT32 freq;

        //初始化定时器
        for (UINT8 Index = 0; Index < SCH_MAX_TASKS; Index ++)
        {
                gTask.Function = NULL;
                gTask.Delay = 0;
                gTask.Period = 0;       
                gTask.RunMe = 0;
        }
       
}

void SchedulerStart(void)
{

   //启动定时器
   //开启中断
}

//__irq __arm
void TickISR(void)
{
        UINT8 Index;

        for (Index = 0; Index < SCH_MAX_TASKS; Index ++)
        {
                if (gTask.Function != NULL)                  /* 有一个任务 */
                {
                        if (gTask.Delay == 0)            /* 需要运行 */
                        {
                                {
                                        gTask.RunMe ++;
                                }
                               
                                if (gTask.Period)            /* 是定期调度的任务 */
                                {
                                        gTask.Delay = gTask.Period;
                                }
                        }
                        else
                        {
                                gTask.Delay --;                /* 任务运行的时间还没有到 */
                        }
                }
        }
}

void SchedulerDispatchTask(void)
{
        UINT8 Index;
        for (Index = 0; Index < SCH_MAX_TASKS; Index++ )
        {
                if ((gTask.RunMe > 0))
                {
                        if (gTask.Function != NULL)
                                (*gTask.Function)();
                        gTask.RunMe --;
                        if (gTask.Period == 0)
                        {
                                gTask.Function = NULL;
                        }
                }
        }
        ReportStatus();
        GoToSleep();
}

void ReportStatus(void)
{
#if REPORT_ERRORS > 0
        if (gErrorCode != gLastErrorCode)
        {
                /* 在此处添加出错提示代码 */

                gLastErrorCode = gErrorCode;
                if (gErrorCode != 0)
                {
                        gErrorTickCnt = 60000;
                }
                else
                {
                        gErrorTickCnt = 0;
                }
        }
        else
        {
                if (gErrorTickCnt != 0)
                {
                        if (--gErrorTickCnt == 0)
                        {
                                gErrorCode = 0;
                        }
                }
        }
#endif
}

void GoToSleep(void)
{
}

UINT8 AddTask(void (*Fnc)(void),          //任务函数
                          UINT32 Del,                   //直到任务第一次运行时的时标数
                          UINT32 Per                   //重复运行之间的时标数
                          )
{
        UINT8 Index = 0;
        while ( (gTask.Function != NULL) && (Index < SCH_MAX_TASKS))
        {
                Index++;
        }
        if (Index == SCH_MAX_TASKS)
        {
                gErrorCode = ERROR_TOO_MANY_TASKS;
                return SCH_MAX_TASKS;
        }
        gTask.Function = Fnc;
        gTask.Delay = Del;
        gTask.Period = Per;
        gTask.RunMe = 0;
        return Index;
}

BOOL DeleteTask(UINT8 Index)
{
        BOOL Return_Code;
        if (gTask.Function == 0)
        {
                gErrorCode = ERROR_CANNOT_DELETE_TASK;
                Return_Code = FALSE;
        }
        else
        {
                Return_Code = TRUE;
        }
        gTask.Function = NULL;
        gTask.Delay = 0;
        gTask.Period = 0;
        gTask.RunMe = 0;
        return Return_Code;
}


__________________________________________main.c_______________________________
void Task1(void)
{
任务必须返回,处理时间要小于调度时间
}
................
void main(void)
{
//添加任务

AddTask(Task1);
//下面的就不用管了
SchedulerStart();

   for (;;)
   {               
      SchedulerDispatchTask();
   }
}

ATmega32 发表于 2007-11-19 13:43:54

协作式的任务是要返回的,协作式有个很大的优点就是可以不必给任务分配堆栈,不单独分配堆栈空间,任务占用的总堆栈空间是任务中使用堆栈空间最大的一个。


假设有5个任务,实际堆栈空间使用最大值分别是80,80,80,80,100,分配堆栈裕量是20,

不考虑中断
采用协作式,使用最大总堆栈空间是100,如果需要给总堆栈分配一个空间加上裕量是100+20=120
采用抢占式,给任务分配的空间分别是100,100,100,100,120,总共是100+100+100+100+120=520

如果考虑中断用栈没有与任务用栈分开,假设中断用栈是40,裕量10
采用协作式,如果需要给总堆栈分配空间 120+50=170
采用抢占式,给任务分配的空间分别是 (100+50)+(100+50)+(100+50)+(100+50)+(120+50)=770

省RAM空间是很大的。任务越多,节省空间越大。



抢占式调度占用RAM空间绝大部分都是分配给任务堆栈。
还有抢占式任务切换的时候,进栈,出栈也要花费大量时间。

如果出现了

//假设中断是开放的
OS_ENTER_CRITICAL();//执行后,SREG.7=0,cpu_sreg.7=1
OS_ENTER_CRITICAL();//执行后,SREG.7=0,cpu_sreg.7=0
OS_EXIT_CRITICAL();//执行后,cpu_sreg.7=0,SREG.7=0
OS_EXIT_CRITICAL();//执行后,cpu_sreg.7=0,SREG.7=0

amwox 发表于 2007-11-19 14:16:16

看来是理解的问题.
void A (void)
{
   OS_ENTER_CRITICAL();//
   ................
   OS_EXIT_CRITICAL();//
}
void B(void)
{
   OS_ENTER_CRITICAL();//
   A();
   OS_EXIT_CRITICAL();//
}

这种嵌套是没问题的.
但,下面这种就有问题了.
void B(void)
{
   OS_ENTER_CRITICAL();//
....
   OS_ENTER_CRITICAL();//
   A();
   OS_EXIT_CRITICAL();//
....
   OS_EXIT_CRITICAL();//
}
这根本上是错误的,没有意义,必须避免.
OS_ENTER_CRITICAL();//表示进入关键代码
OS_EXIT_CRITICAL();//表示退出键代码
必须配对使用.
同样,在同一个函数中,OS_MutexLock 与OS_MutexUnLock也必须配对使用

ATmega32 发表于 2007-11-19 14:21:20

我的意思是嵌套,就像括号一样,(与)成对。
那么嵌套括号就是(……(……)……).
对应就是
OS_ENTER_CRITICAL();
……
OS_ENTER_CRITICAL();
……
OS_EXIT_CRITICAL();
……
OS_EXIT_CRITICAL();

liguangqang 发表于 2007-11-19 14:33:50

强烈支持楼主,先一下了,系统开销情况怎么样,还有怎不能写个使用手册的,方便大家移植和使用.

mbit 发表于 2008-4-9 10:37:57

支持楼主,学习一下

dgxll 发表于 2008-4-9 12:24:05

楼主厉害,向楼主学习

yzlyear 发表于 2008-4-9 14:16:27

强人

ndust 发表于 2008-4-9 15:50:41

强,记号

hushenghong 发表于 2008-5-21 13:02:05

谢谢

ba_wang_mao 发表于 2008-5-21 16:30:14

我看得眼花撩乱!

wenwu 发表于 2008-5-21 16:48:55

写OS不用太多资金投入,希望网站能组织个嵌入式OS的开源项目,重在学习,呵呵。

jackiezeng 发表于 2008-5-21 17:07:29

mark

microyao 发表于 2008-5-22 23:42:06

标记一下.

Inside 发表于 2011-6-30 21:56:43

mark!

fk2011 发表于 2011-7-9 10:12:50

严重学习当中。

8s209 发表于 2012-2-27 22:21:57

学习

gxy508 发表于 2012-2-28 11:13:37

mark

HoldMyARM 发表于 2012-2-28 11:45:11

mark

mypc16888 发表于 2012-2-29 11:02:22

看看

river0830 发表于 2012-5-20 22:13:43

学习中,谢谢楼主分享

buttonsjj 发表于 2012-5-21 10:02:00

强烈希望网站能建个嵌入式OS的群,重在学习。

luckseason 发表于 2013-9-11 10:51:06

牛人。。。

龙之舞者 发表于 2013-9-18 17:50:56

mark 回帖是个好习惯

cmj201003 发表于 2013-9-27 13:45:17

学习!!!!!!!

cxning 发表于 2013-9-27 13:49:44

学习,不过好像看不懂.
页: [1]
查看完整版本: 我写的嵌入式操作系统,现在传上来与大家共同探讨!