OS21操作系统——概述

来源:互联网 发布:java 解压加密zip文件 编辑:程序博客网 时间:2024/06/10 06:16

1.OS21概述

   OS21是一个免费、轻量级的多任务实时操作系统,基于OS20 API设计,使用GNU工具进行编译,gdb进行调试。目前OS21主要用于ST公司的机顶盒主芯片(ST40/ST200)中,与应用程序一道生成单一映象文件,具有相同的地址空间与名字空间,以及相同的特权模式。

   OS21采用了多优先级、占先式的任务调度算法,任务之间使用信号量、互斥锁、事件标签进行同步;使用消息队列进行通信。实时事件由中断处理,并使用信号量与任务通信。任务所需的内存分配方案由用户选择,任务优先级可指定。提供的主要功能有:

(1)基于256级的多优先级、可占先式调度;

(2)信号量(semaphores);

(3)互斥锁(mutexes);

(4)消息队列(message queues);

(5)高精度定时器;

(6)存储管理;

(7)中断处理;

(8)节省存储空间。

 

从性能上讲,OS21提供的任务间切换时间小于2.6us,中断响应时间最小为1.5us,整个代码小于30KB,数据小于5KB。

OS21使用面向对象编程风格,每个主要的OS21系统服务由一个类来表示,例如:存储分区、任务、信号量、互斥量等。类的实例被分配在系统分区或用户自定义分区中,不使用时需要回收其占用空间。


2.OS21与OS20的异同点

    OS21与OS20提供的系统服务比较相似,调用的API函数名称也很相似,具体来说包含下列API

    (1) Kernel API

    (2) Memory and partitions

    (3) Tasks and scheduler APIs

    (4) Semaphore API

    (5) Memory API

    (6) Time API

    但OS20针对ST20 CPU进行开发,OS21则针对ST40 CPU进行开发,二者在BSP部分存在较大不同。

    头文件:与OS20相比,OS21采用了意义更明确的头文件。如下:

OS21操作系统鈥斺敻攀 
    内核启动:OS20提供了两种方式来启动内核:手动和自动方式(在编译时通过添加 -runtime os20实现),OS21通常只使用手动方式来启动内核。尽管也可实现自动启动。

   int main(void)

  {

     kernel_initialize(NULL);

     kernel_start();

     kernel_timeslice(OS21_TRUE);

     ...

   }

    OS21的时间片功能缺省为关闭,要使用时需要手动打开。

    任务方面:与OS20相比,当改变任务的优先级时,该任务在队列中的位置也发生了变化。

    OS20使用了两个预定义的内存空间——system_partion与internal_partion,用户也可访问,在OS21中则没有这两个空间,而需要自行分配。在OS21中的堆内存既可由C运行库函数(malloc和free)管理,也可由OS21自身管理。

    通常情况下OS20中所有的_init()函数均被_create()所代替,尽管_init()函数的优点在于内存分配的灵活性,OS21采取了一个不同的解决办法来增加灵活性:除了_create()函数外,还增加了_create_p()函数来定义partition指针。这在存储空间紧张的系统中,可由应用程序自己选择从哪块空间中分配。如图:下列_init()函数都将由_create()或_create_p()函数代替。

    message_init_queue()

    message_init_queue_timeout()

    partition_init_fixed()

    partition_init_heap()

    partition_init_simple()

    semaphore_init_fifo()

    semaphore_init_fifo_timeout()

    semaphore_init_priority()

    semaphore_init_priority_timeout()

    task_init()

    中断和缓存:OS20的中断和缓存API与ST20的中断缓存体系结构紧密相关,其目的是为了完全使用上硬件的特性。在缓存的设计上,OS21遵循了与OS20一样的设计思想,即根据具体芯片设计,每款芯片都有不同的API,当然也不同于OS20。而OS21提供的中断则具有通用性,可在不同芯片间移植,这一点不同于OS20。二维块数据移动:由于二维块数据移动严格与ST20芯片结构相关,OS21已去掉了这方面内容。

    时间管理:在OS21中,时钟由64位的整型osclock_t表示,而在OS20中则为32位的整型类型clock_t。

    此外,OS21还提供了一些OS20所不具备的功能:例如task event flag等。


3、内核介绍

为了实现多优先级的任务调度,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运行的总时间。


4、对于ST平台上的OS21系统介绍

系统框架图示:


主要特性如下:



原创粉丝点击