#include <native/timer.h>
#include <native/sem.h>
-#include <rtdk.h>
+#include <rtdk.h>
+RT_TASK task[5];
+RT_SEM sem;
-#define ITER 10
-
-static RT_TASK t1;
-static RT_TASK t2;
-
-int global = 0;
-
-void taskOne(void *arg)
-{
- int i;
- for (i=0; i < ITER; i++)
- {
- rt_printf("I am taskOne and global = %d................\n", ++global);
- }
-}
-
-void taskTwo(void *arg)
+void demo(void *arg)
{
- int i;
- for (i=0; i < ITER; i++)
- {
- rt_printf("I am taskTwo and global = %d----------------\n", --global);
- }
+ int num = * (int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+ curtask=rt_task_self();
+ rt_task_inquire(curtask, &curtaskinfo);
+ rt_sem_p(&sem, TM_INFINITE);
+ rt_printf("Task name: %s - Argument %d\n", curtaskinfo.name, num);
+ rt_sem_v(&sem);
}
int main(int argc, char* argv[])
{
- /* Perform auto-init of rt_print buffers if the task doesn't do so */
- rt_print_auto_init(1);
-
- /* Avoids memory swapping for this program */
- mlockall(MCL_CURRENT|MCL_FUTURE);
-
- /* create the two tasks */
- rt_task_create(&t1, "task1", 0, 1, 0);
- rt_task_create(&t2, "task2", 0, 1, 0);
-
- /* start the two tasks */
- rt_task_start(&t1, &taskOne, 0);
- rt_task_start(&t2, &taskTwo, 0);
-
- return 0;
+ char str[10] ;
+ int i;
+
+ rt_print_auto_init(1);
+ mlockall(MCL_CURRENT | MCL_FUTURE);
+ rt_printf("start task\n");
+
+ rt_sem_create(&sem, "sem", 0, S_FIFO);
+
+ for (i=0; i<5; i++)
+ {
+ sprintf(str, "hello-%d", i);
+ rt_task_create(&task[i], str, 0, 50+i, 0);
+ rt_task_start(&task[i], &demo, &i);
+ }
+// rt_sem_v(&sem);
+ rt_sem_broadcast(&sem);
}
-
-
Since the first task is started first the main loop halts until it's finished.
3b.
+This works because the semaphore queue is FIFO. So the first one locks the
+semaphore to update the global variable, the second task also wants to do this
+but he has to wait in the queue and will be the next in line. After the first
+task releases the semaphore the second task locks it and the first task has to
+line up in the queue again. This goes on, tasks taking turns, till the tasks
+are finished.
3c.
+rt_sem_v doesn't work because they are released and the first one will get the
+lock. rt_sem_broadcast works because all tasks are released at the same time
+and the priority is then the next measure of who goes first.
--- /dev/null
+CFLAGS=$(shell xeno-config --xeno-cflags) -lnative -lrtdk
+LDFLAGS=$(shell xeno-config --xeno-ldflags)
+
+BINARIES=$(addprefix ex06,a b c d)
+
+all: $(BINARIES)
+
+clean:
+ $(RM) -v $(BINARIES) *.o
-/* ex06a.c */
-
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <native/timer.h>
#include <native/sem.h>
-#include <rtdk.h>
+#include <rtdk.h>
#include <sys/io.h>
#define NTASKS 3
-#define HIGH 52 /* high priority */
-#define MID 51 /* medium priority */
-#define LOW 50 /* low priority */
-
-RT_TASK demo_task[NTASKS];
-RT_SEM mysync;
-
#define BASEPERIOD 0 // baseperiod 0 to get ns
#define EXECTIME 2e8 // execution time in ns
#define SPINTIME 1e7 // spin time in ns
+RT_TASK demo_task[NTASKS];
+RT_SEM mysync;
+
void demo(void *arg)
{
- RTIME starttime, runtime;
- int num=*(int *)arg;
- RT_TASK *curtask;
- RT_TASK_INFO curtaskinfo;
-
- rt_printf("Task : %d\n",num);
-
- rt_sem_p(&mysync,TM_INFINITE);
-
- runtime = 0;
- while(runtime < EXECTIME) {
- rt_timer_spin(SPINTIME); // spin cpu doing nothing
-
- runtime = runtime + SPINTIME;
-
- rt_printf("Running Task : %d at ms : %d\n",num,runtime/1000000);
- }
- rt_printf("End Task : %d\n",num);
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+
+ rt_printf("Task: %d\n", num);
+
+ rt_sem_p(&mysync, TM_INFINITE);
+
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ rt_timer_spin(SPINTIME); // spin cpu doing nothing
+ runtime = runtime + SPINTIME;
+ rt_printf("Running Task: %d at ms: %d\n", num, runtime/1000000);
+ }
+ rt_printf("End Task: %d\n", num);
}
//startup code
void startup()
{
- int i;
- char str[10] ;
-
- // semaphore to sync task startup on
- rt_sem_create(&mysync,"MySemaphore",0,S_FIFO);
-
- // set timing to ns
- rt_timer_set_mode(BASEPERIOD);
-
- for(i=0; i < NTASKS; i++) {
- rt_printf("start task : %d\n",i);
- sprintf(str,"task%d",i);
- rt_task_create(&demo_task[i], str, 0, 50, 0);
- rt_task_start(&demo_task[i], &demo, &i);
- }
- // assign priorities to tasks
- // (or in creation use 50+i)
- rt_task_set_priority(&demo_task[0],LOW);
- rt_task_set_priority(&demo_task[1],MID);
- rt_task_set_priority(&demo_task[2],HIGH);
-
- rt_printf("wake up all tasks\n");
- rt_sem_broadcast(&mysync);
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // set timing to ns
+ rt_timer_set_mode(BASEPERIOD);
+
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n",i);
+ sprintf(str,"task%d",i);
+ rt_task_create(&demo_task[i], str, 0, 50+i, 0);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
}
void init_xenomai() {
- /* Avoids memory swapping for this program */
- mlockall(MCL_CURRENT|MCL_FUTURE);
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT|MCL_FUTURE);
- /* Perform auto-init of rt_print buffers if the task doesn't do so */
- rt_print_auto_init(1);
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
}
int main(int argc, char* argv[])
{
- printf("\nType CTRL-C to end this program\n\n" );
+ printf("\nType CTRL-C to end this program\n\n" );
- // code to set things to run xenomai
- init_xenomai();
+ // code to set things to run xenomai
+ init_xenomai();
- //startup code
- startup();
+ //startup code
+ startup();
- // wait for CTRL-c is typed to end the program
- pause();
+ // wait for CTRL-c is typed to end the program
+ pause();
}
--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/sem.h>
+
+#include <rtdk.h>
+#include <sys/io.h>
+
+#define NTASKS 3
+
+#define BASEPERIOD 0 // baseperiod 0 to get ns
+
+#define EXECTIME 2e8 // execution time in ns
+#define SPINTIME 1e7 // spin time in ns
+
+RT_TASK demo_task[NTASKS];
+RT_SEM mysync;
+
+void demo(void *arg)
+{
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+
+ rt_printf("Task: %d\n", num);
+
+ rt_sem_p(&mysync, TM_INFINITE);
+
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ rt_timer_spin(SPINTIME); // spin cpu doing nothing
+ runtime = runtime + SPINTIME;
+ rt_printf("Running Task: %d at ms: %d\n", num, runtime/1000000);
+ }
+ rt_printf("End Task: %d\n", num);
+}
+
+//startup code
+void startup()
+{
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // set timing to ns
+ rt_timer_set_mode(BASEPERIOD);
+
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n",i);
+ sprintf(str,"task%d",i);
+ rt_task_create(&demo_task[i], str, 0, i == 1 ? 52 : 50+i, 0);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
+}
+
+void init_xenomai() {
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT|MCL_FUTURE);
+
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
+}
+
+int main(int argc, char* argv[])
+{
+ printf("\nType CTRL-C to end this program\n\n" );
+
+ // code to set things to run xenomai
+ init_xenomai();
+
+ //startup code
+ startup();
+
+ // wait for CTRL-c is typed to end the program
+ pause();
+}
--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/sem.h>
+
+#include <rtdk.h>
+#include <sys/io.h>
+
+#define NTASKS 3
+
+#define BASEPERIOD 0 // baseperiod 0 to get ns
+
+#define EXECTIME 2e8 // execution time in ns
+#define SPINTIME 1e7 // spin time in ns
+
+RT_TASK demo_task[NTASKS];
+RT_SEM mysync;
+int switch_happened = 0;
+
+void demo(void *arg)
+{
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+
+ rt_printf("Task: %d\n", num);
+
+ rt_sem_p(&mysync, TM_INFINITE);
+
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ if(num == 2 && runtime >= EXECTIME/2 && switch_happened == 0){
+ rt_task_set_priority(&demo_task[1], 51+10);
+ rt_task_set_priority(&demo_task[0], 50+10);
+ switch_happened = 1;
+ }
+ rt_timer_spin(SPINTIME); // spin cpu doing nothing
+ runtime = runtime + SPINTIME;
+ rt_printf("Running Task: %d at ms: %d\n", num, runtime/1000000);
+ }
+ rt_printf("End Task: %d\n", num);
+}
+
+//startup code
+void startup()
+{
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // set timing to ns
+ rt_timer_set_mode(BASEPERIOD);
+
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n",i);
+ sprintf(str,"task%d",i);
+ rt_task_create(&demo_task[i], str, 0, 50+i, 0);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
+}
+
+void init_xenomai() {
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT|MCL_FUTURE);
+
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
+}
+
+int main(int argc, char* argv[])
+{
+ printf("\nType CTRL-C to end this program\n\n" );
+
+ // code to set things to run xenomai
+ init_xenomai();
+
+ //startup code
+ startup();
+
+ // wait for CTRL-c is typed to end the program
+ pause();
+}
--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/sem.h>
+
+#include <rtdk.h>
+#include <sys/io.h>
+
+#define NTASKS 3
+
+#define BASEPERIOD 0 // baseperiod 0 to get ns
+
+#define EXECTIME 2e8 // execution time in ns
+#define SPINTIME 1e7 // spin time in ns
+
+RT_TASK demo_task[NTASKS];
+RT_SEM mysync;
+int switch_happened[NTASKS] = {0, 0, 0};
+
+void demo(void *arg)
+{
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+
+ rt_printf("Task: %d\n", num);
+
+ rt_sem_p(&mysync, TM_INFINITE);
+
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ if(runtime >= EXECTIME/2 && switch_happened[num] == 0){
+ rt_task_set_priority(&demo_task[num],
+ num == 0 ? 40 : (num == 1 ? 39 : 38));
+ switch_happened[num] = 1;
+ }
+ rt_timer_spin(SPINTIME); // spin cpu doing nothing
+ runtime = runtime + SPINTIME;
+ rt_printf("Running Task: %d at ms: %d\n", num, runtime/1000000);
+ }
+ rt_printf("End Task: %d\n", num);
+}
+
+//startup code
+void startup()
+{
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // set timing to ns
+ rt_timer_set_mode(BASEPERIOD);
+
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n",i);
+ sprintf(str,"task%d",i);
+ rt_task_create(&demo_task[i], str, 0, 50+i, 0);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
+}
+
+void init_xenomai() {
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT|MCL_FUTURE);
+
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
+}
+
+int main(int argc, char* argv[])
+{
+ printf("\nType CTRL-C to end this program\n\n" );
+
+ // code to set things to run xenomai
+ init_xenomai();
+
+ //startup code
+ startup();
+
+ // wait for CTRL-c is typed to end the program
+ pause();
+}
--- /dev/null
+6a.
+The tasks are released at the same time so the highest priority task goes first
+so the order is: 2, 1, 0
+
+6b.
+The tasks are all released at the same time so the highest priority goes first.
+Task 1 and 2 have the same priority and then its first come first serve so the
+order is: 1, 2, 0
+
+6c.
+Task 2 starts since it has the highest priority, when it's halfway it changes
+task1 to a priority higher then his own so that task takes over. When task 1 is
+finished task 2 can move on and will change the priority of task 0 to something
+higher then his own so task 1 will start and when task 1 is finished task 2
+executes the rest of his function.
+
+6d.
+Task 2 starts since it has the highest priority, when it's halfway it changes
+to 38 and task 1 kicks in and halfway it changes its priority to 39. Now task 0
+has the highest priority so it goes halfway and changes its priority to 40
+which is again the highest so it can resume execution. When task 0 is finished
+task 1 kicks in again with the second half and when that's done task 2 can
+finish its second half.
--- /dev/null
+CFLAGS=$(shell xeno-config --xeno-cflags) -lnative -lrtdk
+LDFLAGS=$(shell xeno-config --xeno-ldflags)
+
+BINARIES=$(addprefix ex07,a b c)
+
+all: $(BINARIES)
+
+clean:
+ $(RM) -v $(BINARIES) *.o
-/* ex07a.c */
-
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void demo(void *arg)
{
- RTIME starttime, runtime;
- int num=*(int *)arg;
- RT_TASK *curtask;
- RT_TASK_INFO curtaskinfo;
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
- rt_printf("Task : %d\n",num);
+ rt_printf("Task : %d\n", num);
- rt_sem_p(&mysync,TM_INFINITE);
+ rt_sem_p(&mysync,TM_INFINITE);
- // let the task run RUNTIME(=200) jiffies in steps of SPINTIME(=20) jiffies
- runtime = 0;
- while(runtime < EXECTIME) {
- rt_timer_spin(SPINTIME*BASEPERIOD); // spin cpu doing nothing
- // note: rt_timer_spin function does not accept jiffies only nanoseconds
- // deviates from timing conventions throughout the Xenomai API
+ // let the task run RUNTIME(=200) jiffies in steps of SPINTIME(=20) jiffies
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ rt_timer_spin(SPINTIME*BASEPERIOD); // spin cpu doing nothing
+ // note: rt_timer_spin function does not accept jiffies only nanoseconds
+ // deviates from timing conventions throughout the Xenomai API
- runtime = runtime + SPINTIME;
+ runtime += SPINTIME;
- rt_printf("Running Task : %d at time : %d\n",num,runtime);
- }
- rt_printf("End Task : %d\n",num);
+ rt_printf("Running Task: %d at time: %d\n", num, runtime);
+ }
+ rt_printf("End Task: %d\n", num);
}
//startup code
void startup()
{
- int i;
- char str[10] ;
-
- // semaphore to sync task startup on
- rt_sem_create(&mysync,"MySemaphore",0,S_FIFO);
-
- // change to period mode because round robin does not work
- // in one shot mode
- rt_timer_set_mode(BASEPERIOD);// set tick period
- for(i=0; i < NTASKS; i++) {
- rt_printf("start task : %d\n",i);
- sprintf(str,"task%d",i);
- rt_task_create(&demo_task[i], str, 0, 50, 0);
- rt_task_start(&demo_task[i], &demo, &i);
- }
- rt_printf("wake up all tasks\n");
- rt_sem_broadcast(&mysync);
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // change to period mode because round robin does not work
+ // in one shot mode
+ rt_timer_set_mode(BASEPERIOD);// set tick period
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n", i);
+ sprintf(str, "task%d", i);
+ rt_task_create(&demo_task[i], str, 0, 50, 0);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
}
void init_xenomai() {
- /* Avoids memory swapping for this program */
- mlockall(MCL_CURRENT|MCL_FUTURE);
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT | MCL_FUTURE);
- /* Perform auto-init of rt_print buffers if the task doesn't do so */
- rt_print_auto_init(1);
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
}
int main(int argc, char* argv[])
{
- printf("\nType CTRL-C to end this program\n\n" );
+ printf("\nType CTRL-C to end this program\n\n" );
- // code to set things to run xenomai
- init_xenomai();
+ // code to set things to run xenomai
+ init_xenomai();
- //startup code
- startup();
+ //startup code
+ startup();
- // wait for CTRL-c is typed to end the program
- pause();
+ // wait for CTRL-c is typed to end the program
+ pause();
}
--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/sem.h>
+
+#include <rtdk.h>
+#include <sys/io.h>
+
+#define NTASKS 3
+
+RT_TASK demo_task[NTASKS];
+RT_SEM mysync;
+
+// set new baseperiod for the clock :
+// - clock only increments counter when a base period is passed
+// - the unit of the clock counter is called a jiffie, which in fact
+// represents that a baseperiod is passed
+// e.g. If 10 baseperiods are passed, the clock gives an increase
+// in 10 jiffies
+#define BASEPERIOD 1e6 // baseperiod in ns.
+
+// when base period is set, all times in the api are expressed in jiffies
+#define EXECTIME 200 // execution time in jiffies
+#define SPINTIME 10 // spin time in jiffies
+
+void demo(void *arg)
+{
+ rt_task_set_mode(0, T_RRB, NULL);
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+
+ rt_printf("Task: %d\n", num);
+
+ rt_sem_p(&mysync, TM_INFINITE);
+
+ // let the task run RUNTIME(=200) jiffies in steps of SPINTIME(=20) jiffies
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ rt_timer_spin(SPINTIME*BASEPERIOD); // spin cpu doing nothing
+ // note: rt_timer_spin function does not accept jiffies only nanoseconds
+ // deviates from timing conventions throughout the Xenomai API
+
+ runtime = runtime + SPINTIME;
+
+ rt_printf("Running Task: %d at time: %d\n", num, runtime);
+ }
+ rt_printf("End Task: %d\n", num);
+}
+
+//startup code
+void startup()
+{
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // change to period mode because round robin does not work
+ // in one shot mode
+ rt_timer_set_mode(BASEPERIOD);// set tick period
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n", i);
+ sprintf(str, "task%d", i);
+ rt_task_create(&demo_task[i], str, 0, 50, 0);
+ rt_task_slice(&demo_task[i], 1);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
+}
+
+void init_xenomai() {
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT | MCL_FUTURE);
+
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
+}
+
+int main(int argc, char* argv[])
+{
+ printf("\nType CTRL-C to end this program\n\n" );
+
+ // code to set things to run xenomai
+ init_xenomai();
+
+ //startup code
+ startup();
+
+ // wait for CTRL-c is typed to end the program
+ pause();
+}
--- /dev/null
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/sem.h>
+
+#include <rtdk.h>
+#include <sys/io.h>
+
+#define NTASKS 4
+
+RT_TASK demo_task[NTASKS];
+RT_SEM mysync;
+
+// set new baseperiod for the clock :
+// - clock only increments counter when a base period is passed
+// - the unit of the clock counter is called a jiffie, which in fact
+// represents that a baseperiod is passed
+// e.g. If 10 baseperiods are passed, the clock gives an increase
+// in 10 jiffies
+#define BASEPERIOD 1e6 // baseperiod in ns.
+
+// when base period is set, all times in the api are expressed in jiffies
+#define EXECTIME 200 // execution time in jiffies
+#define SPINTIME 10 // spin time in jiffies
+
+void demo(void *arg)
+{
+ rt_task_set_mode(0, T_RRB, NULL);
+ RTIME starttime;
+ RTIME runtime;
+ int num = *(int *)arg;
+ RT_TASK *curtask;
+ RT_TASK_INFO curtaskinfo;
+
+ rt_printf("Task: %d\n", num);
+
+ rt_sem_p(&mysync, TM_INFINITE);
+
+ // let the task run RUNTIME(=200) jiffies in steps of SPINTIME(=20) jiffies
+ runtime = 0;
+ while(runtime < EXECTIME) {
+ rt_timer_spin(SPINTIME*BASEPERIOD); // spin cpu doing nothing
+ // note: rt_timer_spin function does not accept jiffies only nanoseconds
+ // deviates from timing conventions throughout the Xenomai API
+
+ runtime = runtime + SPINTIME;
+
+ rt_printf("Running Task: %d at time: %d\n", num, runtime);
+ }
+ rt_printf("End Task: %d\n", num);
+}
+
+//startup code
+void startup()
+{
+ int i;
+ char str[10] ;
+
+ // semaphore to sync task startup on
+ rt_sem_create(&mysync, "MySemaphore", 0, S_FIFO);
+
+ // change to period mode because round robin does not work
+ // in one shot mode
+ rt_timer_set_mode(BASEPERIOD);// set tick period
+ for(i = 0; i < NTASKS; i++) {
+ rt_printf("start task: %d\n", i);
+ sprintf(str, "task%d", i);
+ rt_task_create(&demo_task[i], str, 0, i == 3 ? 80 : 50, 0);
+ rt_task_slice(&demo_task[i], 1);
+ rt_task_start(&demo_task[i], &demo, &i);
+ }
+ rt_printf("wake up all tasks\n");
+ rt_sem_broadcast(&mysync);
+}
+
+void init_xenomai() {
+ /* Avoids memory swapping for this program */
+ mlockall(MCL_CURRENT | MCL_FUTURE);
+
+ /* Perform auto-init of rt_print buffers if the task doesn't do so */
+ rt_print_auto_init(1);
+}
+
+int main(int argc, char* argv[])
+{
+ printf("\nType CTRL-C to end this program\n\n" );
+
+ // code to set things to run xenomai
+ init_xenomai();
+
+ //startup code
+ startup();
+
+ // wait for CTRL-c is typed to end the program
+ pause();
+}
--- /dev/null
+7a.
+The tasks just run according to the order of starting so: 0, 1, 2
+
+7b.
+The tasks just finish one bit every time.
+
+7c.
+Same as 7b except that task 3 finishes completely first. This is because round
+robin is only used for tasks with the same priority.