Is there the ability to make multi thread in arduino???

Is there the ability to make multi thread in arduino???&how??

Yes, it's called using interrupts ;)

But no, there is no multi-threading as such. You can kind of emulate it using a Finite State Machine, and interrupts run asynchronously to the main loop, so you can get multiple things happening "at once" that way.

There are (I think) some kind of threading libraries around for the arduino, but TBH it really doesn't have the resources at its disposal to do it properly.

micheal_91: Is there the ability to make multi thread in arduino???&how??

Why do you want to? Perhaps if you explain your project in more detail.

Somebody wrote a library to enable you to schedule callback functions to be called after a delay or at a regular interval, which lets you achieve many of the same objectives. But if you design your code to execute asynchronously (i.e. without blocking anywhere) then the need for multi-threading disappears. I suppose it would be possible to implement interrupt-based multi-threading, and it would be an interesting exercise, but a typical Arduino has so little RAM that it can barely afford to have one stack let along multiple ones.

I wrote a simple set of software timer functions some time ago that give a similar functionality.

It all depends on what you want to do really.


Rob

I have a cooperative multithreading library that I use for my more complex projects. You can find it at https://github.com/dc42/arduino. It's a bit short of demo material at present.

I have a cooperative multithreading library

Sorry, no. That is a multi-tasking library. Not a multithreading library. True multithreading requires an operating system and multiples cores so that more than one activity can be performed at the same time. Neither of which the Arduino has.

Multi-tasking is switching the part of a single thread that is being executed, when the time is (or other conditions are) right. That is what your library is doing.

micheal_91: Is there the ability to make multi thread in arduino???&how??

I've written several programs that "pseudo multitask" by calling multiple functions from an ISR.

It's like this:

void ISR_loop(void) { function_1(); function_2(); function_3(); }

Then run the loop fast... maybe 100 times per second. Only thing is that the total execution time for each function must not be longer than the ISR time period, otherwise the stack will fill up and crash.

PaulS:

I have a cooperative multithreading library

Sorry, no. That is a multi-tasking library. Not a multithreading library. True multithreading requires an operating system and multiples cores so that more than one activity can be performed at the same time. Neither of which the Arduino has.

Multi-tasking is switching the part of a single thread that is being executed, when the time is (or other conditions are) right. That is what your library is doing.

From the definition of multithreading given by Wikipedia, I believe I can reasonably call it a multithreading library. Indeed, Wikipedia uses the term "cooperative multithreading" on that page. Multithreading existed long before multiple core CPUs. But I agree that "cooperative multitasking" is a more commony-used term than "cooperative multithreading".

This is just a question of terminoligy.

In this context a "thread" is a sub-process contained within a single process.

Multi-tasking and multi-threading are two different things, and yet at the same time the same thing.

One system can have many processes. One process can have many threads.

However, it is all a moot point on the Arduino, as there is only one process - the main loop(). But you can have multiple threads within that process. On a computer it is down to the operating system to manage those threads (and the threads library, like pthread, pth, etc).

From a scheduling POV there is no real difference between a thread and a process.

And, there is some confusion between simultaneous and co-operative multitasking / multithreading. When you have a single core, only one thread executes at a time, and it's down to some system to switch between the threads. This is the "swapper" or "scheduler". It decides which thread should be executing and when. The scheduling strategy is critical to how the system works, and how responsive different things are.

If you have multiple cores, then you can have simultaneous threads running (aka symmetric multi-processing, or SMP). Threads can swap between cores at will depending on what the swapper / scheduler decides should be running. But still, you can only have as many threads as you have cores, so there is still co-operative multithreading / multitasking going on even then.

So, call it multithreading (or co-operative multithreading if you want to be pedantic), as it is multiple threads within the one process, and not multiple processes within the one operating system.

You could also call it Time-Division Multitasking (TDM) if you so wish ;)

I think we've been here before:

http://arduino.cc/forum/index.php/topic,126552

@OP: why do you want multi threading?

[quote author=Nick Gammon link=topic=131638.msg991024#msg991024 date=1352584325] I think we've been here before:

http://arduino.cc/forum/index.php/topic,126552

@OP: why do you want multi threading? [/quote]

[quote author=Robert Jordan] The wheel of Time turns, and Ages come and pass, leaving memories that become legend. Legend fades to myth, and even myth is long forgotten when the Age that gave it birth comes again. [/quote]

I guess he wants to do TDM because he's too lazy to work out a more imaginative way of doing what he wants...?

majenko: I guess he wants to do TDM because he's too lazy to work out a more imaginative way of doing what he wants...?

I think that's unfair. If you need to do a lot of things at once, doing them all in loop() gets very messy, and a multi-tasking scheduler provides a solution with much better structure. You might as well say that anyone who programs in C/C++ is too lazy to learn assembler.

void ISR_loop(void)
{
    function_1();
    function_2();
    function_3();
}

More like this:

timer isr:
  increase process_id;

loop:
  switch process_id:
    1: process 1;
    2: process 2;
    3: process 3;
  ...
  //delay(); - optional

It assumes that the process can be done within their allotted time and will quit as expected.

dc42:

majenko: I guess he wants to do TDM because he's too lazy to work out a more imaginative way of doing what he wants...?

I think that's unfair. If you need to do a lot of things at once, doing them all in loop() gets very messy, and a multi-tasking scheduler provides a solution with much better structure. You might as well say that anyone who programs in C/C++ is too lazy to learn assembler.

hell yeah ;)

Anyway, in my experience, if what you are doing is so complex it can't be done in a loop() with a FSM, then it won't fit in an Arduino anyway :P

dhenry: void ISR_loop(void) {     function_1();     function_2();     function_3(); }

More like this:

timer isr:
  increase process_id;

loop:   switch process_id:     1: process 1;     2: process 2;     3: process 3;   ...   //delay(); - optional




It assumes that the process can be done within their allotted time and will quit as expected.

kind of simplistic...

For proper TDM most of the work is done in the timer ISR.

You have x number of functions, each one is the "main" of a process. Those functions are all continuous loops. The timer, when triggered, takes the current stack frame, analyses it for the current state of the interrupted "process", and stores that detail in the processes state store. It also looks at the return address for the interrupt to find where in the interrupted "process" it was interrupted, and stores that too. Then it pulls in the details of a different process from that processes store, and sets up the environment to be where that process was interrupted. It then returns to where the new recovered return address.

All of it takes lots of memory.

In the RetroBSD project we require some form of external swap device to store all this information, and that's with 32K of kernel RAM and 96K of user RAM to play with. A basic "user" structure (what stores all this process information) is around 3K, and there is always 2 of them in memory at once - the "user" process, and the "swapper" process, which manages the switching of the "user" process. So that's 3 times more than the total RAM on a 328P already - and that's without any actual process memory...

majenko: So that's 3 times more than the total RAM on a 328P already - and that's without any actual process memory...

And then, since the Arduino doesn't support the concept of mapped memory, you need to reserve the maximum permitted space for each stack in advance. I agree: the Arduino simply doesn't have the resources to support this kind of architecture, and is not a suitable platform for solutions which require it.

PeterH:

majenko: So that's 3 times more than the total RAM on a 328P already - and that's without any actual process memory...

And then, since the Arduino doesn't support the concept of mapped memory, you need to reserve the maximum permitted space for each stack in advance. I agree: the Arduino simply doesn't have the resources to support this kind of architecture, and is not a suitable platform for solutions which require it.

Yeah, a problem we run up against with the pic32 - a fixed memory management system, so no memory protection, memory mapping, virtual addressing ... a real pain. Only one user process in memory at a time, and that has the entire 96K user memory to itself.

It's because full-blown operating system schedulers require too much memory to save the state of each task that the schedulers used on microcontrollers are normally of the cooperative type, simplified such that each task runs its function to completion and returns before another task is scheduled. That way, only a few bytes of memory (beyond what you would need anyway if you didn't use a scheduler) is needed to store the state of each task, and as there is only one stack, you don't need to make decisions on stack size.

dc42:
It’s because full-blown operating system schedulers require too much memory to save the state of each task that the schedulers used on microcontrollers are normally of the cooperative type, simplified such that each task runs its function to completion and returns before another task is scheduled. That way, only a few bytes of memory (beyond what you would need anyway if you didn’t use a scheduler) is needed to store the state of each task, and as there is only one stack, you don’t need to make decisions on stack size.

Yeah, a glorified FSM, where the “outer” state is the identifier for which process to run :wink: