搜索
bottom↓
回复: 34

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

[复制链接]

出0入0汤圆

发表于 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)


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

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2007-11-19 12:04:40 | 显示全部楼层
强。有没有OS讨论群?

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

出0入0汤圆

 楼主| 发表于 2007-11-19 12:41:28 | 显示全部楼层
我的QQ还开不了群,有兴趣加我156388624,发消息MircoROS

出0入0汤圆

发表于 2007-11-19 13:01:31 | 显示全部楼层
我认为在小型MCU,特别是小RAM的MCU,没必要用抢先式调度,并且给每个任务都分配堆栈。
任务多了,RAM占用量是很大的。
不如用协作式,也不必给任务单独分配堆栈。占用RAM量将减小很多。

出0入0汤圆

发表于 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()//
嵌套的话,会不会有危险?

出0入0汤圆

 楼主| 发表于 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()//
在嵌套时是不会有危险的,可以放心使用的

出0入0汤圆

发表于 2007-11-19 13:31:24 | 显示全部楼层
强人,我一直想用一个,可是自己写不出来,终于。。。。

出0入0汤圆

 楼主| 发表于 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_ERRORS  0

#define TICKS_PER_SEC  100
#define SCH_MAX_TASKS  3

#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[SCH_MAX_TASKS];
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);




void  SchedulerInit (void)
{
        UINT32 freq;

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

void SchedulerStart(void)
{

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

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

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

void SchedulerDispatchTask(void)
{
        UINT8 Index;
        for (Index = 0; Index < SCH_MAX_TASKS; Index++ )
        {
                if ((gTask[Index].RunMe > 0))
                {
                        if (gTask[Index].Function != NULL)
                                (*gTask[Index].Function)();
                        gTask[Index].RunMe --;
                        if (gTask[Index].Period == 0)
                        {
                                gTask[Index].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[Index].Function != NULL) && (Index < SCH_MAX_TASKS))
        {
                Index++;
        }
        if (Index == SCH_MAX_TASKS)
        {
                gErrorCode = ERROR_TOO_MANY_TASKS;
                return SCH_MAX_TASKS;
        }
        gTask[Index].Function = Fnc;
        gTask[Index].Delay = Del;
        gTask[Index].Period = Per;
        gTask[Index].RunMe = 0;
        return Index;
}

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


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

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

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

出0入0汤圆

发表于 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

出0入0汤圆

 楼主| 发表于 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也必须配对使用

出0入0汤圆

发表于 2007-11-19 14:21:20 | 显示全部楼层
我的意思是嵌套,就像括号一样,(与)成对。
那么嵌套括号就是(……(……)……).
对应就是
OS_ENTER_CRITICAL();
……
OS_ENTER_CRITICAL();
……
OS_EXIT_CRITICAL();
……
OS_EXIT_CRITICAL();

出0入4汤圆

发表于 2007-11-19 14:33:50 | 显示全部楼层
强烈支持楼主,先一下了,系统开销情况怎么样,还有怎不能写个使用手册的,方便大家移植和使用.

出0入0汤圆

发表于 2008-4-9 10:37:57 | 显示全部楼层
支持楼主,学习一下

出0入0汤圆

发表于 2008-4-9 12:24:05 | 显示全部楼层
楼主厉害,向楼主学习

出0入0汤圆

发表于 2008-4-9 14:16:27 | 显示全部楼层
强人

出0入0汤圆

发表于 2008-4-9 15:50:41 | 显示全部楼层
强,记号

出0入0汤圆

发表于 2008-5-21 13:02:05 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2008-5-21 16:30:14 | 显示全部楼层
我看得眼花撩乱!

出0入0汤圆

发表于 2008-5-21 16:48:55 | 显示全部楼层
写OS不用太多资金投入,希望网站能组织个嵌入式OS的开源项目,重在学习,呵呵。

出0入0汤圆

发表于 2008-5-21 17:07:29 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-5-22 23:42:06 | 显示全部楼层
标记一下.

出0入0汤圆

发表于 2011-6-30 21:56:43 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-7-9 10:12:50 | 显示全部楼层
严重学习当中。

出0入0汤圆

发表于 2012-2-27 22:21:57 | 显示全部楼层
学习

出0入0汤圆

发表于 2012-2-28 11:13:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-28 11:45:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-29 11:02:22 | 显示全部楼层
看看

出0入0汤圆

发表于 2012-5-20 22:13:43 | 显示全部楼层
学习中,谢谢楼主分享

出0入0汤圆

发表于 2012-5-21 10:02:00 | 显示全部楼层
强烈希望网站能建个嵌入式OS的群,重在学习。

出0入0汤圆

发表于 2013-9-11 10:51:06 | 显示全部楼层
牛人。。。

出0入0汤圆

发表于 2013-9-18 17:50:56 | 显示全部楼层
mark 回帖是个好习惯

出0入0汤圆

发表于 2013-9-27 13:45:17 | 显示全部楼层
学习!!!!!!!

出0入0汤圆

发表于 2013-9-27 13:49:44 | 显示全部楼层
学习,不过好像看不懂.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 00:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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