Re: Periodic scheduling of 2 kernel tasks (different modules)

bhargavb <[email protected]> Tue, 9 May 2017 10:52:47 +0530
Newsgroups gmane.linux.real-time.rtai
Message-ID <CA+bpL9KPi+fE3bEc7vFQbrXVJAy7BOkbJO2ZEMhZ2t866ptgxw@mail.gmail.com>
Dear Shabby,

Thank you for your response.
1) Attached the code files task1.c, task2.c and the scripts used to start
rt modules, insert and remove the task1 and task2 modules.
 So, I used script (task.sh) to insert the 2 kernel modules. (sudo insmod
task1.ko && sudo insmod task2.ko). Also, rt_printk is used.

*Code snapshots below for quick reference:*
* task1 : *
rt_task_init(&t1,taskOne, 0, 1024, *0*, 0, 0);
now = rt_get_time();
rt_task_make_periodic(&t1,now + (38 * tick_period),tick_period);
// This is high priority but starting late, so as to preempt other. Tried
modifying start time to various values


*task2:*
retval = rt_task_init(&t2,taskTwo, 0, 1024, *1*, 0, 0);
tick_period = start_rt_timer(nano2count(TIMERTICKS));
now = rt_get_time();
rt_task_make_periodic(&t2,now + (10 * tick_period),tick_period); // This is
scheduled first but should be preempted by task1

The output is not consistent.

2) I am sorry, I have not understood clearly or completely. One thing
importantly I did not understand is whether oneshot mode counter generates
a timer interrupt only once? periodic mode keeps generating timer interrupt
indefinetely as per period set. In oneshot mode the timer doesnt restart
with given load value again so, no mode timer interrupts should be
generated if my understanding is correct. How does scheduler get invoked
then?
Continuing the same question, below:
I understood rt_task_make_periodic(xxx) is for the particular task under
schedule that is made periodic. So, the default behaviour of oneshot mode
remains, unless a call to rt_set_periodic_mode() is called.  So, when I do
not call any api related to periodic mode, and a task is scheduled which
should run for say 1 minute (for at least one full execution and there on
the same code repetition as in a while loop); and the oneshot mode timer
load value corresponding to say less than 2 minutes and greater than 1
minute, the task will run for 2 full cycles/loops of 1 minute each as,
after that the timer interrupt should be not generated after 2 minutes.

Also, there is only one timer and how can it act both in oneshot mode and
as periodic timer interrupt generator simultaneously and with multiple
timing frequencies for various periodic tasks.

Thanks and regards,
Bhargav


On Mon, May 8, 2017 at 10:43 PM, Shahbaz Youssefi <[email protected]> wrote:

>
>
> On Mon, May 8, 2017 at 11:51 AM, bhargavb <[email protected]>
> wrote:
>
>> Hello,
>>
>> I am a beginner in rtai (and kernel module programming). Kindly answer
>> below queries.
>>
>> *Question 1:*
>> I have written 2 simple rtai kernel modules using periodic scheduling,
>> both of them.
>> One module prints one number each period (starting from 1 to 10
>> incrementing each period) and other one does the same thing -1 to -10
>> decrementing each period.
>> There are no other rtai kernel modules that I have inserted except the
>> two (apart from rtai hal,sched etc).
>>
>> In this scenario, where no other real time modules are inserted by me,
>> shouldn't the behaviour be consistent? It is not happening so.
>> If in a cycle it prints 1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,
>> 7,-7,8,-8,9,-9,10,-10
>> in other cycle of execution (I do rmmod and insmod again), it prints some
>> other pattern like 1,2,3,4,-1,-2,5,6, etc
>>
>> As long as same logic is present in each rtai kernel modules and no new
>> rtai kernel module inserted or deleted, the output should be same each
>> execution in real time. But it is not so. I did not get this. Please help
>> me understand.
>>
>
> Please provide some code. What are the task priorities? Are you using
> `printk` or `rt_printk`? How do you insert the modules (manually from the
> terminal? A script that inserts one after the other)?
>
>
>>
>> *Question 2:*
>> I have seen in some of the example code samples, *rt_set_oneshot_mode()*
>> is called and then *start_rt_timer(1)*, then *rt_task_init()* and
>> *rt_task_make_periodic()* . Does one shot mode setting of the timer have
>> any effect in the sequence of calls? I understand the timer can be either
>> set to one shot mode or periodic mode. I understand we are setting one shot
>> mode initially and then overriding the setting by calling
>> *rt_task_make_periodic()*. Is my understanding correct? I mean it is
>> same as removing the call to rt_set_oneshot_mode()
>>
>> ---
>> ---
>> ---
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> *  rt_set_oneshot_mode();
>> timer_period_count=nano2count(timer_period_ns);
>> start_rt_timer(timer_period_count);
>> rt_task_init_cpuid(&tau_2,  /* pointer to our task structure
>> */                 f_tau_2,       /* the task function */
>> 0,             /* arg for f_tau_2 */                 1024,          /* size
>> of the stack */                 100,           /* tau_2 has priority = 100
>> */                 0,             /* we don't use floating point unit
>> */                 0,             /* we don't use signals
>> */                 0);            /* run on CPU 0 */
>> rt_task_make_periodic(&tau_1, /* pointer to our task structure
>> */                                  /* start 2 timer_periods from now
>> */                          rt_get_time() +
>> 2*timer_period_count,                          5*timer_period_count); /*
>> recurring period (ignored in one-shot) */*
>> ---
>> ---
>> ---
>>
>>
> rt_set_oneshot_mode and start_rt_timer have to do with the scheduling
> clock of RTAI as a whole, while rt_task_make_periodic identifies just one
> of the tasks as periodic. From documentation of rt_task_make_periodic*:
>
> Recall that the term clock ticks depends on the mode in which the hard
> timer runs. So if the hard timer was set as periodic a clock tick will last
> as the period set in start_rt_timer, while if oneshot mode is used a clock
> tick will last as the inverse of the running frequency of the hard timer in
> use and irrespective of any period used in the call to start_rt_timer.
>
> If I recall correctly, oneshot mode is default (and periodic mode is
> deprecated?)
>
>
>>
>> Thanks and regards,
>> Bhargav
>>
>> _______________________________________________
>> Rtai mailing list
>> [email protected]
>> https://mail.rtai.org/cgi-bin/mailman/listinfo/rtai
>>
>
>


-- 
Bhargav

_______________________________________________
Rtai mailing list
[email protected]
https://mail.rtai.org/cgi-bin/mailman/listinfo/rtai
task.sh (application/x-sh, 62 B)
#!/bin/bash

sudo insmod ./task1.ko && sudo insmod ./task2.ko
task1.c (text/x-csrc, 1.4 KB)
/*
   file global.c
   update global variable by two tasks
*/

/* includes */
#include <linux/kernel.h>	/* decls needed for kernel modules */
#include <linux/module.h>	/* decls needed for kernel modules */
#include <linux/version.h>	/* LINUX_VERSION_CODE, KERNEL_VERSION() */
#include <linux/errno.h>	/* EINVAL, ENOMEM */

/*
  Specific header files for RTAI, our flavor of RT Linux
 */
#include "rtai.h"		/* RTAI configuration switches */
#include "rtai_sched.h"	/* RTAI scheduling */
#include <rtai_sem.h>   /* RTAI semaphores */
#include <rtai_fifos.h>   /* RTAI semaphores */

MODULE_LICENSE("GPL");

/* globals */
#define ITER 10
#define TIMERTICKS 500000
static RT_TASK  t1;
/* function prototypes */
void taskOne(long arg);

int global = 0;

void tasks(void)
{
    int retval;
	RTIME tick_period;
	RTIME now;
	tick_period = start_rt_timer(nano2count(TIMERTICKS));

    /* init the two tasks */
    retval = rt_task_init(&t1,taskOne, 0, 1024, 0, 0, 0);
	now = rt_get_time();
	rt_task_make_periodic(&t1,now + (38 * tick_period),tick_period);
}

void taskOne(long arg)
{
    int i;
    for (i=0; i < ITER; i++)
    {
        rt_printk("1 I am taskOne and global = %d................\n", ++global);
	rt_task_wait_period();	
    }
}

int init_module(void)
{
    rt_printk("start of init_module\n");
    tasks();
    rt_printk("end of init_module\n");
    return 0;
}

void cleanup_module(void)
{
    // task end themselves -> not necessary to delete them
    return;
}
task2.c (text/x-csrc, 1.5 KB)
/*
   file global.c
   update global variable by two tasks
*/

/* includes */
#include <linux/kernel.h>	/* decls needed for kernel modules */
#include <linux/module.h>	/* decls needed for kernel modules */
#include <linux/version.h>	/* LINUX_VERSION_CODE, KERNEL_VERSION() */
#include <linux/errno.h>	/* EINVAL, ENOMEM */

/*
  Specific header files for RTAI, our flavor of RT Linux
 */
#include "rtai.h"		/* RTAI configuration switches */
#include "rtai_sched.h"	/* RTAI scheduling */
#include <rtai_sem.h>   /* RTAI semaphores */
#include <rtai_fifos.h>   /* RTAI semaphores */

MODULE_LICENSE("GPL");

/* globals */
#define ITER 10
#define TIMERTICKS 500000
static RT_TASK  t2;
/* function prototypes */
void taskTwo(long arg);

int global = 0;
int anotherITER = 0;

void tasks(void)
{
    int retval;
	RTIME tick_period;
	RTIME now;
    /* init the two tasks */
    retval = rt_task_init(&t2,taskTwo, 0, 1024, 1, 0, 0);
	tick_period = start_rt_timer(nano2count(TIMERTICKS));
	
	now = rt_get_time();
	rt_task_make_periodic(&t2,now + (10 * tick_period),tick_period);
}

void taskTwo(long arg)
{
    int i;
    for (i=0; i < ITER; i++)
    {
        rt_printk("I am taskTwo and global = %d,anotherITER = %d----------------\n", --global,anotherITER);
	rt_task_wait_period();
    }
}

int init_module(void)
{
    printk("start of init_module\n");

    rt_set_oneshot_mode();
    start_rt_timer(1);

    tasks();

    printk("end of init_module\n");
    return 0;
}

void cleanup_module(void)
{
    // task end themselves -> not necessary to delete them
    return;
}
insmod.sh (application/x-sh, 454 B)
insmod rtai_hal.ko
insmod rtai_sched.ko
insmod rtai_bits.ko
insmod rtai_sem.ko
insmod rtai_msg.ko
insmod rtai_mq.ko
insmod rtai_fifos.ko
insmod rtai_serial.ko
insmod rtai_shm.ko
insmod rtai_tasklets.ko
insmod rtai_mbx.ko
insmod rtai_netrpc.ko
insmod rtai_tbx.ko
insmod rtai_wd.ko
insmod rtai_smi.ko
insmod preempt_rt.ko
insmod switches_rt.ko
insmod latency_rt.ko
insmod kthreads_preempt_rt.ko
insmod kthreads_switches_rt.ko
insmod kthreads_latency_rt.ko