The fastest way to stop a thread/task on arduino

sdfewa wrote on Friday, January 19, 2018:

Just noticed that arduino/avr is supported by freeRTOS and was really cheered up.

First question is that does arduino support all the features of this os?

2nd question: What is the fastest way to stop a thread/task (even it is a blocking one).
Assume, I have an arduino board controls a lathe with (freeRTOS). There is a thread keeps monitoring the emergency stop button at a very high frequency (1000Hz, for example ) and running at the highest priority, higher than all the other threads. Whenever the emergency stop button is pressed some threads must stop immedietely even they are in the middle of something. I don’t want to shut down the whole machine by the emergency stop button because I want to resume some work later on. Note, the subthreads don’t have to save their states for later, some other thread can do that for them and just use state machine design, I guess they can just restart and check the state variables and resume their job. So what’s the best way? To ask them to suspend? or just vTaskDelete() ? I assume to delete them takes longer than necessary because they will save their state first.

I guess this kind of immediate interruption of thread/taks is needed in general robots/areo/aircraft/industry control or any thing requires real time. So if any work around will be welcome and will benefit a lot people.

Any arduiono exmaple of this kind?

richard_damon wrote on Friday, January 19, 2018:

First, stopping all the tasks is likely the wrong thing to do on pressing an Emergency Stop button. Normally such an event causes a trigger of some sort to be sent to most tasks (tiggers may be different for different tasks) to transition as quickly as possible to a ‘safe’ state. For a task running a motion control loop, it may just be a change of the control state to tell it to come to a stop.

Actually, if you think about it, just stopping a task is rarely the ‘safe’ thing, as normally there is some cleanup that it should do to stop cleanly. The key is that a feature like Emergency Stop really needs to be designed in as a fundamental mode of operation of the tasks, and not just bolted on as a somewhat arbitrary stopping of tasks. Each task is designed with a limited responce time to the signal, and what is should do.

Actually, in many cases, for true safety, an Emergency Stop is built at dedicated hardware levels to just immediately remove power from the mechanical system and apply brakes, assuming that is a ‘safe’ default state (it isn’t always. especially if brakes aren’t available).

sdfewa wrote on Friday, January 19, 2018:

Wow, You are fast, Richard! That’s the spirit of the Real-time system!!!

Actually, the lathe case is just an exmple. I totally understand your idea and usually the emergency stop button is a hardware one.

So far to start a task can be as fast and the hardware can do, right? But to stop one is due to the design of the thread.

Yes, could you please elaborate on the trigger (also to benefit others who need this) ? My guess there are severl ways:

  1. If the thread to be stop is simple, I can just put a if block to check the state variable and control the flow of execution immediately, and this is the fastest way. And this is prefered because it avoid the overhead of other unnecessary operation such as releasing the memory in the heap. Also to resume this thread, it is much faster, because all the local variables and still there and don’t need to be passed from other thread. Downside is, in order to make the swith as fast as possible in any state of this thread, one need to put the same if block in between any lines in this thread. Am I right(?)
    However, in some thread, one single line of code may take quiet a while to finish(lets call it blocking code ). So even one put if block in between every single line, there is still could be some unpredictble delay of stopping that thread. And I guess the idea of RTOS is not that it is fast, but it is fast and Predictably fast. So this method can not be used in this scenario.
  2. Use some vTaskDelete way to inform the task to quit. Does this give some predictable delay even if the thread is running blocking code? From what I read, vTaskDelete has to wait for the task.
  3. Ask the task to go to suspended state. I don’t know how.
  4. … Maybe more. Could you please elaborate a little bit?

I used the lathe example just to say sometimes, to stop a task/thread immediately is as important as to start it immediately. But if there is a mechanism with some predictable delay to stop a thread, it is still okay.

Thanks in advance.

rtel wrote on Friday, January 19, 2018:

Just noticed that arduino/avr is supported by freeRTOS and was really
cheered up.

Minor correction, arduino/avr USES FreeRTOS, rather than supported by
FreeRTOS. The work is done by a [very active] third party, not us.

2nd question: What is the fastest way to stop a thread/task (even it is
a blocking one).
Assume, I have an arduino board controls a lathe with (freeRTOS). There
is a thread keeps monitoring the emergency stop button at a very high
frequency (1000Hz, for example )

I think you are in a thread conversation on this already (I’ve seen the
emails go flying by), but just my 2c, emergency stop buttons are just
that - emergency stop - and normally hard wired to remove power or do
some other hard wired action to place the system in a safe state. ‘In
general’ that cannot be done by software as it might be a software issue
that caused the emergency stop to be pushed in the first place.

sdfewa wrote on Saturday, January 20, 2018:

Thanks Richard again for adding comments. I didn’t know the email actually went through. Yes, the arduino community is quite active. Thanks to arduino platform, people can quickly go from 0 knowldge of embedded system to building programs using rtos within a week. So forgive me if I asked stupid questions LOL.

The lathe example is just an example, I just made a simplified scenario. Actually I need some fast response to the enviornment. So it is not an emergency stop so to speak. in reality there will be a lot scenarios I can imagine people need some task to go silent.

After carefully reading the tutorial again, I think I don’t have to force the slave tasks to quit, that may cost more resource, I just need to pause them and clean them up later.

I think I can interrupt them first using interrupt and then either control the system in ISR or switch to some handler task which has the highest priority and then suspend or delete the slave tasks there to free the resource used by the slave tasks. I didn’t know that the idle task does the clearning after deleting a task and thought as a tiny system freertos doens’t have any deferred processing mechanism.

I think as long as the slave tasks don’t use non-interruptable mechanism like taskENTER_CRITICAL() , taskEXIT_CRITICAL() or locking the scheduler, one can always interrupt it if the interrupt has a higher priority.

richard_damon wrote on Saturday, January 20, 2018:

If the need is just to have some action happen qucikly, then that is exactly one of the uses of a high priority task. As to tasks being able to block the system with critical sections or stopping the scheduler, that is an issue of proper system design.

Critical sections need to be strictly limited in length, with that limit controlled by how much latency is allowed to be added to interupt servicing. The kernal uses a policy of these are only for very short and deterministic intervals (no loops over lists), and I typically think of the restriction as they should be no more than an order of microsecords (and that is long), They tend to be very short, guarding the change of a global variable or two.

Schedule stopping can be somewhat longer, being limited by the wors case task latency. FreeRTOS uses this when it needs to scan a list use globally. I personally think of it as usable for periods of larger number of microseconds, but not for the range of mill-seconds. I don’t find a lot of uses for this operation.

Longer interlocks tend to be for a specific resource, and don’t need a ‘global’ block, and use a mutex or a semaphore protecting that specific resource. This sort of interlock is much less apt to interfear with you ‘Emergency’ task operation.

One key point, which is somewhat different than sometimes on bigger OSes, is that you are runnign A program, and you in general need to be able to trust that you are following your own design rules. It isnt a case like on a big machine where a supervisory process can detect that a lesser process has ‘broken the rules’ and kill it and let the system clean up. FreeRTOS tasks are NOT processes in that sense, but much more like a thread on a big system OS. A FreeRTOS task really only be deleted when it is at a know state, so you know what clean up needs to be done.

As to the Idle task doing the clean up, If Task A deletes Task B, in the latest versions of FreeRTOS, that happens immediately, the deferal to the Idle task only happens for the case of a task deleting itself, as the task needs to be removed from the scheduler before the cleanup starts, which means it can’t do the cleanup itself, so it is deferred to the Idle task. I wil note that I rarely find a need to delete a task, as that imples that tasks are also created dynamically, which implies critcal usage of dynamic memory, which is something I try very hard to avoid. My policy is that after the application has finished initialization, usage of the heap is absolutly minimized and only for non-critical operations that are allowed to fail.

sdfewa wrote on Sunday, January 21, 2018:

Thanks, Richard. Very informative and good comparison between rtoses and non-rtoses in general.
Yes, I will make sure it is safe even in the worst scenario when the emergency button is pushed.

In order to benefit more people, I put a question about different time solution in a seperate question: