【问题标题】:How to ensure consistency of data between two execution loops如何确保两个执行循环之间的数据一致性
【发布时间】:2020-06-09 14:44:48
【问题描述】:

我一直在开发基于 FreeRTOS 操作系统的控制软件。从时序上看,软件可以分为两个循环。

在模数转换结束时以 100 us 的周期调用第一个执行循环(快速循环 (FL))。在每第四次执行快速循环后调用第二个执行循环(慢循环 (SL))。所以控制软件的时序可以用下面的时序图来描述

我需要确保快速循环和慢速循环之间共享的数据的一致性。慢速循环必须在其整个执行时间内使用在快速循环第四次执行结束时有效的数据值。

我一直在思考如何保证上述数据的一致性。我的第一个想法是使用一些全局变量(比如说mutex)

typedef enum
{
    SLOW_LOOP_RUNNING,
    SLOW_LOOP_WAITING
}MutexState

MutexState mutex; 

将以原子方式使用。例如,如果慢循环开始计算,它首先执行

mutex = SLOW_LOOP_RUNNING;

在慢循环执行结束时执行

mutex = SLOW_LOOP_WAITING;

快速循环始终监控mutex 变量的状态,如果它发现互斥锁包含SLOW_LOOP_RUNNING 值,它不会覆盖共享变量。我认为这可以工作,但我不喜欢全局变量。有没有人有更好的想法如何解决这个问题?提前感谢您的任何建议。

【问题讨论】:

  • 您的操作环境是什么? (例如Linux,用户进程,内核模块);其他的?
  • 听起来您的程序将受益于 DMA 而不是轮询。您必须捕获每个 ADC 样本的原因是什么?这是某种信号处理方式吗?
  • @Lundin,感谢您的反应。也许我的表情很笨拙。正如我试图通过上图描述的那样,一旦触发 SL 执行,SL 使用的共享变量的值就不能受到 FL 执行的影响。
  • 我要问的是:您要解决的实际问题是什么?因为这看起来像一个奇怪的解决方案。为什么需要并行处理?为什么需要循环?为什么需要 100us 的最后期限?
  • 我的问题是如何确保 SL 与 FL 共享的变量在 SL 执行期间具有固定值(尽管 FL 刷新它们,但 SL 必须使用在第四个末尾有效的值FL的执行)。 FL执行周期100us与PWM频率耦合。就循环而言。 FL 应实现感应电机的转矩控制回路。 SL 应执行其他不太重要的任务。

标签: c embedded task data-synchronization


【解决方案1】:

如果数据很小,我会发送/复制它。特别是如果您已经在使用fork(),您可以使用pipes (ex)。您的快速循环在每第 4 个循环中可以write(buf) 将数据传输到管道 fd,然后慢速循环可以从其中read(buf)。更好的是,如果您只想在接收到来自第 4 个快速循环周期的数据后运行慢速循环循环,您可以select() 仅在有数据要从管道读取时运行慢速循环功能。与互斥锁相比,这种方法应该更干净且不易出错,完全避免数据竞争;允许您将慢循环任务视为纯粹的功能性任务。

【讨论】:

  • 您好 JWCS,感谢您的反应。我喜欢你关于管道(队列)的想法,但我一直在考虑实施。我的意图是让 FL 和 SL 只创建软件的调度层,换句话说,FL 和 SL 都不知道它们将执行哪些功能,因此它们不知道它们之间将交换哪些数据。这就提出了一个应该在哪里实现队列的问题。在执行循环“模板”(FL 和 SL)中或在其中执行的对象中。提前感谢您的意见。
  • 好吧,无论您以哪种方式从一个进程获取数据到另一个进程,在内存中它只是一堆字节。您必须在双方都指定某种通用解释,才能对数据进行编码/解码。如果这是嵌入的,您可能不会动态创建新类型的数据;如果这是为了控制,那么您的数据大部分是先验的。
猜你喜欢
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
相关资源
最近更新 更多