问题标签 [protothread]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
328 浏览

oop - Arduino Protothreads 似乎由两个按钮共享

我遇到了关于 Arduino 中的 Protothreading 库的问题。我创建了一个Button类,它代表一个硬件按钮。现在的想法是你可以附加一个ButtonListener来监听按钮。如果按下按钮,则clicked()调用该函数。

现在我创建了两个实现ButtonListener

另一个实现是 aButton13Listener并打印“Button 13 clicked!”

然后让我们运行代码:

我期待“点击按钮 12!” 当我单击针脚 12 上的按钮时,“单击了按钮 13!” 当我单击引脚 13 上的按钮时。

但是当我尝试点击任何按钮时,它会随机打印“Button 12 clicked!” 或“点击了按钮 13!” 无论我按什么按钮。

看起来原型线程在按钮或其他东西之间共享。

如果我检查按钮的调用顺序,如下所示:

然后是以下输出:

这似乎没问题。

所以有什么问题?我错过了什么?

0 投票
1 回答
425 浏览

c - 使用 protothreads 通过 Arduino 控制电机继电器

我正在通过 arduino 控制两个电机继电器。设置如下:

每个继电器都由一个简单的开关设置控制。当开关闭合时,继电器激活。当开关打开时,继电器不活动。

我决定试一试 protothreads,因为我希望这两个开关可以并行控制电机。为此,我编写了以下代码:

问题如下。只要我按下一个开关,相应的继电器就会响应。但是,当我按下两个开关时,只有一个继电器响应(可能是最早触发的那个)。

如何修复代码,以便在按住两个开关时,两个继电器同时响应?

非常感谢您的时间和提前帮助

0 投票
1 回答
91 浏览

protothread - protothread 在外部 main 函数中将一个线程跳转到开头

我有一个原型线程设置和阻塞......

一段时间后,mythread可以在“lineA”、“lineB”或“lineC”处被阻塞。

一个外部函数,比如main()重置,怎么会mythread在开头的“lineA”处再次被阻塞。

通过运行宏PT_RESTART(&pt_mythread)?编译器不喜欢它。因为我的main()函数不在 PT_BEGIN, PT_END 块内,所以return那个宏的内部是坏的,坏的。

还是又跑PT_INIT(&pt_mythread)了?有什么建议么?

0 投票
0 回答
256 浏览

c - __LINE__ 上的 Protothread 调用大于 256:错误:案例标签值超出

我在我的嵌入式设备(STM32、GCC)上使用了 protothreads,因为它很轻量级,并且可以让我自己处理复杂的状态机。

随着我的主程序的增长,在大于 256 的行号上调用 PT_* 函数

在编译时,它会抛出这个错误:

如果 PT_YIELD 或 PT_WAIT_UNTIL 放置在低于 256 的行号上,它会编译。

这是 PT_YIELD、PT_WAIT_UNTIL、LC_SET 和 struct pt 的片段:

为什么“case __LINE__:”不能超过 256,因为它存储在 uint32_t 上?

0 投票
2 回答
714 浏览

coroutine - Contiki OS 中的 Protothread 实现——为什么状态变量不是静态的?

我正在阅读由瑞典 SICS 的 Adam Dunkels 开发的 Contiki OS 中的 protothread 实现的源代码。我真的很困惑它的实现和Simon Tatham所展示的协同程序想法之间的细微差别——也就是说,为什么状态变量在Adam 的 protothread实现中不必是静态的,而在 Simon 的论文中声明为静态的?

我们先来仔细看看西蒙的讨论。例如,如果能写一个函数说

并且连续十次调用函数返回数字 0 到 9。

这可以通过在此函数中使用以下宏来实现:

正如预期的那样,调用此函数十次将给出 0 到 9。

不幸的是,如果我们像这样使用 Adam 的本地延续宏封装的 switch-case(Contiki src 树中的/core/sys/lc-switch.h),这将不起作用,即使您将状态变量设置为静态:

在这里,就像 Simon 的示例一样,s 用作状态变量,它保留由 LC_SET(s) 设置的位置(屈服点)。并且当函数稍后恢复执行时(从头开始),它会根据 s 的值进行切换。这种行为产生的效果是函数在先前调用设置的屈服位置之后继续运行。

这两组宏的区别在于:

  1. 状态变量 s 在 Simon 的示例中是静态的,但在 Adam 的 LC 定义中是非静态的;
  2. crReturn 在返回结果之前设置状态,而在 Adam 的 LC 定义中,LC_SET(s) 纯粹设置状态并标记屈服点。

当然,后者不适用于函数中的这种 for 循环情况。这种“返回并继续”行为的关键在于状态变量是静态的以及在返回语句之前设置的状态。显然 LC 宏不满足任何要求。那么为什么 LC 宏是这样设计的呢?

我现在只能推测这些 LC 宏只是非常低级的原语,不应该以这个 for 循环示例中所示的方式使用。我们需要进一步构建那些包裹这些 LC 原语的 PT 宏,以使它们真正有用。并且 crReturn 宏仅用于演示目的,以特别适合 for 循环情况,因为并非每次您都想通过从函数返回来产生执行。

0 投票
1 回答
837 浏览

c++ - C++ 中的原型线程

嗨,我正在研究通过串行总线控制电梯的嵌入式系统。每次我发送一条消息(数据包包含地址,数据长度,数据,crc)我都需要等待电梯响应,它由确认包表示。

每次我从电梯收到数据包时都会设置 ACK。接收消息是通过中断完成的。ACK 数据包看起来像:

当它到来时,我将 ACK 设置为true

这是我的发送功能:

这只是尝试,它不起作用。

我的问题是如何使用 protothreads 使第一个函数正常工作。

0 投票
1 回答
3176 浏览

timer - Contiki 延迟秒数

我正在尝试开发一段 contiki 代码,我需要在其中等待三秒钟才能获得换能器输出。虽然这听起来很不像转换器,但在开发时,我想以人类可读的速度模拟行为,因此我需要将计时器设置为 3 秒。

Contiki 计时器有很好的文档记录,并且有一系列很好的示例,其中提到了计时器的创建、设置和重置。但是,如果我有如下代码:

现在设置计时器后不会立即触发到期。所以 if 块永远不会被执行。实际上,它永远不会破晓。

现在有两种方法可以让系统等待。一,通过像这样在计时器上添加一个while循环:while(!timer_expired(&&transducerOutputWaitTimer)){}; //做一点事

或 cpu_delay_usecs{mytimerdur_in_secs*10^6*}; //做一点事

我认为这两种方法都不优雅。虽然一个浪费 CPU 周期,但另一个强制执行不必要的大计算。

有没有更好的办法?我知道那个钟

这个问题附有以下两个:

  1. 如何从另一个触发一个 Contiki protothread?如果我能做到这一点,我就可以得到一个中断,它会导致transducerOutput 调用一个进程,我可以从这个进程中触发etimer 和进程事件。

  2. CPU延迟到底是什么意思?这是否意味着整个 CPU 时钟周期在给定的持续时间内被阻止?如果是,系统中当前运行的其他进程如何受到影响?

更新 更新 1:while 方法不起作用。代码可能进入了无限循环。更新 2:我在设置计时器后尝试了 clock_delay(3*CLOCK_SECOND) 方法。有效。但是,在这种情况下,为什么我需要 timer 方法呢?

更新 3(这会改变答案的上下文,因此根据建议添加此评论)

我的计时器需要在不同的 void 函数中的进程之外使用。在这种情况下,我需要使用 timer() 库而不是 etimer(它特定于进程。那么在这种情况下如何让我的方法等待所需的时间呢?

0 投票
2 回答
300 浏览

events - Contiki 事件源

在 Contiki 中编写多个进程时,通常会轮询一个进程并等待其退出或继续信号。但是,如果我需要等待特定进程结束并且我有多个进程触发的事件,我如何才能到达创建该事件的源进程?例如,在下面的代码中,我想知道哪个进程刚刚退出,以便 P3 可以继续前进。

这是一个常见的情况:

还有其他方法,我可以做一个while循环,直到两者process_is_running(&P1)process_is_running(&P2)为假。但是ev,在 Process 句柄中添加少量内容的比较方法会更加优雅和可读。

我无法从 Contiki 源代码中得到任何提示。有没有人尝试过像我上面暗示的那样的替代方案?

0 投票
1 回答
124 浏览

c - 了解宏行为和原型线程

在此先感谢您的帮助。

首先是前言。我一直在研究使用https://github.com/contiki-os/contiki/tree/master/core/net/mac/tsch给出的 Contiki TSCH 实现。在 Cooja 模拟器中运行一个简单的示例时(在基本代码中添加了一些日志消息,以便我可以看到发生了什么),我注意到 ASN 计数器没有增加其最高有效字节。

具体来说,ASN(TSCH 的绝对时隙编号)由结构体给出

并且本质上可以被认为是一个索引值,表示为两个变量,最高有效字节和最低有效 4 个字节。以下宏用于将 ASN 增加一定数量。

暂时忽略 printf 语句(我添加了这些语句以试图了解发生了什么)。据我了解这个宏,最不重要的字节首先增加。然后,如果最低有效字节环绕最高有效字节,则递增。但是,在查看正在发生的事情的日志时,我注意到当最不重要的字节环绕时,最重要的字节并没有增加。

现在到我的实际问题。为了确定为什么最重要的字节没有被增加,我将上面的打印语句添加到宏中,并在实际宏调用的上方和下方添加了打印语句,如下所示(注意 ASN 由 tsch_current_asn 给出,timeslot_diff 是我想要的数量将 ASN 递增)。

这样做产生了以下日志,这绝对让我难过

具体来说,似乎在宏 inc 中的第一个和第二个 printf 语句之间(timeslot_diff)从 0 更改为 1877。换句话说,在我看来,该语句

更改了 inc 的值(timeslot_diff)。此外,在我看来,此语句将 ans.ls4b (tsch_current_asn.ls4b) 从 1877 更改为 0。

关于宏如何工作,或者这是 Contiki 的 protothreads 的影响(即被暂停并稍后恢复),我是否有一个高级的时间?

作为参考,宏调用的实际代码在 https://github.com/contiki-os/contiki/blob/master/core/net/mac/tsch/tsch-slot-operation.c的第 1035 行给出该宏在https://github.com/contiki-os/contiki/blob/master/core/net/mac/tsch/tsch-asn.h的第 67 行给出。

0 投票
2 回答
90 浏览

c++ - 如何检查 (*this) 上的 std::is_base_of<>

对于某些任务,如果没有宏,我就无法逃脱。现在我想至少添加一些防止误用的保护。

我想static_assert使用 MYMACRO()

  1. 在基类的子类中,...
  2. ...即,在run()方法中

一种天真的方法失败了:

重现:

预测可能的问题:
它有什么用?- http://dunkels.com/adam/dunkels06protothreads.pdf
标签作为值: - https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html为什么不使用上下文切换
“正确” RTOS ?- 我希望上述解决方案能够简化本机架构下的单元测试,避开对本机 (POSIX) 端口QEMU / renode目标板的需求。(不是针对所有人,而是针对许多测试)