所有SWI任务共享一个堆栈,SWI任务只能在程序编制时预先定义好。DSP/BIOS中对任务的动态产生和对阻塞状态的支持是通过TSK模块来实现的。TSK有15个优先级,也是可以抢断的,但是每个TSK任务使用独立的堆栈。TSK任务是通过TSK_create()和TSK_delete()来动态生成和结束的。它的运行状态如图2所示。
5 同步(SEM/ATM/QUE/MBX)
多任务系统中多个任务之间的协调同步工作可以通过多种方法来实现。常用方法如信号量、原子量、队列和邮箱等。在DSP/BIOS中对这些方法的支持分别通过模块SEM、ATM、QUE和MBX来实现。由于这些方法的使用与一般的操作系统完全一样,在这里就不再赘述了。仅就最灵活的在SWI中使用Mailbox的方法来加以简单地说明。每个SWI任务都带有一个Mailbox,对它的操作可以是计数型的SWI_inc()、 SWI_dec() 也可以是比特位操作型的 SWI_or()、 SWI_andn()。Mailbox控制SWI任务被调度的条件。这些操作的功能如表2所示。
or操作是将Mailbox中的某一位置1,同时引起SWI任务的调度。当一个SWI任务可能由多个事件触发时,使用or操作可以方便地表示出触发的事件。如例3使用or操作指示触发事件:
andn操作是将Mailbox中的某一位清0,如果Mailbox为0,则引起SWI任务的调度。一个SWI任务需要多个条件都满足时才运行的情况下,使用andn操作可以方便地表示出这些条件的状态。如例4用andn操作来表示多条件时SWI任务调度:
inc和dec操作则更加灵活,用户可以借此实现多种应用。唯一需要注意的是,inc操作总是引起任务调度,而dec操作仅在Mailbox减到0时才引起一次任务调度。
6 通讯(PIP/SIO/HST)
一个系统如何从外部设备中取得数据,向外部设备输出数据,如何在两个任务之间进行数据正常交换是多样灵活的。但是这种多样性也给软件的维护升级以及模块化工作带来许多不利因素。因此在保持多样性的同时,保持接口的一致性对于一个软件来说是非常有帮助的。考虑到DSP大多数是通过某种类型的串行接口如中继线E1、IIS、SPI、同步串行口等与外部设备进行数据交换的,所以在DSP/BIOS中提供了两种非常有用的接口对象PIP和 SIO。
PIP对象包含一个缓冲队列,与之对应的有两个任务读和写。图3很好地说明了PIP的逻辑关系和操作方式。例5,例6分别是一个PIP对象对应的读任务和写任务的示范程序。