multithreading Arduino 是否支持线程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14002984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 01:20:57  来源:igfitidea点击:

Does Arduino support threading?

multithreadingarduino

提问by Snake Sanders

I have a couple of tasks to do with arduino but one of them takes very long time, so I was thinking to use threads to run them simultaneously. I have an Arduino Mega

我有几项与 arduino 相关的任务,但其中一项需要很长时间,所以我想使用线程同时运行它们。我有一个 Arduino Mega

[Update] Finally after four years I can install FreeRTOS in my arduino mega. Here is a link

[更新] 四年后,我终于可以在我的 arduino mega 中安装 FreeRTOS。这是一个链接

采纳答案by Filipe YaBa Polido

In short: NO. But you may give it a shot at: http://www.kwartzlab.ca/2010/09/arduino-multi-threading-librar/

简而言之:不。但是你可以试一试:http: //www.kwartzlab.ca/2010/09/arduino-multi-threading-librar/

回答by Ivan Seidel

Not yet, but I always use this Library with big projects: https://github.com/ivanseidel/ArduinoThread

还没有,但我总是在大项目中使用这个库:https: //github.com/ivanseidel/ArduinoThread

I place the callback within a Timer interrupt, and voilá! You have pseudo-threads running on the Arduino...

我将回调放在 Timer 中断中,瞧!你有伪线程在 Arduino 上运行......

回答by Mr. Girgitt

Just to make this thread more complete: there are also protothreadswhich have very small memory footprint (couple bytes if I remember right) and preserve variables local to thread; very handy and time saving (far less finite state machines -> more readable code).

只是为了使这个线程更完整:还有一些内存占用非常小的protothreads(如果我没记错的话,是几个字节)并保留线程本地的变量;非常方便和节省时间(更少的有限状态机 - > 更易读的代码)。

Examples and code: arduino-class / ProtoThreads wiki

示例和代码: arduino-class / ProtoThreads wiki

Just to let you know what results you may expect: serial communication @ 153K6 baudrate with threads for: status diodes blinking, time keeping, requested functions evaluation, IO handling and logic and all on atmega328.

只是为了让您知道您可能期望的结果:串行通信@ 153K6 波特率与线程:状态二极管闪烁、计时、请求的功能评估、IO 处理和逻辑以及所有在 atmega328 上。

回答by FrancescoMM

Not real threading but TimedActions are a good alternative for many uses

不是真正的线程,但 TimedActions 是许多用途的不错选择

http://playground.arduino.cc/Code/TimedAction#Example

http://playground.arduino.cc/Code/TimedAction#Example

Of course, if one task blocks, the others will too, while threading can let one task freeze and the others will continue...

当然,如果一个任务阻塞,其他任务也会阻塞,而线程可以让一个任务冻结而其他任务继续......

回答by lkrasner

The previous answer is correct, however, the arduino generally runs pretty quick, so if you properly time your code, it can accomplish tasks more or less simultaneously.

前面的答案是正确的,但是,arduino 通常运行得非常快,因此如果您对代码进行适当的计时,它可以或多或少地同时完成任务。

The best practice is to make your own functions and avoid putting too much real code in the default void loop

最好的做法是自己制作函数,避免在默认的void循环中放入太多真实的代码

回答by eyal

You can use arduinos

你可以使用arduino

It is designed for Arduino environment. Features:

它是为 Arduino 环境设计的。特征:

  • Only static allocation (no malloc/new)
  • Support context switching when delaying execution
  • Implements semaphores
  • Lightweight, both cpu and memory
  • 仅静态分配(无 malloc/new)
  • 延迟执行时支持上下文切换
  • 实现信号量
  • 轻量级,CPU和内存

I use it when I need to receive new commands from bluetooth/network/serial while executing the old ones and the old ones have delay in them. One thread is the sever thread that does the following loop:

我在执行旧命令时需要从蓝牙/网络/串行接收新命令时使用它,而旧命令有延迟。一个线程是执行以下循环的服务器线程:

while (1) {
    while ((n = Serial.read()) != -1) {
        // do something with n, like filling a buffer
        if (command_was_received) {
            arduinos_create(command_func, arg);
        }
    }
    arduinos_yield(); // context switch to other threads
}

The other is the command thread that executes the command:

另一个是执行命令的命令线程:

int command_func(void* arg) {
    // move some servos
    arduinos_delay(1000); // wait for them to move
    // move some more servos
}

回答by BATMAN_

No you can't but you can use Timer interrupt. Ref : https://www.teachmemicro.com/arduino-timer-interrupt-tutorial/

不,你不能,但你可以使用定时器中断。参考:https: //www.teachmemicro.com/arduino-timer-interrupt-tutorial/

回答by Francesco Boi

Arduino does not support multithread programming.

Arduino 不支持多线程编程。

However there have been some workarounds, for example the one in this project(you can install it also from the Arduino IDE).

但是有一些变通方法,例如本项目中的变通方法(您也可以从 Arduino IDE 安装它)。

It seems you have to define the schedule time yourself while in a real multithread environment it is the OS that decides when to execute tasks.

似乎您必须自己定义调度时间,而在真正的多线程环境中,由操作系统决定何时执行任务。

Alternatively you can use protothreads

或者你可以使用protothreads

回答by Luiz Menezes

Arduino does not supports threading. However, you can do the next best thing and structure your code around state machines running in interleaving.

Arduino 不支持线程。但是,您可以做下一个最好的事情,并围绕交错运行的状态机构建您的代码。

While there are lots of ways to implement your tasks as state machines, I recommend this library (https://github.com/Elidio/StateMachine). This library abstracts most of the process.

虽然有很多方法可以将您的任务实现为状态机,但我推荐这个库 ( https://github.com/Elidio/StateMachine)。这个库抽象了大部分过程。

You can create a state machine as a class like this:

您可以将状态机创建为这样的类:

#include "StateMachine.h"
class STATEMACHINE(Blink) {
  private:
    int port;
    int waitTime;
    CREATE_STATE(low);
    CREATE_STATE(high);

    void low() {
      digitalWrite(port, LOW);
      *this << &STATE(high)<< waitTime;
    }
    void high() {
      digitalWrite(port, HIGH);
      *this << &STATE(low)<< waitTime;
    }
  public:
    Blink(int port = 0, int waitTime = 0) :
      port(port),
      waitTime(waitTime),
      INIT_STATE(low),
      INIT_STATE(high)
      {
        pinMode(port, OUTPUT);
        *this << &STATE(low);
      }
};

The macro STATEMACHINE()abstracts the class inheritances, the macro CREATE_STATE()abstracts the state wrapper creation, the macro INIT_STATE()abstracts method wrapping and the macro STATE()abstracts state wrapper reference within the state machine class.

STATEMACHINE()抽象类继承,宏CREATE_STATE()抽象状态包装器创建,宏INIT_STATE()抽象方法包装和宏STATE()抽象状态机类内的状态包装器引用。

State transition is abstracted by <<operator between the state machine class and the state, and if you want a delayed state transition, all you have to do is to use that operator with an integer, where the integer is the delay in millisseconds.

状态转换是由<<状态机类和状态之间的运算符抽象出来的,如果您想要延迟状态转换,您所要做的就是使用带有整数的运算符,其中整数是以毫秒为单位的延迟。

To use the state machine, first you have to instantiate it. Declaring an reference to the class in global space while instantiating it with newon setup function might do the trick

要使用状态机,首先必须实例化它。在全局空间中声明对类的引用,同时使用newon setup 函数实例化它可能会奏效

Blink *led1, *led2, *led3;


void setup() {
  led1 = new Blink(12, 300);
  led2 = new Blink(11, 500);
  led3 = new Blink(10, 700);
}

Then you run the states on loop.

然后你循环运行状态。

void loop() {
    (*led2)();
    (*led1)();
    (*led3)();
}