打印

关于即将开源的HotTask51的任务优先级调度问题及讨论

[复制链接]
5351|32
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hotpower|  楼主 | 2009-2-17 19:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*------------------------------------------------------------------------------------
        HotTaskPriorityTickCount位名定义及优先级处理过程简要说明
HotTask51采用和Linux类似的动态优先调度算法。(但HotTask51的级别0最小,7最大,共8个任务)

TickCount每次在节拍中断中所有任务被遍历减一,当跳变为 0时表示该任务时间片用完,进入
就绪状态。若遍历时遇到多个跳变为0的任务时,表示有相同的优先级在同一时间片内发生冲突
故需要对同级任务进行再判,但HotTask51采用从最低优先级任务开始遍历,遍历过程中如遇到
TickCount跳变为 0,则立即将任务号入保存该节拍中断的就绪寄存器中,注意被挂起的任务除外

最后跳变就是该同级任务的最高级别的任务。它就会第1个被切换。
注意遍历时,TickCount跳变为 0时ready都会被置1 并一直被保存到切换时ready被清零!!!

故HotTask51任务优先级可以相同,这个要优于ucOS-II任务不能同级别优先的缺点.
当然我们应该尽量来避免同级任务给系统的“实时”带来不必要的麻烦。
故HotTask51也建议任务不要同级。但HotTask51自身具备动态优先级调度的设计不应该产生非议。


HotTask51时从“裸奔”来考虑和设计及处理问题的,它不追求大而全,"强实时"等华丽的外表。
故HotTask51的6个用户设计的非常紧凑,故能充分地合理利用51十分紧张的系统资源。

HotTask51从工控的特点来构建OS,为区别它们儿拒绝更名带有“OS”的字样~~~
并腾出一个任务作为用户初始化任务和运行期间的看门狗监视任务。它与普通任务执行看门狗任务
有些本质的区别,及时用户设置某最高级任务单独执行看门狗监视系统环境。

但它肯定不如系统自绑定且可为硬件看门狗提供挂钩函数的狗任务~~~

况且该内核的编程是由“狗论”的“缔造者”菜农同志集20年之精华“友情赞助”~~~

HotTask51优先级和节拍计数器位定义
HotTask51在创建任务时:
Priority=1~6
TickCount=7-Priority或TickCount=~Priority=6~1
--------------------------------------------------------------------------------*/
typedef volatile struct
{
    HotTask_REG    TickCount:        3;//0 每次进入HotTaskTick时减一,初值为7-Priority
    HotTask_REG    ready:            1;//5 该任务就绪,只要TickCount-1=0即被置1,遍历=0
    HotTask_REG    Priority:        3;//4 在创建任务时的优先级1~6
    HotTask_REG    Suspend:        1;//7 该任务已被挂起(初始化为1,即无此任务)
                                  //  被挂起的任务不参与就绪和切换的处理
}HotTask_BITS_PriorityTickCount, *HotTask_BITS_pPriorityTickCount;

typedef volatile union
{
    HotTask_REG                        Regs;//以寄存器字节访问
    HotTask_BITS_PriorityTickCount     Bits;//以寄存器位访问
}HotTask_REG_PriorityTickCount, *HotTask_REG_pPriorityTickCount;


谢谢参与~~~特别是“阶级敌人”们~~~

相关帖子

沙发
HotTask51| | 2009-2-17 19:30 | 只看该作者

自己先坐沙发~~~孤独呀~~~期待吴教授和俺PK~~~

使用特权

评论回复
板凳
Airwill| | 2009-2-17 19:35 | 只看该作者

好啊

 千呼万唤, 有点要出来了.

1. TickCount 只给3bit 是不是紧了点?
2. 两个同优先级的就绪任务的调度, 数据结果里没有支持, 不知道怎么处理?

使用特权

评论回复
地板
HotTask51| | 2009-2-17 19:40 | 只看该作者

敬请“阶级敌人”先支招~~~(礼让三先)~~~

使用特权

评论回复
5
HotTask51| | 2009-2-17 20:44 | 只看该作者

关于智能实现同级优先平均获得时间片问题(非典)

“阶级敌人”们会从HotTaskPriorityTickCount位的构架中看出

50年代的人有多么地“节约闹革命”~~~

从HotTask51的动态优先调度算法实现叙述中可以看出“红色脑浆”的再现~~~

它之精华:

1.用一局部变量来记录某节拍中断时遍历任务就绪(--TickCount==0)时
  它会在其高4位的位域中加一,即+=0x10,同时将被中断的任务号及TaskID
  覆盖填入到其低4位。
  当其遍历结束后,若>=0x20时,即至少有2个任务在此期间就绪。
  此变量命名为readyCount,初值为0x00,即高4位=0,无就绪任务出现,
  低4位=0,表示切换任务号即TaskID=0,即空闲任务。
  俺觉得这样解释和命名是比较合理的。
  注意readyCount的累加条件(Suspend=1即被挂起的任务不累加):
  1.满足--TickCount==0。
  2.满足ready==1,即上次被“同类抛弃”的高优先任务

2.请特别留意ready位,它在任务就绪而被高级别任务不受规则,不再被事先
  约定的同级互让时,ready永远为1,故其在后面的节拍中断时,由于节拍
  计数(记录)器TickCount只有3位,且在就绪跳变时被Priority所覆盖,
  故此次虽参加遍历且被减一,但未满足就绪跳变的条件--TickCount==0,
  故ready不会被改动,即保留原状态ready=1.
  故readyCount。
  HotTask51这么做合理吗???是特点吗???

下面是关于主题---关于智能实现同级优先平均获得时间片问题之探讨

51一般都有2个以上的硬件定时器,其中有1个给HotTask51使用,其他为用户
  自己所有。
  
  在OS为“单核”即一个硬件定时器的环境下,所谓的时间片可能会成为一句空话!!!
  
同级的“无赖势力”可能在为大家事先约定的时间片里,不进行协作
式的OS,那么,HotTask51想降低这些无赖势力的破坏采取的“扶贫”

政策就会“代代流传”...上次的“可怜人”成了新的无赖~~~
那么HotTask51的好心就随之东流~~~

那么如何智能地对付这些无赖分子呢???
我们可以向布什同志学习,以“打击恐怖”为由,建立快速反应
部队~~~

HotTask51将在事先未经用户的同意下,强征其未用之定时器来
实现真正的时间片即“双核多线程”之“高科技”~~~

若用户定时器用满且和HotTask51“签下”了协议,默认在紧急状态
下,HotTask51有权在其“中断隐身”期间,将其降级(以后再谈如何实现)

因为系统节拍中断默认最低级硬件中断,但所有硬件中断在其隐身
后都被纳入了HotTask51的任务体系!!!

但他们的“任务级别”虽然属于“7级”,但都低于同级的“狗任务”

所以,HotTask51的狗任务对整个系统拥有绝对和生杀大权,如软件
复位!!!

所以暂且抛开主题而论,“阶级敌人”置顶的“探讨: OS 和看门狗的问题”

对于俺自封的“狗论之缔造者”而言,都是白讨论~~~

所以,HotTask51的路还会有些时日,但其“红色的思想”绝不次于
任何地球人!!!!

菜农深深地明白~~~




使用特权

评论回复
6
hotpower|  楼主 | 2009-2-17 23:14 | 只看该作者

刚和小菜农的探讨又有更合理的想法,解决了“霸权问题”

而且不动用其他空闲定时器。(这样做将会时代码更复杂和管理困难)

新算法比较合情合理~~~

以后再论~~~

使用特权

评论回复
7
Airwill| | 2009-2-18 12:03 | 只看该作者

呵呵,

能成为 hotpower 的"敌人", 也是荣幸的哦!

看来得保持清醒的头脑, 随时给 hot 以当头一棒, 保持"敌人"的作为.

言归正传: 我倒是有个办法.
 给 ready 的任务,增加一个没有被执行的呀延迟计时器.

当然得保证同优先级的任务, 能够不会有相同的等待时间.
初步想来, 应该不难办到.

只是, 又给 Systick() 增加工作内容了

使用特权

评论回复
8
hotpower|  楼主 | 2009-2-18 17:22 | 只看该作者

“老头舌战群孩”结束,菜农胜出~~~正式开工~~~

最后结论:

1.统一的任务(包括和任务有关所有处理)及事件(硬件中断)的调度机制

2.保证在所有7个用户任务和事件下的同级任务严格在1个节拍内按时间片分配。

3.本算法只用9个全局char变量和一个局部char变量.

4.支持基本52下所有的硬件中断。

5.开工。

6.太非典了~~~


注:比以前的思路多出1个任务。

即:
任务0: 空闲任务
任务1~7:用户任务

事件0~6:MCS52标准中断事件
事件7:  系统看门狗、用户初始化事件

使用特权

评论回复
9
学生D| | 2009-2-18 22:26 | 只看该作者

有意思。

 在OS为“单核”即一个硬件定时器的环境下,所谓的时间片可能会成为一句空话!!!
*******************************************************************
那别人为什么做得到?

看这个51_RTOS, 既有任务切换,——用户不依赖OS而进行实时切换(所谓布什的快速反应部队);又有系统切换,——OS时间片切换,(时间片可由用户设置变长)。并且二者可以同时作用,且只用了一个定时器2。

还有一个大概没想到:任务故障死循环时,无法自行切换,这时系统切换起了作用,时间片超时事件发生,OS中止了故障任务程序,切换到新的任务开始运行,——看门狗啊。

使用特权

评论回复
10
HotC51| | 2009-2-19 00:58 | 只看该作者

回答楼上2个问题

1.非法关总中断即EA=0
2.真的强实时并无任务时间片超时可以发生,因为OS本身定义的就是死循环。
  故任务死循环本身就是对的~~~
  所以无什么“故障”而言。

  要言,这个我认为是“协作OS”的概念~~~

使用特权

评论回复
11
HotC51| | 2009-2-19 02:10 | 只看该作者

今天正式开战~~~

interface
{
    HotTask_IREG iSystemStart;//0x55aa系统上电测试变量
//任务级别    在HotTaskTick()中用于同级任务循环扫描
    HotTask_REG_PriorityReadyQueue PriorityReadyQueue[HotTask_MaxCount];//就绪队列
//................
}HotTask_Interface;

/*------------------------------------------------------------------------------
    HotTask51任务优先就绪队列HotTask_BITS_PriorityReadyQueue类型接口定义
HotTask51中所有涉及任务的操作,某任务的挂起、就绪状态,及原始优先级别和遍历计数
等都是通过本定义实现。
其中:
#define interface typedef struct//COM接口定义
--------------------------------------------------------------------------------*/
interface
{//任务“遍历从低字节到高字节”---任务ID升序遍历,任务1~任务7
    HotTask_REG    ReadyCount:        3;//0 初值为PrioValue
    HotTask_REG    ReadyBit:        1;//5 该任务就绪位,只要ReadyCount-1=0即被置1
    HotTask_REG    Priority:        3;//4 初值为(TaskPriority^7)<<3
    HotTask_REG    Suspend:        1;//7 该任务已被挂起(初始化为1,即无此任务)
                                  //  被挂起的任务不参与就绪和切换的处理
}HotTask_BITS_PriorityReadyQueue, *pHotTask_BITS_PriorityReadyQueue;

/*------------------------------------------------------------------------------
    HotTask51任务优先就绪队列HotTask_BITS_PriorityReadyQueue类型联合定义
HotTask51中所有位域操作涉及都加入联合以便可以用字节和位分别访问。
--------------------------------------------------------------------------------*/
typedef volatile union
{//以数组表示[8]
    HotTask_REG                        Regs;//以寄存器字节访问
    HotTask_BITS_PriorityReadyQueue Bits;//以寄存器位访问
}HotTask_REG_PriorityReadyQueue, *pHotTask_REG_PriorityReadyQueue;

/*---------------------------------------------------------------------------------
    HotTask51任务函数向量表接口IHotTask_TaskVtbl_Interface类型定义
HotTask51中涉及任务函数数组及任务函数指针数组的,都将以类COM接口封装。
采用COM接口技术的最大好处是将C语言通过其类型的定义,即可对接口内的成员(函数、变量)
如同Delphi/C++/C#/Jave/VB.Net等高级语言一样,灵活的访问其所有成员。
-----------------------------------------------------------------------------------*/

interface
{
    void (*Task0)(void);//注意:和真的任务0名称Task0一样对仿真大有好处
    void (*Task1)(void);//建议将其和实际名称一致,虽然可以任意取名
}IHotTask_TaskVtbl_Interface, *pIHotTask_TaskVtbl_Interface;

typedef volatile union
{
/*----------------------------------------
     以函数名检索
----------------------------------------*/
    IHotTask_TaskVtbl_Interface Pointer;
/*------------------------------------------------------------------------------------------------
    以函数数组检索。请注意:一定要用计算来得到数组的个数,这样可随意增添任务而不改程序
-------------------------------------------------------------------------------------------------*/
    pHotTaskFUNC Array[sizeof(IHotTask_TaskVtbl_Interface) / sizeof(pHotTaskFUNC)];
}IHotTask_Task_Interface;

/*--------------------------------------------------------------------------
    HotTask51事件优先就绪位队列HotEvent_BITS_PriorityReadyQueue类型接口定义
HotTask51中的“事件”就是MCU中的硬件中断,它于中断使能寄存器定义完全等同。
只是HotTask51将其总中断使能位作为其
--------------------------------------------------------------------------*/
interface
{//事件“遍历从高位到低位”---位左移遍历,若有扩展,增加搜索
    HotEvent_REG    EX0_ReadyBit:        1;//0外部中断0事件就绪位
    HotEvent_REG    ET0_ReadyBit:        1;//1定时器0事件就绪位
    HotEvent_REG    EX1_ReadyBit:        1;//2外部中断1事件就绪位
    HotEvent_REG    ET1_ReadyBit:        1;//3定时器1事件就绪位
    HotEvent_REG    ES_ReadyBit:        1;//4串口事件就绪位
    HotEvent_REG    ET2_ReadyBit:        1;//5定时器2事件就绪位(HotTaskTimer)
    HotEvent_REG    EINT_EnableBit:        1;//6 扩展事件使能位主要为以后扩展事件
    HotEvent_REG    Wdt_Init_ReadyBit:    1;//7 系统狗任务和用户初始化任务
                                          //(只有此位与51对应的EA定义不同)
}HotEvent_BITS_PriorityReadyQueue, *pHotEvent_BITS_PriorityReadyQueue;


/*------------------------------------------------------------------------------
    HotTask51事件优先就绪队列HotEvent_REG_PriorityReadyQueue类型定义
HotTask51中所有位域操作涉及都加入联合以便可以用字节和位分别访问。
--------------------------------------------------------------------------------*/
typedef volatile union
{//以数组表示[x]
    HotEvent_REG                     Regs;//以寄存器字节访问,和51的IE定义相同
    HotEvent_BITS_PriorityReadyQueue Bits;//以寄存器位访问
}HotEvent_REG_PriorityReadyQueue, *pHotEvent_REG_PriorityReadyQueue;

/*---------------------------------------
        HotTaskLock
----------------------------------------*/
typedef volatile struct
{
    HotTask_REG    TaskIdle:        1;//0
    HotTask_REG    TaskUser1:        1;//1
    HotTask_REG    TaskUser2:        1;//2
    HotTask_REG    TaskUser3:        1;//3
    HotTask_REG    TaskUser4:        1;//4
    HotTask_REG    TaskUser5:        1;//5
    HotTask_REG    TaskUser6:        1;//6
    HotTask_REG    TaskWdt_Init:    1;//7
}HotTask_BITS_Lock, *HotTask_BITS_pLock;

typedef volatile union
{
    HotTask_REG        Regs;
    HotTask_BITS_Lock         Bits;
}HotTask_REG_Lock, *HotTask_REG_pLock;


/*---------------------------------------
        HotTaskId
----------------------------------------*/

typedef volatile struct
{
    HotTask_REG    HotTaskForeId:    3;//0
    HotTask_REG    Reserved1:        1;//3
    HotTask_REG    HotTaskBackId:    3;//4
    HotTask_REG    Reserved2:        1;//7
}HotTask_BITS_ID, *HotTask_BITS_pID;


typedef volatile union
{
    HotTask_REG        Regs;
    HotTask_BITS_ID         Bits;
}HotTask_REG_ID, *HotTask_REG_pID;

使用特权

评论回复
12
学生D| | 2009-2-19 10:03 | 只看该作者

是咬文嚼字故意狡辩,还是....

2.真的强实时并无任务时间片超时可以发生,因为OS本身定义的就是死循环。
  故任务死循环本身就是对的~~~
  所以无什么“故障”而言。

  要言,这个我认为是“协作OS”的概念~~~
******************************************************************
谁都知道,你做的是“协作OS”,何来强实时?
既然“协作OS”,就不可能是一个任务单独占据过长的时间片。OS会以一种合理的方式对各个任务进行管理,由不得用户任务意愿。

假设任务A正常运行到某一时刻T,需要延时一段时间X,OS设计当然使A在这时刻T之后退出运行,把CPU资源让给其它任务。如果A任务在T时刻之前受到干扰,出现故障死循环,——我们常说的“崩溃”,那么就运行不到延时程序,也就无法正常退出当前任务并让出CPU资源,即使你是强实时,假设长时间没有其他优先级任务事件发生时,难道你的OS允许A任务“故障死循环”一直“非法不正常占有”CPU资源,而认为它是正常的吗?你不怕这种故障循环范围越来越大,“殃及无辜”吗?

算了吧,一个OS,连任务内部循环是正常还是故障都不能分辨,那叫什么OS?

使用特权

评论回复
13
学生D| | 2009-2-19 10:42 | 只看该作者

再说“狗论”。(接上贴)

假设当A任务出现故障无法正常让出CPU资源时,强实时模式下,HOT的OS中任务7看门狗要起作用了。可是问题来了:

任务7的喂狗时间肯定要设置得比较大,至少要大于6个任务正常完成的时间和,——假设为T6。

那么上面任务A崩溃时,故障发生经过T6时间流逝,硬件看门狗起了作用。(119终于来了。)有什么问题?

1、响应比裸奔狗还慢;
2、本来可以设计使OS及时响应,拉正错误,偏要设计一条迟钝的笨狗;
3、任务A故障时,其他任务以及管理者——OS内核都是正常的。结果这条笨狗偏不要OS管理,它要自己干,要复位机器,使所有一切重新来过。

这就好像,一个公司里,有一个人犯错,结果要所有的人,——包括老板,都停止工作,重新来过。

   这个OS比裸奔还钝。

使用特权

评论回复
14
hottask51| | 2009-2-19 10:49 | 只看该作者

谢谢!!!等开源代码公开后再论是协作还是OS及实时

正在编写~~~

使用特权

评论回复
15
hotpower|  楼主 | 2009-2-20 02:14 | 只看该作者

52的ram确实太小,脑晕





使用特权

评论回复
16
hotpower|  楼主 | 2009-2-20 07:19 | 只看该作者

晕~~~

使用特权

评论回复
17
lhj200304| | 2009-2-23 09:42 | 只看该作者

看看

看看和陈明计的那个相比是否更优秀

使用特权

评论回复
18
01dxwlm| | 2009-2-23 16:11 | 只看该作者

晕吖,怎么会是如此雷同

"TickCount每次在节拍中断中所有任务被遍历减一,当跳变为 0时表示该任务时间片用完,进入
就绪状态。若遍历时遇到多个跳变为0的任务时,表示有相同的优先级在同一时间片内发生冲突
故需要对同级任务进行再判,但HotTask51采用从最低优先级任务开始遍历,遍历过程中如遇到
TickCount跳变为 0,则立即将任务号入保存该节拍中断的就绪寄存器中,注意被挂起的任务除外

最后跳变就是该同级任务的最高级别的任务。"
看了hotpower 的这个论述怎么和我目前做的是一模一样,只是你的是--,我的是++;
看我的:
void    OSTimerTick(void)
{
    OS_TCB    *ptcb;
    OS_TCB    *ptcbend;
    INTOS    prio;

#if    OS_TASK_IDLE_EN > 0

    OSTime++;
    if(OSTime == OS_TICKS_PER_SEC)
    {
        OSTime = 0;
        OSCpuFree = OSIdleCtr * OS_CPUFREE_FACTOR >> 20;
        OSIdleCtr = 0;
    }
#endif

    prio = 0;
    ptcbend = &OSTCBTbl[OS_LOWEST_PRIO];
    ptcb = OSTCBTbl;

    while(ptcb <= ptcbend)
    {
        if(ptcb->TimerPeriod != 0)
        {
            ptcb->TimerCnt++;

            if(ptcb->TimerCnt >= ptcb->TimerPeriod)
            {
                ptcb->TimerCnt = 0;
                OSISREventSend(prio,OS_EVENTID_TIMER);
            }
        }
        ptcb++;
        prio++;
    }
}
"
if(ptcb->TimerCnt >= ptcb->TimerPeriod)
            {
                ptcb->TimerCnt = 0;
                OSISREventSend(prio,OS_EVENTID_TIMER);"这不就是了吗?

使用特权

评论回复
19
hotpower|  楼主 | 2009-2-23 21:43 | 只看该作者

18楼的俺已彻底抛弃了17楼所述及其师傅们之理论~不必更好

使用特权

评论回复
20
hotpower|  楼主 | 2009-2-24 02:05 | 只看该作者

菜农的“零耗时键盘OS理论”雷翻了Linux的动态优先调度算法

想与18楼01dxwlm再次讨论任务调度资源再优化问题

首先我们的方法没什么雷同问题,因为想做OS的都能想到这个主意。

这个方法实际类似Linux的动态优先调度算法,它的初值是任务的级别。
并初始化级别就绪计数器。

每次节拍中断时,计数器依据此值逐次递减,减到零时认为该任务就绪。

楼主位的思路是为每个任务都配置一对,因为他们的初值及级别不同,

想到每组的配备无可厚非。

但是仔细分析后感觉没必要,观点论述如下:

因为考虑同级问题,为区分快捷和不排序,遍历时对每个任务的就绪

计数器作递减操作,至零则就绪。

俺又考虑强实时,故将节拍加速,及倍频为8.

这样就绪计数器的初值就变成了级别的8倍。

由于我又改变了设计,0级别最高且为事件而非任务服务,

这样级别1要8个节拍后才递减为0而就绪,若其他7个任务级别都为1时

第8个节拍后这7个任务都将就绪,但由于考虑强实时问题,这7个任务

必须依次在各自的节拍内就绪。

注意:这里每个级别被中断了8次,原来一个节拍10mS,现在实际变为

10ms/8=1.25mS.

这8个节拍首个节拍(0级别)为系统事件(俺定义级别高于任务)

这样完全满足了强实时的要求。

那么为了继续节约,若是一个就绪计数器都不要了又将如何???

俺被菜农“零耗时键盘”的时间片轮询思想所迷惑,更被“扫而不描”

之“理论”所雷翻~~~故设想如下:

1.设置一个公用的节拍计数器,永远没有初值(初始化为0后一直滚动+1)
2.规定此节拍计数器的低3位D2D1D0为同级优先的该任务的级别。
  高3位D5D4D3为任务的序号。最高2位无意思。
任务级别表:
(键盘列)(键盘行)
  任务0:    级别0(恒为最高0)
  任务1:    级别1
  任务2:    级别2
  任务3:    级别1
...................
当节拍计数器运行(注意"键盘"的扫而不描)时,

注意下面“扫描”的次数为8进制。
00次:(“扫而要描”--就绪,任务级别表里有任务0,级别0)
    D5D4D3=0即“键盘的0行”,OS任务级别0
    D2D1D0=0即“键盘的0列”,OS任务序号0---系统任务就绪
01次:(“扫而不描”,任务级别表里没有任务1,级别0)
    D5D4D3=0即“键盘的0行”,OS任务级别0
    D2D1D0=1即“键盘的1列”,OS任务序号1
02次:(“扫而不描”,任务级别表里没有任务2,级别0)
    D5D4D3=0即“键盘的0行”,OS任务级别0
    D2D1D0=2即“键盘的2列”,OS任务序号2
.....................................................
07次:(“扫而不描”,任务级别表里没有任务7,级别0)
    D5D4D3=0即“键盘的0行”,OS任务级别0
    D2D1D0=7即“键盘的7列”,OS任务序号7
.....................................................
10次:(“扫而不描”,任务级别表里没有任务0,级别1)
    D5D4D3=1即“键盘的1行”,OS任务级别1
    D2D1D0=0即“键盘的0列”,OS任务序号0---系统任务强行就绪
11次:(“扫而要描”--就绪,任务级别表里有任务1,级别1)
    D5D4D3=1即“键盘的1行”,OS任务级别1
    D2D1D0=1即“键盘的1列”,OS任务序号1---任务1级别1就绪
12次:(“扫而不描”,任务级别表里没有任务2,级别1)
    D5D4D3=1即“键盘的1行”,OS任务级别1
    D2D1D0=2即“键盘的2列”,OS任务序号2
13次:(“扫而要描”--就绪,任务级别表里有任务3,级别1)
    D5D4D3=1即“键盘的1行”,OS任务级别1
    D2D1D0=3即“键盘的3列”,OS任务序号3---任务3级别1就绪
.....................................................
17次:(“扫而不描”,任务级别表里没有任务7,级别1)
    D5D4D3=1即“键盘的1行”,OS任务级别1
    D2D1D0=7即“键盘的7列”,OS任务序号7
20次:(“扫而不描”,任务级别表里没有任务0,级别2)
    D5D4D3=2即“键盘的2行”,OS任务级别2
    D2D1D0=0即“键盘的0列”,OS任务序号0---系统任务强行就绪
21次:(“扫而不描”,任务级别表里没有任务1,级别2)
    D5D4D3=2即“键盘的2行”,OS任务级别2
    D2D1D0=1即“键盘的1列”,OS任务序号1
22次:(“扫而要描”--就绪,任务级别表里有任务2,级别2)
    D5D4D3=2即“键盘的2行”,OS任务级别2
    D2D1D0=2即“键盘的2列”,OS任务序号2---任务2级别2就绪
..........................................................

看看上面的“零耗时键盘”运行结果和任务级别表的就绪是否一致
00次:(“扫而要描”--就绪,任务级别表里有任务0,级别0)
10次:(“扫而不描”,任务级别表里没有任务0,级别1)
    D2D1D0=0即“键盘的0列”,OS任务序号0---系统任务强行就绪
11次:(“扫而要描”--就绪,任务级别表里有任务1,级别1)
13次:(“扫而要描”--就绪,任务级别表里有任务3,级别1)
20次:(“扫而不描”,任务级别表里没有任务0,级别2)
    D2D1D0=0即“键盘的0列”,OS任务序号0---系统任务强行就绪
22次:(“扫而要描”--就绪,任务级别表里有任务2,级别2)
再看看任务级别表:
(键盘列)(键盘行)
  任务0:    级别0(恒为最高0)00次,10次,20次
  任务1:    级别1 11次 (因为它比任务2,2级别高,故在第1*8+1=9次时就绪)
  任务2:    级别2 22次 (因为它比任务3级别低,故在第2*8+2=18次时就绪)
  任务3:    级别1 13次 (因为它比任务2级别高,故在第1*8+3=11次时就绪)

“零耗时键盘”中的“扫而不描”把人雷翻了~~~


昨天菜农用5个位(不到1个字节)雷翻了4×8×16位任务函数指针即64个字节
现在用6个位D5D4D3D2D1D0替代了至少7个任务级别就绪计数器。

那么2天菜农之“战果”为:
用5+6=11位算2字节雷翻了64+7=71个字节~~~

71个字节对于MCS51单片机可怜的RAM而言,真是“功德无量”呀~~~

再次感谢“苍天”~~~“感谢菜农80年代的零耗时键盘OS理论”~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1538

主题

21697

帖子

506

粉丝