Timer driven interrupts

Dear Husarion users,

I am using CORE2 board and would like to ask about the simplest possible way
to divide the “software” space of the uP into two spaces:

  1. So called “super loop” architecture that goes on and on.
  2. Timer interrupt driven architecture that can be called for instance every 10ms
    Of course I don’t want to use any software delays.

The first one is obvious and can be realized in main() function using while(1)
The second needs one timer that reloads itself after let’s say 10ms. During reload action the interrupt is called
that can be used to run the specific part of the program.

I realize that my problem is rather trivial and can be realized in several different ways but I would like to ask about the simplest possible solution, rather not using tasks.

Regards
Tom

Hi Tom,

Tasks was created specifically for dividing the program into different independent functions, so I have to ask. Why you don’t want to use tasks? I need to know this to give you the most suitable advice.

Best Regards,
Hubert

Hi Hubert,
Maybe, the problem is that I don’t really understand the task concept. Probably we are looking at the problem from two different sides. For control applications (like PID control, etc.) I need the system tick of several, let’s say 10ms to give precise intervals to call the control function. Having this “base clock” I can do other different functions that should be called periodically like switch debouncing, reading analog inputs etc. To change the period of the “base clock” I simply count the timer interrupts for instance 100 times and I have 1second base for LEDs. In this concept I have two program spaces: while(1) loop for non time critical functions (like calculations) and timer driven functions for time critical functions (like control actions). That is really enough for most of embedded systems. This concept comes from low level programming that I was using first. After that I started to use C/C++ for control applications but trying to maintain the same well known structure using timers.
So I ask if this is possible to realize using Husarion framework?

Now returning to tasks. When I go through one of your examples: System_sys_task.cpp I see in the main function:

void hMain()
{
sys.taskCreate(&buzzer); // running task buzzer
sys.taskCreate(&motors); // running task motors
sys.taskCreate(&tog); //runing task tog
while (true)
{
Serial.printf(“fizz\n”);
sys.delay(1000);
}
}

and one of the functions:

void buzzer() // creating instruction for buzzer
{
while (true)
{
Serial.printf(“buzz\n”);
sys.delay(500);
}
}

I understand that first I create and run some tasks like buzzer, motors and tog. They are running in different intervals because of different sys.delay().
But what happens if I have the same value in sys.delay()?
The next question is how many tasks can I create and how are they related to 100% of uP calculations ability? Is sys.delay() “wasting” the processor power - or it is made using timers?
How can I calculate how much processor power I have left in while(true) loop?

Regards
Tom

Hi Tom,

It is possible to achieve time critical functions in hFramework, the tasks are designed for it.

But what happens if I have the same value in sys.delay()?

Function sys.delay() stops the task for given amount of seconds, thus the full time of each loop will take is sum of code execution + loop time. Depending on code executed in each loop the time will vary.
If you want more control and regular execution of each loop, there is sys.delaySync() function. It will stop the task until the given time has passed regardless how much time did it take to execute loop.
If you want your tasks not to interfere during execution, you can set different reference time for each of your tasks.

The next question is how many tasks can I create and how are they related to 100% of uP calculations ability?

There is no fixed limit for number of tasks, but they will be limited by amount of memory they consume. Each task is consuming processor power only during operations + a bit for switching between tasks.

Is sys.delay() “wasting” the processor power - or it is made using timers?

Both sys.delay() and sys.delaySync() are based on timers, they are not blocking processor while waiting.

How can I calculate how much processor power I have left in while(true) loop?

You could use sys.getStats() function. It prints processor usage by each running task.

Regards,
Łukasz

Dear Łukasz,
Thank you very much for very detailed answers.
As I see the whole concept of hFramework is very well designed and takes different scenarios
that potential customers can have.
Yesterday I started to use tasks in a few of examples and found them friendly and useful.
One question that arose yesterday was how to pass variables between different tasks?
I had two tasks: one for checking the button and the other for moving the servo and even when I was
using the global variable I couldn’t pass the information form one task to the other. The solution was to check the button inside the servo task, but the question - how to pass the variables - remained.

Best wishes
Tom

Hi Tom,

I prepared a simple example of how to communicate between tasks:

#include "hFramework.h"

using namespace hFramework;

bool pressed = false;

void button_task()
{
	while (true)
	{
		pressed = hBtn1.isPressed();
		hLED3.set(pressed);
		sys.delay(50);
	}
}

void led_task()
{
	while (true)
	{
		hLED1.set(pressed);
		sys.delay(50);
	}
}

void hMain()
{
	sys.taskCreate(button_task);
	sys.taskCreate(led_task);

	while (true)
	{
		sys.delay(100);
	}
}

Above code is checking the button state, and switches LEDs state accordingly. Both tasks use the same bool pressed to set the LED state.

In case you are still encountering problems with servo, please post here your code.

Regards,
Łuaksz