每个任务都有阻塞延时,以释放CPU使用权,使其他任务有机会运行,多任务系统中,时基切换频繁,所以使用时基列表统一管理很有必要

[TOC]

1.简介

每个任务都有阻塞延时,以释放CPU使用权,使其他任务有机会运行,多任务系统中,时基切换频繁,所以使用时基列表统一管理很有必要

2.设置时基列表有关函数以及变量

添加全局变量

  1. OSCFG_TICK_WHEEL_SIZE(时基列表宽度)
  2. OSTickCtr(时基列表计数变量)
  3. OSCfg_TickWheel[ size] 时基列表

    变量类型(OS_TICK_SPOKE)

  4. NbrEntriesMax
    时基列表成员包含的单项链表最大节点数
  5. NbrEntries
    时基列表成员当前链表节点数
  6. FirstPtr
    时基列表成员当前链表第一个节点
    (以上三个变量的类型皆为OS_TICK_SPOKE类型,OS_TICK_SPOKE是32位无符号整型重定义)

    添加任务控制块成员

  7. TickNextPtr
     链表的下一位
  8. TickPrevPtr
     链表的上一位
  9. TickSpokePtr
     链表的根部
  10. TickCtrMatch
    等于OSTickCtr加上TickRemain的值
  11. TickRemain
    还剩余的等待时间,每个TICK自减
    (以上为时基列表主要成员)

    链表实现函数

    OS_TickListInit(),用循环来初始化时基列表所有成员有关的数据域=0
    初始化的目标变量如下:
    • NbrEntriesMax;
    • NbrEntries;
    • FirstPtr;

      往时基列表插入一个任务TCB(OS_TickListInsert())

  12. 传入任务TCB,以及延时时间
  13. 判断该链表有没有节点
    (1)无则直接插入到第一个节点
    (2)有则和每个节点比较剩余延时时间,插到时间比他短后面一位
        ((1)和(2)主要配置的TCB参数是链表的上下位及链表根部,用来联系链表)
  14. 在插入成功后刷新spoke里面Nbr的值
  15. 把插入的tcb根指针指向根节点

    从时基列表删除一个指定的节点(OS_TickListRemove())

  16. 传入任务TCB
  17. 确定任务在链表里面
  18. 将要删除的任务时间清零
  19. 判断任务TCB的位置
    (1)第一个节点
             直接配置对应配置;
    (2)不是第一个
             保存前后节点;
             断开TCB前后联系;
             将前后重新连接;
  20. 复位删除的任务TCB里面时基列表相关成员
  21. Nbr减少1

    更新计数器Ctr,扫描时基判断任务是否到期(OS_TickListUpdate())

  22. 进入临界段
  23. 索引链表(每次调用只扫描一个)
  24. while()循环;扫描链表的第一个节点,判断时间是否到期,没到期则退出,到期则继续扫描后面的节点,让到期任务都就绪(链表的排序是按就绪准备时间来计算)
     就绪函数-从时基列表删除、在插入就绪任务
  25. 退出临界段

3.调用流程

  1. 初始化
    编写一个初始化函数创建变量,调用清除函数,清除对应数据表。
  2. 调用
    在每一个延迟函数里面执行
    1. 插入时基列表
    2. 从就绪列表移除
  3. 时基更新
    在每一个TICK中断任务里面加入更新时基列表