【问题标题】:Task scheduling - controlling the execution of a function任务调度——控制一个函数的执行
【发布时间】:2011-03-22 09:59:05
【问题描述】:
在一个嵌入式项目中,我们应该实现一个具有不同优先级的任务调度程序,项目实现是用 C 语言实现的,并在Arduino 设备上运行。
现在我们处于研究阶段,突然出现一个问题,但没有人有足够的经验来给出确定的答案:
如何控制函数的执行时间?我们如何在函数返回之前跟踪时间,以便在发生超时时中断它?
一个建议是使用fork(),但由于 Arduino 不包含操作系统,因此没有内核来处理线程。还是我错了?
任何意见都会有所帮助,非常感谢,
【问题讨论】:
标签:
c
embedded
scheduling
arduino
interrupt
【解决方案1】:
你需要一个计时器。所有非协作式多任务系统(即那些不依赖函数来一直说“你现在可以打断我”的系统)使用计时器在一段时间后(比如 100 毫秒)停止执行。
在中断处理程序中,检查是否有另一个“线程”可以运行和切换上下文。
一个非常简单的实现是“就绪列表”:只要任务或线程可以做一些工作,就将其添加到就绪列表中。
当计时器触发时,将当前任务添加到列表的末尾,并使列表的头部成为当前任务。
【解决方案2】:
在嵌入式系统中,任务调度程序是操作系统(通常是 RTOS)的核心,因此您被要求实现一个而不是来使用一个。
Jean Labrosse 的引导Micro C/OS-II 中描述了这样一个调度程序如何工作的简单示例。它描述了带有调度和 IPC 的完整 RTOS 内核。对于您的项目,您可以获取此核心的描述并实现您自己的(或者您可以使用包含的源代码)。
这样的内核通过在某些操作系统调用和定时器中断上进行调度来工作。上下文切换涉及存储一个任务的处理器寄存器,然后用另一个任务的寄存器替换。因为这个寄存器保存/恢复包括堆栈指针和程序计数器,所以控制在线程之间切换。
可能需要更简单的调度形式(而不是抢占式)调度。一种方法是实现任务函数,这些函数运行到完成,并在必要时存储自己的状态并作为状态机实现,然后有一个简单的循环来轮询计时器并根据调度表调用每个“任务”函数(即包括任务的周期性和指向其函数的指针,也就是说每秒调用一个函数,而每毫秒调用另一个函数。