mart week 2
authorroot <root@xenomailinux.localdomain>
Thu, 17 Sep 2015 16:03:42 +0000 (18:03 +0200)
committerroot <root@xenomailinux.localdomain>
Thu, 17 Sep 2015 16:03:42 +0000 (18:03 +0200)
13 files changed:
mart/ex03/ex03c.c
mart/ex03/explanations.txt
mart/ex06/Makefile [new file with mode: 0644]
mart/ex06/ex06a.c
mart/ex06/ex06b.c [new file with mode: 0644]
mart/ex06/ex06c.c [new file with mode: 0644]
mart/ex06/ex06d.c [new file with mode: 0644]
mart/ex06/explanations.txt [new file with mode: 0644]
mart/ex07/Makefile [new file with mode: 0644]
mart/ex07/ex07a.c
mart/ex07/ex07b.c [new file with mode: 0644]
mart/ex07/ex07c.c [new file with mode: 0644]
mart/ex07/explanations.txt [new file with mode: 0644]

index 195a64f..8da98ef 100644 (file)
@@ -7,50 +7,39 @@
 #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);
 }
-
-
index f53474f..941a767 100644 (file)
@@ -2,5 +2,14 @@
 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.
diff --git a/mart/ex06/Makefile b/mart/ex06/Makefile
new file mode 100644 (file)
index 0000000..6eaf467
--- /dev/null
@@ -0,0 +1,9 @@
+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
index cdefd1b..4fb986c 100644 (file)
@@ -1,5 +1,3 @@
-/* ex06a.c */
-
 #include <stdio.h>
 #include <signal.h>
 #include <unistd.h>
@@ -9,91 +7,81 @@
 #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();
 }
diff --git a/mart/ex06/ex06b.c b/mart/ex06/ex06b.c
new file mode 100644 (file)
index 0000000..e131e51
--- /dev/null
@@ -0,0 +1,87 @@
+#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();
+}
diff --git a/mart/ex06/ex06c.c b/mart/ex06/ex06c.c
new file mode 100644 (file)
index 0000000..4a52124
--- /dev/null
@@ -0,0 +1,93 @@
+#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();
+}
diff --git a/mart/ex06/ex06d.c b/mart/ex06/ex06d.c
new file mode 100644 (file)
index 0000000..e3734b9
--- /dev/null
@@ -0,0 +1,93 @@
+#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();
+}
diff --git a/mart/ex06/explanations.txt b/mart/ex06/explanations.txt
new file mode 100644 (file)
index 0000000..3c1c900
--- /dev/null
@@ -0,0 +1,23 @@
+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.
diff --git a/mart/ex07/Makefile b/mart/ex07/Makefile
new file mode 100644 (file)
index 0000000..8a98192
--- /dev/null
@@ -0,0 +1,9 @@
+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
index 11eac9b..857f329 100644 (file)
@@ -1,5 +1,3 @@
-/* ex07a.c */
-
 #include <stdio.h>
 #include <signal.h>
 #include <unistd.h>
@@ -31,69 +29,70 @@ RT_SEM mysync;
 
 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();
 }
diff --git a/mart/ex07/ex07b.c b/mart/ex07/ex07b.c
new file mode 100644 (file)
index 0000000..bf598a1
--- /dev/null
@@ -0,0 +1,100 @@
+#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();
+}
diff --git a/mart/ex07/ex07c.c b/mart/ex07/ex07c.c
new file mode 100644 (file)
index 0000000..81dc33d
--- /dev/null
@@ -0,0 +1,100 @@
+#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();
+}
diff --git a/mart/ex07/explanations.txt b/mart/ex07/explanations.txt
new file mode 100644 (file)
index 0000000..6bc94ec
--- /dev/null
@@ -0,0 +1,9 @@
+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.