首页 文章

VxWorks信号

提问于
浏览
2

我对VxWorks论坛中提出的上一个问题有疑问 . 我的目标是当高优先级函数生成一个信号时,低优先级函数将立即处理它(高优先级函数必须被抢占)

代码是:

sig_hdr () { ... }
task_low_priority() {
    ...
    // Install signal handler for SIGUSR1
    signal(SIGUSR1, sig_hdr);

    ...
}

task_high_priority() {
    ...
    kill(pid, SIGUSR1); //pid is the ID of task_low_priority
    ...
}

行后: signal(SIGUSR1, sig_hdr); 我添加 taskDelay(0) . 我想阻止高优先级任务,所以低优先级任务可以获得CPU以执行信号处理程序,但除非我做 taskDelay(1) 否则它不会发生 .

任何人都可以解释为什么它不适用于 taskDelay(0)

3 回答

  • 1

    这正是我不明白低优先级任务在高优先级任务运行时如何获得一些CPU时间的重点?

    高优先级任务将继续运行直至被阻止 . 如果它被阻止,那么准备运行的低优先级任务将运行 .

  • 0

    我的回答有两部分:1 . 如何正确使用任务延迟与vxWorks 2. TaskDelay不是您的问题的正确解决方案

    第一部分:

    vxWorks中的TaskDelay可能会混淆:

    taskDelay(0) - 根本不执行延迟!

    它是调度程序从CPU中删除当前任务的命令 . 如果这仍然是系统中的最高优先级任务,它将返回到队列的头部而没有任何延迟 . 如果调度程序配置为FIFO以便在具有相同优先级的情况下执行任务并且您的任务具有要运行的CPU实时使用者功能,则可以使用此命令,可以尝试以相同的优先级释放CPU以执行其他任务(不错) .

    顺便说一句,它与taskDelay(NO_WAIT)相同 .

    TaskDelay(1) - 这将在零(!!!)到1系统节拍之间的某个时间延迟调用任务 . vxWorks的延迟在圆形系统滴答处完成 .

    TaskDelay(2) - 在1个系统滴答到2个系统滴答之间的某个时间 .

    3 ......(明白......)

    TaksDelay(-1)(A.K.A taskDelay(WAIT_FOREVER)) - 将永远延迟任务(不推荐) .

    第二部分:

    使用taskDelay启用低优先级任务可能是错误的想法 . 您没有提供所有问题信息,但请注意,延迟高优先级任务不会确保您的低优先级任务将运行(无论您将编写的睡眠时间如何) . 高优先级和低优先级任务中具有最高优先级的其他任务可能会针对所有“睡眠时间”运行 . vxWorks中有几种同步方法,如二进制信号量,更改任务优先级,信号,......

  • 0

    实际上,taskDelay(0)不会让低优先级任务运行,原因如下:

    • 高优先级任务正在执行

    • 高优先级任务问题taskDelay(0)
      调用

    • 调度程序并扫描下一个要运行的任务,它将选择"ready"的最高优先级任务

    • 发出taskDelay(0)的任务已准备就绪,因为延迟已过期(即已经过了0个滴答)

    • 因此,高优先级任务立即重新安排,在这种情况下,taskDelay(0)实际上是浪费CPU周期 .

    现在,在您发出taskDelay(1)的情况下,遵循相同的步骤,但区别在于高优先级任务未处于就绪状态,因为尚未经过一个滴答,因此准备好的低优先级任务可以具有1个CPU时间滴答,然后它将被高优先级任务抢占 .

    现在有一些设计不良的系统可以做以下事情:

    taskLock();
    ...
    taskDelay(0);
    ...
    taskUnlock();
    

    为了使低优先级任务占用CPU,直到某个点然后允许高优先级任务通过发出taskDelay(0)来接管 . 但是,如果您玩这样的游戏,那么您应该重新考虑您的设计 .

    同样在你的情况下我会考虑一个更健壮的系统,而不是做一个taskDelay()来允许一个低优先级的任务来处理一个事件,你应该发送一个消息到一个低优先级的任务,并具有该低优先级的任务来处理该消息队列 . 虽然您的高优先级任务会阻塞由您的事件处理程序或类似的东西给出的信号量 . 在这种情况下,您希望在两个不同的任务之间强制执行ping pong以完成任务,但是如果您添加一个充当缓冲区的队列,那么只要您的系统是可调度的(即有足够的时间来响应)对所有事件,排队并完全处理它们)然后它会工作 .


    Update

    我假设你的系统应该是这样的:

    • 事件发生(中断驱动?) .

    • 高优先级任务运行以收集数据 .

    • 数据由低优先级任务处理 .

    如果是这种情况,您想要遵循的模式实际上非常简单,实际上只需要完成一项任务即可完成:

    中断处理程序收集数据,并向任务发送消息(msgQSend()) . 使用msgQReceive的消息队列上的任务正在等待处理 .

    但是,如果我对您的系统有更多了解(您真正想做什么)以及为什么使用posix调用而不是本机vxworks调用,它可能会有所帮助 .


    如果您不熟悉实时系统,您应该了解Rate单调分析,维基百科上有一个非常简短的摘要:

    http://en.wikipedia.org/wiki/Rate-monotonic_scheduling另请注意,在VxWorks中,“高优先级”为0,“低优先级”为255,实际数字与其含义成反比:D

相关问题