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
[Update]
Finally after four years I can install FreeRTOS in my arduino mega. Here is a link
In short: NO.
But you may give it a shot at:
http://www.kwartzlab.ca/2010/09/arduino-multi-threading-librar/
(Archived version: https://web.archive.org/web/20160505034337/http://www.kwartzlab.ca/2010/09/arduino-multi-threading-librar
Github: https://github.com/jlamothe/mthread
Not yet, but I always use this Library with big projects:
https://github.com/ivanseidel/ArduinoThread
I place the callback within a Timer interrupt, and voilá! You have pseudo-threads running on the Arduino...
Just to make this thread more complete: there are also protothreads which 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).
Examples and code:
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.
Not real threading but TimedActions are a good alternative for many uses
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...
No you can't but you can use Timer interrupt.
Ref : https://www.teachmemicro.com/arduino-timer-interrupt-tutorial/
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.
The best practice is to make your own functions and avoid putting too much real code in the default void loop
You can use arduinos
It is designed for Arduino environment. Features:
Only static allocation (no malloc/new)
Support context switching when delaying execution
Implements semaphores
Lightweight, both cpu and memory
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
}
Arduino does not support multithread programming.
However there have been some workarounds, for example the one in this project (you can install it also from the 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
The straight answer is No No No!. There are some alternatives but you can't expect a perfect multi threading functionality from an arduino mega. You can use arduino due or lenado for multithreading like below-
void loop1(){
}
void loop2(){
}
void loop3(){
}
Normally, I handle those types of cases in backend. You can run the main code in a server while using Arduino to just collect inputs and show outputs. In such cases I would prefer nodemcu which has built in wifi.
Thread NO!
Concurrent YES!
You can run different tasks concurrently with FreeRTOS library.
https://www.arduino.cc/reference/en/libraries/freertos/
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );
// Now set up two tasks to run independently.
xTaskCreate(
TaskBlink
, (const portCHAR *)"Blink" // A name just for humans
, 128 // Stack size
, NULL
, 2 // priority
, NULL );
xTaskCreate(
TaskAnalogRead
, (const portCHAR *) "AnalogRead"
, 128 // This stack size can be checked & adjusted by reading Highwater
, NULL
, 1 // priority
, NULL );
void TaskBlink(void *pvParameters) // This is a task.
{
(void) pvParameters;
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
for (;;) // A Task shall never return or exit.
{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
}
}
void TaskAnalogRead(void *pvParameters) // This is a task.
{
(void) pvParameters;
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
for (;;)
{
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
vTaskDelay(1); // one tick delay (15ms) in between reads for stability
}
}
Just take care!
When different tasks tried to reach variables at the same time, like i2c communication line or sd card module. Use Semaphores and mutexes
https://www.geeksforgeeks.org/mutex-vs-semaphore/.
Arduino does not supports threading. However, you can do the next best thing and structure your code around state machines running in interleaving.
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.
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.
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 new on setup function might do the trick
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)();
}
Related
I wrote a simple multi-threaded application in OMNET++ that does not call any OMNET++ API in the working thread and is working as expected. I know that OMNET++ does not support multi-thread applications by design, but I was wondering if there is any mechanism that I can use to make a bridge between my worker thread and my code in the main simulation thread.
More specifically, I am saving some data in a vector in the working thread and I want to signal the code in the simulation thread to consume it (producer/consumer scenario). Is there any way to achieve this?
Do I need to design my own event scheduler?
METHOD 1
The simplest way to achieve your goal is to use a selfmessage in simulation thread and a small modification of worker thread. The worker thread should modify a common variable (visible by both threads). And the selfmessage should periodically check the state of this variable.
The sample code of this idea:
// common variable
bool vectorReady;
// worker thread
if (someCondition) {
vectorReady = true;
}
// simulation thread
void someclass::handleMessage(cMessage * msg) {
if (msg->isSelfMessage()) {
if (vectorReady) {
vectorReady = false;
// reads vector data
}
scheduleAt(simTime() + somePeriod, msg);
}
The place of declaration of common variable depends how you create and start the worker thread.
METHOD 2
The other way is to create own scheduler and adding a condition just before every event. By default OMNeT++ uses cSequentialScheduler scheduler. It has the method takeNextEvent() which is called to obtain next event. You can create a derived class and overwrite this method, for example:
// cThreadScheduler.h
#include <omnetpp.h>
using namespace omnetpp;
class cThreadScheduler : public cSequentialScheduler {
public:
virtual cEvent *takeNextEvent() override;
};
// cThreadScheduler.cc
#include "cThreadScheduler.h"
Register_Class(cThreadScheduler);
cEvent* cThreadScheduler::takeNextEvent() {
if (vectorReady) {
vectorReady = false;
// reads vector data
}
return cSequentialScheduler::takeNextEvent();
}
In omnetpp.ini add a line:
scheduler-class = "cThreadScheduler"
I have some problems designing a Signal/Slot system in C++11.
My main design goals are: simple but still offering some features and thread safe.
My personal opinion on a Signal/Slot system is that emitting should be as fast as possible. Because of that I try to keep the slot list inside the signal tidy. Many other Signal/Slot systems leave disconnected slots empty. That means more slots to iterate and checking slot validity during signal emission.
Here is the concrete problem:
Signal class have one function for emitting and one function for disconnecting a slot:
template<typename... Args>
void Signal<void(Args...)>::operator()(Args&&... args)
{
std::lock_guard<std::mutex> mutex_lock(_mutex);
for (auto const& slot : _slots) {
if (slot.connection_data->enabled) {
slot.callback(std::forward<Args>(args)...);
}
}
}
template<typename... Args>
void Signal<void(Args...)>::destroy_connection(std::shared_ptr<Connection::Data> connection_data)
{
std::lock_guard<std::mutex> mutex_lock(_mutex);
connection_data->reset();
for (auto it = _slots.begin(); it != _slots.end(); ++it) {
if (it->connection_data == connection_data) {
*it = _slots.back(); _slots.pop_back();
break;
}
}
}
This works fine until one tries to make a connection that disconnects itself when signal i emitted:
Connection con;
Signal<void()> sig;
con = sig.connect([&]() { con.disconnect(); });
sig();
I have two problems here:
The emit function must probably be redesigned because slots can potentially be removed when iterated.
There are two mutex locks inside the same thread.
Is it possible to make this work (maybe with recursive mutex?), or should I redesign the system to not interfere with slots list and just leave empty slots (as many other similar projects do) when disconnecting the signal?
Problem:
I have a private variable that is available during the startup of a threaded object, but is out of scope when it is used later (via a signal and slot call).
Details:
I have an application that I'm developing in Qt5 for both linux and windows.
Currently it works as expected under linux (where development began), but now
that I'm trying to stand it up on windows 7 (I didn't have a copy of windows initially) I have run into this problem where (on windows only) my private variables go out of scope after the thread initializes.
Question:
What is wrong with my object/thread structure such that the variable scope is fine under Linux, but not in windows? I thought that was the kind of "behind the scenes" stuff Qt took care of? (clearly not)
More Detail:
The order of operation goes like this
Instantiate an object
Move the object into a thread
Get the thread's start signal and call an init function in the object
Later, get data and emit a signal to the threaded object
Threaded object processes data
The code outlining the steps above is summarized below.
void MyWorkerClass::init()
{
// ... bunchOCode
procThread = new QThread; // <-- procThread - private to MyWorkerClass
procObj = new Processor(startupData); // <-- procObj - private to MyWorkerClass
procObj->moveToThread(procThread);
connect(procThread, SIGNAL(started()), procObj, SLOT(doStart()));
connect(this, SIGNAL(dataIsReady(void *)), procObj, SLOT(processMsgs(void *)));
procThread->start();
ok = waitforProcSetup();
// ... Life is good, do more stuff
}
class Processor : public QObject
{
// ... Other
// ... stuff
private slots:
void doStart();
void processMsgs(void * buffer);
private:
QHash<QString, bool> process;
}
void Processor::doStart() // <-- private slot
{
// ... take care of init stuff that couldn't be done in constructor
// Variable is valid here and I can work with it.
foreach(site, locations.uniqueKeys()) {
process[site] = true; // <-- works like a champ
qDebug() << QString("%1 => %2").arg(site).arg(process[site]);
}
}
void Processor::processMsgs(void * buffer) // <-- buffer is malloc'd memory and works fine
{
// ... When MyWorkerClass gets some data it emits a signal that is connected
// to this private slot.
// Simply trying to examine the variable causes a segfault (because it's uninitialized here)
qDebug() << "... processMsgs:" << process.isEmpty(); // <-- wets the bed
}
.
In trying to improve my question, by following the suggestions from the people who commented, I found out what was going on. I was working on creating a small working version of the example I posted (thanks Kuba Ober). The "error" I was encountering was a segmentation fault that could consistently be recreated with the debug line:
qDebug() << "... processMsgs:" << process.isEmpty(); // <-- wets the bed
Specifically, the private QHash variable "process" was useable when I called it the first time (after the thread was up and running)
connect(procThread, SIGNAL(started()), procObj, SLOT(doStart()));
but that same variable acted like it had gone out of scope when I tried to call it the second time
connect(this, SIGNAL(dataIsReady(void *)), procObj, SLOT(processMsgs(void *)));
The signal (dataIsReady(void *)) for this second call is an explicit "emit" that the worker class does when it's collected some data that can be processed. I tried to make that clear in the comments of the example pseudocode, but I didn't take into account that the comment code I included wouldn't stand out that well since it's all grey.
What was really going on was right after I filled "process[site]" with data I also looped over a quint64 array filling it with data too. The loop went 1 element too far and wrote into the "process" variable, making it look to me like it had gone out of scope. In linux it was purely coincidental that it didn't segfault (likely there was padding between the array and the QHash), but the windows runtime exposed the error for the first time.
I have N threads performing various task and these threads must be regularly synchronized with a thread barrier as illustrated below with 3 thread and 8 tasks. The || indicates the temporal barrier, all threads have to wait until the completion of 8 tasks before starting again.
Thread#1 |----task1--|---task6---|---wait-----||-taskB--| ...
Thread#2 |--task2--|---task5--|-------taskE---||----taskA--| ...
Thread#3 |-task3-|---task4--|-taskG--|--wait--||-taskC-|---taskD ...
I couldn’t find a workable solution, thought the little book of Semaphores http://greenteapress.com/semaphores/index.html was inspiring. I came up with a solution using std::atomic shown below which “seems” to be working using three std::atomic.
I am worried about my code breaking down on corner cases hence the quoted verb. So can you share advise on verification of such code? Do you have a simpler fool proof code available?
std::atomic<int> barrier1(0);
std::atomic<int> barrier2(0);
std::atomic<int> barrier3(0);
void my_thread()
{
while(1) {
// pop task from queue
...
// and execute task
switch(task.id()) {
case TaskID::Barrier:
barrier2.store(0);
barrier1++;
while (barrier1.load() != NUM_THREAD) {
std::this_thread::yield();
}
barrier3.store(0);
barrier2++;
while (barrier2.load() != NUM_THREAD) {
std::this_thread::yield();
}
barrier1.store(0);
barrier3++;
while (barrier3.load() != NUM_THREAD) {
std::this_thread::yield();
}
break;
case TaskID::Task1:
...
}
}
}
Boost offers a barrier implementation as an extension to the C++11 standard thread library. If using Boost is an option, you should look no further than that.
If you have to rely on standard library facilities, you can roll your own implementation based on std::mutex and std::condition_variable without too much of a hassle.
class Barrier {
int wait_count;
int const target_wait_count;
std::mutex mtx;
std::condition_variable cond_var;
Barrier(int threads_to_wait_for)
: wait_count(0), target_wait_count(threads_to_wait_for) {}
void wait() {
std::unique_lock<std::mutex> lk(mtx);
++wait_count;
if(wait_count != target_wait_count) {
// not all threads have arrived yet; go to sleep until they do
cond_var.wait(lk,
[this]() { return wait_count == target_wait_count; });
} else {
// we are the last thread to arrive; wake the others and go on
cond_var.notify_all();
}
// note that if you want to reuse the barrier, you will have to
// reset wait_count to 0 now before calling wait again
// if you do this, be aware that the reset must be synchronized with
// threads that are still stuck in the wait
}
};
This implementation has the advantage over your atomics-based solution that threads waiting in condition_variable::wait should get send to sleep by your operating system's scheduler, so you don't block CPU cores by having waiting threads spin on the barrier.
A few words on resetting the barrier: The simplest solution is to just have a separate reset() method and have the user ensure that reset and wait are never invoked concurrently. But in many use cases, this is not easy to achieve for the user.
For a self-resetting barrier, you have to consider races on the wait count: If the wait count is reset before the last thread returned from wait, some threads might get stuck in the barrier. A clever solution here is to not have the terminating condition depend on the wait count variable itself. Instead you introduce a second counter, that is only increased by the thread calling the notify. The other threads then observe that counter for changes to determine whether to exit the wait:
void wait() {
std::unique_lock<std::mutex> lk(mtx);
unsigned int const current_wait_cycle = m_inter_wait_count;
++wait_count;
if(wait_count != target_wait_count) {
// wait condition must not depend on wait_count
cond_var.wait(lk,
[this, current_wait_cycle]() {
return m_inter_wait_count != current_wait_cycle;
});
} else {
// increasing the second counter allows waiting threads to exit
++m_inter_wait_count;
cond_var.notify_all();
}
}
This solution is correct under the (very reasonable) assumption that all threads leave the wait before the inter_wait_count overflows.
With atomic variables, using three of them for a barrier is simply overkill that only serves to complicate the issue. You know the number of threads, so you can simply atomically increment a single counter every time a thread enters the barrier, and then spin until the counter becomes greater or equal to N. Something like this:
void barrier(int N) {
static std::atomic<unsigned int> gCounter = 0;
gCounter++;
while((int)(gCounter - N) < 0) std::this_thread::yield();
}
If you don't have more threads than CPU cores and a short expected waiting time, you might want to remove the call to std::this_thread::yield(). This call is likely to be really expensive (more than a microsecond, I'd wager, but I haven't measured it). Depending on the size of your tasks, this may be significant.
If you want to do repeated barriers, just increment the N as you go:
unsigned int lastBarrier = 0;
while(1) {
switch(task.id()) {
case TaskID::Barrier:
barrier(lastBarrier += processCount);
break;
}
}
I would like to point out that in the solution given by #ComicSansMS ,
wait_count should be reset to 0 before executing cond_var.notify_all();
This is because when the barrier is called a second time the if condition will always fail, if wait_count is not reset to 0.
In a linux kernel driver, I would like to repeat indefinitely the following sequence:
at time T, a hardware IRQ is enabled
between time T and T + "around" 15ms, the IRQ callback can be reached if the IRQ is triggered. I say around because I'm not using an RT kernel and if it's 14 or 16ms, it's fine. In the IRQ callback, I need to write down get cpu_clock(0) and call wake_up_interruptible. The timeout needs to be killed. The whole process needs to be started again within 5ms.
if by T + "around" 15ms, the IRQ has not been triggered, I need to execute some other code. The IRQ should be disabled then. The whole process needs to be started again within 5ms.
Therefore, by T + "around" 20ms, in worst case, the whole process needs to be started again.
Note that if the IRQ is physically triggered at 18ms, too bad, "I missed the train". I will catch another hardware trigger at the next sequence.
While testing, I was doing something along the following pseudo-code:
INIT_DELAYED_WORK(&priv->work, driver_work);
INIT_DELAYED_WORK(&priv->timeout, driver_timeout);
request_irq(priv->irq, driver_interrupt, IRQF_TRIGGER_RISING, "my_irq", priv);
then:
queue_delayed_work(priv->workq, &priv->work, 0ms);
static void driver_work(struct work_struct *work) {
queue_delayed_work(priv->workq, &priv->timeout, 15ms);
priv->interruptCalled = 0;
enable_irq(priv->irq);
}
Then:
static irqreturn_t driver_interrupt(int irq, void *_priv) {
disable_irq_nosync(priv->irq);
priv->interruptCalled = 1;
cancel_delayed_work(&priv->timeout);
priv->stamp = cpu_clock(0);
wake_up_interruptible(&driver_wait);
queue_delayed_work(priv->workq, &priv->work, 5ms);
return IRQ_HANDLED;
}
And:
static void driver_timeout(struct work_struct *work) {
if (priv->interruptCalled == 0) {
disable_irq_nosync(priv->irq);
//Do other small cleanup
queue_delayed_work(priv->workq, &priv->work, 5ms);
}
}
I'm trying to write a robust but simple driver. Is this a proper implementation? How can I improve this implementation?
Answering my own question: the problem is that queue_delayed_work is based on jiffies. Or 5ms is not possible as HZ=100 (1 jiffy = 10ms). HR timer brought a good solution.