多任务操作系统主要有两种:抢占式和协作式。两者都允许在系统中定义多个任务,不同之处在于任务切换的工作方式。当然,只有一个核心处理器,一次实际上只运行一个任务。
两种类型的多任务操作系统都需要为每个任务使用单独的堆栈。因此,这意味着两件事:首先,处理器允许将堆栈放置在RAM中的任何位置,因此具有指令来移动堆栈指针(SP)-即,不存在像低端那样的专用硬件堆栈PIC的。这省去了PIC10、12和16系列。
您几乎可以完全用C语言编写OS,但是SP随处移动的任务切换器必须处于汇编状态。在不同的时候,我都为PIC24,PIC32、8051和80x86编写了任务切换器。胆量都完全不同,具体取决于处理器的体系结构。
第二个要求是要有足够的RAM来提供多个堆栈。通常,一个堆栈至少需要几百个字节。但是,即使每个任务只有128个字节,八个堆栈也将需要1K字节的RAM,尽管您不必为每个任务分配相同大小的堆栈。请记住,您需要足够的堆栈来处理当前任务以及对其嵌套子例程的任何调用,而且还需要一个中断调用的堆栈空间,因为您永远不知道何时会发生。
有相当简单的方法来确定每个任务要使用多少堆栈。例如,您可以将所有堆栈初始化为特定值,例如0x55,然后运行系统一段时间,然后停止并检查内存。
您没有说要使用哪种PIC。大多数PIC24和PIC32将有足够的空间来运行多任务OS。PIC18(唯一在RAM中具有堆栈的8位PIC)的最大RAM大小为4K。因此,这还真不容易。
使用协作式多任务处理(两者中的较简单者),仅当任务“将其控制权”交还给OS时才执行任务切换。每当任务需要调用OS例程以执行它将等待的某些功能(例如I / O请求或计时器调用)时,就会发生这种情况。这使操作系统更容易切换堆栈,因为不必保存所有寄存器和状态信息,因此可以将SP切换到另一个任务(如果没有其他任务可以运行,则空闲堆栈是给定控制权)。如果当前任务不需要进行OS调用但已经运行了一段时间,则需要自动放弃控制以保持系统响应。
协作式多任务处理的问题是,如果任务永不放弃控制权,它将使系统瘫痪。只有它和碰巧得到控制的所有中断例程都可以运行,因此操作系统似乎会锁定。这是这些系统的“合作”方面。如果实现了仅在执行任务切换时复位的看门狗定时器,则有可能捕获这些错误的任务。
Windows 3.1和更早版本是协作操作系统,这部分是其性能不那么出色的原因。
抢占式多任务处理更难实现。在此,不需要手动放弃任务,而是可以为每个任务提供最大的运行时间(例如10毫秒),然后如果有一个任务,则将任务切换到下一个可运行任务。这要求任意停止一个任务,保存所有状态信息,然后将SP切换到另一个任务并启动它。这使任务切换器更加复杂,需要更多的堆栈,并使系统速度降低了一点。
对于协作式和抢占式多任务处理,中断可以随时发生,这将暂时抢占正在运行的任务。
正如supercat在评论中指出的那样,协作多任务处理的一个优点是共享资源更加容易(例如,诸如多通道ADC之类的硬件或诸如修改链表之类的软件)。有时,两个任务希望同时访问同一资源。通过抢占式调度,操作系统可能会使用资源在一项任务的中间切换任务。因此,必须使用锁来防止其他任务进入并访问同一资源。对于协作式多任务处理,这不是必需的,因为任务控制着何时将其自身释放回操作系统。