调度器,极小资源单片机值得一用(转)

源:再出个调度器,极小资源单片机值得一用

自认为有如下特点:

1)  超级可以移植性,与CPU无关,几乎任何支持C语言编程的CPU都可以用!(本文仅仅以51单片机为例而已,但实际上可以任意移植)
2)  小之又小, 原理很简单,一看就懂。
3)  省之又省, 可以说对RAM和ROM省到极致。
4)  取protothread之精华,将定时器与状态机和伪线程语法融合到一个框架,任务函数可以有两种写法。
5)  基于定时器触发,调度效率高,最大化减少无效的代码运行时间。

***********************************************************/
 #include <stc89c51.h>
 #include <stdio.h>

 /*****************小小调度器部分开始********************************************/
 #define  _SS   static char lc=0; switch(lc){   case 0: lc=0;
 #define  _EE   }; lc=0;
 #define  WaitX(a,b)  settimer(&lc,__LINE__,a,b); return ; case __LINE__:
 struct TASK {
   char td;
   void (*fp)();
 };
 #define MAXTASKS 5
 struct TASK tasks[MAXTASKS];

 //设置定时器
void settimer(char *lc,char  line,char  tmrid,int d){
   *lc=line;
   tasks[tmrid].td=d;
 }
 //逻辑定时器处理,在定时器中断里调用
void dectimers() {
 unsigned char i;
 for (i=0;i<MAXTASKS;i++){
    if (tasks[i].td>0)  tasks[i].td--;
 }
 }
 //任务调度函数,在main里面运行
void runtasks() {
    unsigned char i;
    for(i=0;i<MAXTASKS;i++)
    {
      if (tasks[i].fp!=0){
            if (tasks[i].td==0){
              tasks[i].td=-1;
              tasks[i].fp();
                 }
          }
         }
 }
 /****************小小调度器部分结束*******************************************************/

sbit KEY = P3^2;
 unsigned char code numtab[16]={0x24,0x6F,0xE0,0x62,0x2B,0x32,0x30,0x67,0x20,0x22,0x21,0x38,0xB4,0x68,0xB0,0xB1};

 sfr IAP_CONTR = 0xC7;
 sfr WDT_CONTR = 0xC1;

 //清除看门狗
void clr_wdt()
 {
   WDT_CONTR =0x3C;
 }

 //初始化定时器
void InitT0()
 {
         TMOD = 0x21;
         IE |= 0x82;  // 12t
         TL0=0Xff;
         TH0=0Xb7;
         TR0 = 1;
 }
 //定时器中断
void INTT0(void) interrupt 1 using 1
 {
         TL0=0Xff;    //10ms 重装
        TH0=0Xb7;
         dectimers();
 }

 sbit LED1= P2^4;  

 //任务一,状态机写法
void ontimer0(){
   LED1=!LED1;  // LED1引脚接在发光管负极,LED1=0 为亮,LED1=1为灭。

  //重装定时器
  if (LED1) tasks[0].td=45;  //450mS 灭
  else tasks[0].td=5;  //50ms  亮
}

 //任务二,状态机写法
char keycount=0;
 void task1(){
 if(KEY==0) {
    keycount++;
    if (keycount>20) IAP_CONTR = 0x60;  //持续按下键1秒,将重启并进入固件升级
}
else{
     keycount=0;
 }
 //重装定时器
tasks[1].td=5;
 }

 //任务三,伪线程写法
void  task2()
 {
 static char i;
 _SS

 while(1){

 for(i=0;i<=9;i++){   //从0--9快速显示,间隔200mS
    WaitX(2,20);         //    等待200mS,实际是设置定时器2为200mS
    P1=numtab[i];
 }
 for(i=0;i<=9;i++){ //从0--9慢速显示,间隔500mS
    WaitX(2,50);       //    等待500mS,实际是设置定时器2为500mS
    P1=numtab[i];
 }
 }

 _EE
 }

 void main()
 {
         unsigned char         KeyNum;
         P3M0 = 0x00;
         P3M1 =0x00;
         //WDT_CONTR= 0x00;   //关闭看门狗
        P1 = 0xff;         //关显示

          clr_wdt();

         InitT0();

         KEY =1;                                //按键IO口
        KeyNum=0;                        //按下次数

    //装载任务:
         tasks[0].fp=ontimer0;
         tasks[1].fp=task1;
         tasks[2].fp=task2; 

     //循环调度
        while(1){
          runtasks();
          clr_wdt();
         }
 }

优化无止境!呵呵,330楼看似不能再优化了,但我再尝试做一次优化:

敬请评测该版本,看是否还能优化:

/****小小调度器开始**********************************************/
#define MAXTASKS 2
static unsigned char timers[MAXTASKS];
unsigned char currdt;
#define _SS static unsigned char _lc; switch(_lc){default:
#define _EE ;}; _lc=0; return 255;
#define WaitX(tickets)  do {_lc=__LINE__+((__LINE__%256)==0); return tickets ;} while(0); case __LINE__+((__LINE__%256)==0):
#define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); }  while(0);

#define CallSub(SubTaskName) do { _lc=__LINE__+((__LINE__%256)==0); return 0; case __LINE__+((__LINE__%256)==0):  currdt=SubTaskName(); if(currdt!=255) return currdt;} while(0);
#define UpdateTimers() unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}

#define SEM unsigned int
//初始化信号量
#define InitSem(sem) sem=0;
//等待信号量
#define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
//等待信号量或定时器溢出, 定时器tickets 最大为0xFFFE
#define WaitSemX(sem,tickets)  do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;  return 1;} } while(0);
//发送信号量
#define SendSem(sem)  do {sem=0;} while(0);

/*****小小调度器结束*******************************************************/

sbit LED1 = P2^1;
sbit LED2 = P2^2;

void InitT0()
{
        TMOD = 0x21;
        IE |= 0x82;  // 12t
        TL0=0Xff;
        TH0=0XDB;//22M---b7;
        TR0 = 1;
}

void INTT0(void) interrupt 1 using 1
{
    UpdateTimers();

    TL0=0Xff;    //10ms 重装
    TH0=0XDB;//b7;
}

void  task1(){
_SS
  while(1){
   WaitX(50);
   LED1=!LED1;
  }
_EE
}

void  task2(){
_SS
  while(1){
   WaitX(100);
   LED2=!LED2;
  }
_EE
}

void main()
{
        InitT0();
        while(1){
           RunTask(task1,0);
           RunTask(task2,1);
    }
}

在keil下编译,又减少了18字节的ROM(超过10%了)。应该运行效率会更高。

------------------以下为说明-----------------------------------

小小调度器任务函数的写法主要注意的,主要有三点:

1) 任务函数内部变量,建议都用静态局部变量来定义。
2) 任务函数内不能用switch语句。
3) 任务函数内,不能用return语句。 因为return已经被赋予任务延时的特定意义。(这是返回型任务函数版本的一个强制要求)

这三点,并不会明显造成写程序的不方便。
---------------------------
从裸奔到使用OS操作系统或调度系统的代价主要有:

硬件资源代价(对RAM和ROM的消耗),学习代价(学会其原理,并掌握其用法),移植代价(往不同cpu上移植的工作量),效率代价(使用调度系统后带来的额外cpu负担),商业代价(版权费用),稳定性代价(是否引入潜在不稳定因素,或者增大bug跟踪调试工作量)。

从这几方面来讲,应用小小调度器的代价,都是非常小的。
1) 硬件资源代价: 前面的优化版本已经说明问题。keil下,本例程ram消耗 : 22字节,rom消耗126字节.
2) 学习代价: 小小调度器总共只有十多行代码,如果我们做一个简单的解释说明,理解起来其实是很快的。我相信学习时间比其他调度系统要短。
3) 移植代价: 几乎没有什么移植工作量,对于各种cpu,几乎是通吃。
4) 效率代价: 我们一直在努力优化,相信调度效率已经不低了。比如任务切换时间,应该是可以做到uS级别,甚至亚uS级别。
5) 商业代价: 小小本调度器为免费使用,无需支付任何费用。
6) 稳定性代价:小小调度器本质上仅仅是几个宏而已,未涉及任何对内部寄存器或堆栈的操作,避免了引入不稳定风险因素,所有操作都在可预见,可把控的前提下进行。
--------------------------------------------------------------------------

本调度器的宗旨是:以最小的代价,实现基于自然语法的多任务并行处理机制。并具备代码的高度可以移植性。
每个任务占用3个字节RAM。任务数量没有限制。

其工作原理很简单,大家可在此基础上任意DIY自己的调度方法。

时间: 2024-08-29 03:12:55

调度器,极小资源单片机值得一用(转)的相关文章

【大数据技术干货】阿里云伏羲(fuxi)调度器FuxiMaster功能简介(三) 针对在线服务的资源强稳定

免费开通大数据服务:https://www.aliyun.com/product/odps 转载自xingbao 各位好,这是介绍阿里云伏羲(fuxi)调度器系列文章的第三篇,今天主要介绍针对在线服务的资源强稳定 一.FuxiMaster简介 FuxiMaster和Yarn非常相似,定位于分布式系统中资源管理与分配的角色:一个典型的资源分配流程图如下所示: 作为调度器,目前FuxiMaster支持的功能主要有: 1.多租户管理 2.支持FIFO/FAIR调度策略 3.针对在线服务保持资源强稳定(

Hadoop YARN 调度器(scheduler) —— 资源调度策略

本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/hadoop_yarn_resource_scheduler 搜了一些博客,发现写得最清楚的还是<Hadoop权威指南>,以下内容主要来自<Hadoop The Definitive Guide> 4th Edition 2015.3. Hadoop YARN Scheduler 三个调度器 YARN提供了CapacityScheduler, Fai

朴素的UNIX之-调度器细节

0.多进程调度的本质 我们都知道UNIX上有一个著名的nice调用,何谓nice,当然是"好"了,常规的想法是nice值越大越好,实际上,nice值越好,自己的优先级越低,那么为何不用badness呢? 事实上,如果我们理解了操作系统多进程调度系统是一个"利他"系统,这个问题就不是个问题了.nice当然还是好,不是对自己好,而是对别人好.利他系统 是一个人人为我我为人人的系统,类似还有TCP流量控制和拥塞控制,人类的宗教社会组织等等,利他系统都有一个负反馈机制,让波

CFS调度器

一.前言 随着内核版本的演进,其源代码的膨胀速度也在递增,这让Linux的学习曲线变得越来越陡峭了.这对初识内核的同学而言当然不是什么好事情,满腔热情很容易被当头浇灭.我有一个循序渐进的方法,那就是先不要看最新的内核,首先找到一个古老版本的内核(一般都会比较简单),将其吃透,然后一点点的迭代,理解每个版本变更背后的缘由和目的,最终推进到最新内核版本. 本文就是从2.4时代的任务调度器开始,详细描述其实现并慢慢向前递进.当然,为了更好的理解Linux调度器设计和实现,我们在第二章给出了一些通用的概

【转】Go调度器原理浅析

goroutine是golang的一大特色,或者可以说是最大的特色吧(据我了解),这篇文章主要翻译自Morsing的[这篇博客](http://morsmachine.dk/go-scheduler),我读这篇文章的时候不只是赞叹调度器设计的精巧,而且被Unix内核设计思想的影响和辐射所震撼,感觉好多好东西都带着它的影子. 绪论(Introduction)---------------------Go 1.1最大的特色之一就是这个新的调度器,由Dmitry Vyukov贡献.新调度器让并行的Go

Kubernetes 第十七章 调度器

来自: https://www.jianshu.com/p/acb34a1d1b6e Kubenernetes 调度器介绍 Kubernetes 调度器介绍 kube-scheduler是 kubernetes 系统的核心组件之一,主要负责整个集群资源的调度功能,根据特定的调度算法和策略,将 Pod 调度到最优的工作节点上面去,从而更加合理.更加充分的利用集群的资源,这也是我们选择使用 kubernetes 一个非常重要的理由.如果一门新的技术不能帮助企业节约成本.提供效率,我相信是很难推进的.

进程调度, 一个调度器的自白

我是一个进程调度器. 我的职责是调度计算机内所有的进程,为他们分配 CPU 资源. 1. 批处理时代 想当初,操作系统创造我时,只是打算让我用 FCFS 调度算法,简单维护下进程的秩序.但我后来的发展,远远超过了他的想象. 1.1 FCFS 所谓 FCFS 就是「先来先服务(First Come First Serve)」,每个进程按进入内存的时间先后排成一队.每当 CPU 上的进程运行完毕或者阻塞,我就会选择队伍最前面的进程,带着他前往 CPU 执行. 就拿这几个进程来说吧: 按照 FCFS

kubernetes调度及调度器性能调优

kubernetes调度器在kubernetes中,调度指的是将新生成的pod调度到合适的Node节点上,然后Node上对应的kubelet才能运行pod. 1.调度概述调度器通过kubernetes的watch机制来发现新生成的且未调度到Node上的pod.调度器会将发现的每一个未调度的pod调度到合适的Node上运行,调度器会使用以下所述的调度原则来做出调度选择. 2.kube-schedulerkube-sceduler时kubernetes集群中默认调度器,并且是集群控制面的一部分,ku

Yarn 调度器Scheduler详解

理想情况下,我们应用对Yarn资源的请求应该立刻得到满足,但现实情况资源往往是有限的,特别是在一个很繁忙的集群,一个应用资源的请求经常需要等待一段时间才能的到相应的资源.在Yarn中,负责给应用分配资源的就是Scheduler.其实调度本身就是一个难题,很难找到一个完美的策略可以解决所有的应用场景.为此,Yarn提供了多种调度器和可配置的策略供我们选择. 一.调度器的选择 在Yarn中有三种调度器可以选择:FIFO Scheduler ,Capacity Scheduler,FairS ched