OS21操作系统——kernel

为了实现多优先级的任务调度,OS21使用了一个很小的调度内核,确保当前运行的任务总是 处于最高调度优先级。
   
    内核执行
    内核始终维护下列信息:
    1) 当前正在运行的是哪一个任务;
    2) 当前准备运行的一个任务队列。
    当需要作出调度决策时,该内核被调用,总的来说有下列四种情形:
    1)低优先级的任务被高优先级的任务占先;
    2)当一个任务停止调度,例如当该任务等待的消息队列为空时,此时内核会检查任务队列
,选择优先级最高的任务投入运行;
    3)调度器会周期性地分时检查当前执行的任务,如果有与该任务同等优先级的任务,则会
选择处于前列的任务投入运行,而备份当前任务状态;
    4)当一个中断结束,此时没有其他低优先级的任务运行,内核被调用
  
   开始OS21内核
    通过调用下列函数来开启内核。
       if(kernel_initialize(&kernel_init_struct) != OS21_SUCCESS)
        {
               printf("Error : initialise.kernel_initialize failed\n");
               exit(EXIT_FAILURE);
        }
       if(kernel_start() != OS21_SUCCESS)
        {
               printf("Error : initialise.kernel_start failed\n");
               exit(EXIT_FAILURE);
        }

    Kernel_initialize()与kernel_start()函数一般在main函数体中,且只能被调用一次。其中kernel_initialize()初始化任务和队列数据结构,当数据结构被创建后,当前正在调用的任务被初始化为root任务,并具有最高优先级,在该任务中会调用bsp_initialize()。调用kernel_initialize()会设置所需的内存空间,如果sys_heap_base为NULL,则sys_heap_size为空,OS21会调用malloc来分配空间,否则会调用memory_allocate()来分配。如果system_stack_base为NULL,system_stack_size为0,则OS21会从系统heap中分配堆栈空间,其大小为缺省值。
Kernel_start()在kernel_initialize()之后,在任何任务被创建之前被调用,用于开
始占先式的任务调度策略。该函数也会调用bsp_start()。

    kernel_start()的关键代码如下:

int kernel_start (void)

{

  if (_kern_state == KERNEL_STATE_UNINITIALIZED)

  {

    return (OS21_FAILURE);

  }

  ......

  if (_kern_state == KERNEL_STATE_INITIALIZED)

  {

    _scheduler_start ();  

    _interrupt_start (); 

    _md_timer_start (); 

    atexit (_kernel_shutdown);

    bsp_start ();  

    _md_kernel_start_system (); 

    _kern_state = KERNEL_STATE_STARTED;

  }

  OS21_TRACE((TRC_KERNEL, "kernel started OK"));

  return (OS21_SUCCESS);

}

  

这里依然用到了静态变量KERNEL_STATE_UNINITIALIZED,为真时会开启优先级调度器(这里开启了一个优先级为0的空闲任务,使得调度器开始运行),中断服务初始化、开启定时器中断,并注册退出时的回调函数等。还增加了一个静态变量KERNEL_STATE_STARTED表示kernel开始运行。_md_kernel_start_system()用于使一些底层代码得以运行。

OS21中开启/关闭时间片轮转通过显式调用kernel_timeslice()来实现,如下:

void kernel_timeslice (int on)

{

  OS21_TRACE((TRC_KERNEL, "timeslice %s", on ? "on" : "off"));

  if (on)

  {

    _md_timer_timeslice_on ();

  }

  else

  {

    _md_timer_timeslice_off ();

  }

}

比如_md_timer_timeslice_on()用于打开时间片轮转功能,该函数实际上是设置芯片的PLL定时复位寄存器,超时时间即为时间片大小,具体参见CPU芯片手册。

此外,关于kernel的时间方面的API,还有kernel_idle()与kernel_time(),前者获得idle任务所运行的时间,后者获得kernel运行的总时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值