From: Natanael Adityasatria Date: Sat, 19 Sep 2015 17:56:37 +0000 (+0200) Subject: Completed exercise 3, 6, 7 X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=44bdc2b3fcda2c488b927b6e47bd47973474ba88;p=des2015.git Completed exercise 3, 6, 7 --- diff --git a/natanael/ex03/Makefile b/natanael/ex03/Makefile new file mode 100644 index 0000000..2b76c79 --- /dev/null +++ b/natanael/ex03/Makefile @@ -0,0 +1,99 @@ +###### CONFIGURATION ###### + +### List of applications to be build +APPLICATIONS = ex03a ex03b ex03c + +### Note: to override the search path for the xeno-config script, use "make XENO=..." + + +### List of modules to be build +MODULES = + +### Note: to override the kernel source path, use "make KSRC=..." + + + +###### USER SPACE BUILD (no change required normally) ###### +ifeq ($(KERNELRELEASE),) +ifneq ($(APPLICATIONS),) + +### Default Xenomai installation path +XENO ?= /usr/xenomai + +XENOCONFIG=$(shell PATH=$(XENO):$(XENO)/bin:$(PATH) which xeno-config 2>/dev/null) + +### Sanity check +ifeq ($(XENOCONFIG),) +all:: + @echo ">>> Invoke make like this: \"make XENO=/path/to/xeno-config\" <<<" + @echo +endif + + +CC=$(shell $(XENOCONFIG) --cc) + +CFLAGS=$(shell $(XENOCONFIG) --xeno-cflags) $(MY_CFLAGS) + +LDFLAGS=$(shell $(XENOCONFIG) --xeno-ldflags) $(MY_LDFLAGS) -lnative + +# This includes the library path of given Xenomai into the binary to make live +# easier for beginners if Xenomai's libs are not in any default search path. +LDFLAGS+=-Xlinker -rpath -Xlinker $(shell $(XENOCONFIG) --libdir) + +LDFLAGS+= -lrtdk + +all:: $(APPLICATIONS) + +clean:: + $(RM) $(APPLICATIONS) *.o + +endif +endif + + + +###### SPECIAL TARGET RULES ###### +rtprint: rtprint.c + $(CC) $(CFLAGS) $? $(LDFLAGS) -lrtdk -o $@ + + + +###### KERNEL MODULE BUILD (no change required normally) ###### +ifneq ($(MODULES),) + +### Default to sources of currently running kernel +KSRC ?= /lib/modules/$(shell uname -r)/build + +OBJS := ${patsubst %, %.o, $(MODULES)} +CLEANMOD := ${patsubst %, .%*, $(MODULES)} +PWD := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) + +### Kernel 2.6 +ifeq ($(findstring 2.6,$(KSRC)),2.6) + +obj-m := $(OBJS) +EXTRA_CFLAGS := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/posix $(ADD_CFLAGS) + +all:: + $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules + +### Kernel 2.4 +else + +ARCH ?= $(shell uname -i) +INCLUDE := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/compat -I$(KSRC)/include/xenomai/posix +CFLAGS += $(shell $(MAKE) -s -C $(KSRC) CC=$(CC) ARCH=$(ARCH) SUBDIRS=$(PWD) modules) $(INCLUDE) + +all:: $(OBJS) + +endif + +## Target for capturing 2.4 module CFLAGS +modules: + @echo "$(CFLAGS)" + +clean:: + $(RM) $(CLEANMOD) *.o *.ko *.mod.c Module*.symvers + $(RM) -R .tmp* + +endif \ No newline at end of file diff --git a/natanael/ex03/ex03_explanation.txt b/natanael/ex03/ex03_explanation.txt new file mode 100644 index 0000000..787f098 --- /dev/null +++ b/natanael/ex03/ex03_explanation.txt @@ -0,0 +1,8 @@ +ex03a +The output shows the task one is started first and it does the looping to increase the Global variable. After that, the task two is started to decrease the Global variable + +ex03b +Semaphores are used to communicate between tasks. In this case, task one communicates with the task two. After one cycle of looping in task one finished, the task two takes control and it does the one cycle of looping. Then it will come back to Task One again. So, task one and task two do the one cycle of looping alternately. + +ex03c +Using semaphore, we can start task that has higher priority than the others. As we can see from the output, the order of the task is based on its priority. \ No newline at end of file diff --git a/natanael/ex03/ex03a.c b/natanael/ex03/ex03a.c new file mode 100644 index 0000000..6ccf9f3 --- /dev/null +++ b/natanael/ex03/ex03a.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#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) +{ + int i; + for (i=0; i < ITER; i++) + { + rt_printf("I am taskTwo and global = %d----------------\n", --global); + } +} + +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; +} + diff --git a/natanael/ex03/ex03b.c b/natanael/ex03/ex03b.c new file mode 100644 index 0000000..872e65c --- /dev/null +++ b/natanael/ex03/ex03b.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define ITER 10 + +static RT_TASK t1; +static RT_TASK t2; + +int global = 0; + +RT_SEM semGlobal1; +RT_SEM semGlobal2; + +void taskOne(void *arg) +{ + int i; + for (i=0; i < ITER; i++) + { + //rt_printf("Before semGlobal2..............\n"); + rt_sem_p(&semGlobal2, 0); + rt_printf("I am taskOne and global = %d................\n", ++global); + rt_sem_v(&semGlobal1); + //rt_printf("After semGlobal1..............\n"); + } +} + +void taskTwo(void *arg) +{ + int i; + for (i=0; i < ITER; i++) + { + //rt_printf("Before semGlobal1--------------\n"); + rt_sem_p(&semGlobal1, 0); + rt_printf("I am taskTwo and global = %d----------------\n", --global); + rt_sem_v(&semGlobal2); + //rt_printf("After semGlobal2--------------\n"); + } +} + +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 semaphore */ + rt_sem_create(&semGlobal1,"semaphore1",0,S_FIFO); + rt_sem_create(&semGlobal2,"semaphore2",1,S_FIFO); + + /* 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; +} + diff --git a/natanael/ex03/ex03c1.c b/natanael/ex03/ex03c1.c new file mode 100644 index 0000000..39acdf6 --- /dev/null +++ b/natanael/ex03/ex03c1.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +RT_TASK demo_task; +RT_SEM semGlobal; + +void demo(void *arg) +{ + rt_sem_p(&semGlobal, 0); + + RT_TASK *curtask; + RT_TASK_INFO curtaskinfo; + + // inquire current task + curtask=rt_task_self(); + rt_task_inquire(curtask,&curtaskinfo); + + // print task name + int num = * (int *)arg; + rt_printf("Task name : %s - Argument %d \n", curtaskinfo.name,num); + + rt_sem_v(&semGlobal); +} + +int main(int argc, char* argv[]) +{ + char str[10] ; + int i; + + // Perform auto-init of rt_print buffers if the task doesn't do so + rt_print_auto_init(1); + + // Lock memory : avoid memory swapping for this program + mlockall(MCL_CURRENT|MCL_FUTURE); + + /* create semaphore */ + rt_sem_create(&semGlobal,"semaphore",0,S_PRIO); + + rt_printf("start task\n"); + + for (i=0; i<5; i++) + { + /* + * Arguments: &task, + * name, + * stack size (0=default), + * priority, + * mode (FPU, start suspended, ...) + */ + sprintf(str,"hello-%d",i); + rt_task_create(&demo_task, str, 0, 50+i, 0); + + /* + * Arguments: &task, + * task function, + * function argument + */ + rt_task_start(&demo_task, &demo, &i); + } + + rt_sem_v(&semGlobal); +} \ No newline at end of file diff --git a/natanael/ex03/ex03c2.c b/natanael/ex03/ex03c2.c new file mode 100644 index 0000000..447dce4 --- /dev/null +++ b/natanael/ex03/ex03c2.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +RT_TASK demo_task; +RT_SEM semGlobal; + +void demo(void *arg) +{ + RT_TASK *curtask; + RT_TASK_INFO curtaskinfo; + + // inquire current task + curtask=rt_task_self(); + rt_task_inquire(curtask,&curtaskinfo); + + rt_sem_p(&semGlobal,TM_INFINITE); + + // print task name + int num = * (int *)arg; + rt_printf("Task name : %s - Argument %d \n", curtaskinfo.name,num); +} + +int main(int argc, char* argv[]) +{ + char str[10] ; + int i; + + // Perform auto-init of rt_print buffers if the task doesn't do so + rt_print_auto_init(1); + + // Lock memory : avoid memory swapping for this program + mlockall(MCL_CURRENT|MCL_FUTURE); + + /* create semaphore */ + rt_sem_create(&semGlobal,"semaphore",0,S_PRIO); + + rt_printf("start task\n"); + + for (i=0; i<5; i++) + { + /* + * Arguments: &task, + * name, + * stack size (0=default), + * priority, + * mode (FPU, start suspended, ...) + */ + sprintf(str,"hello-%d",i); + rt_task_create(&demo_task, str, 0, 50+i, 0); + + /* + * Arguments: &task, + * task function, + * function argument + */ + rt_task_start(&demo_task, &demo, &i); + } + + rt_sem_broadcast(&semGlobal); + +} \ No newline at end of file diff --git a/natanael/ex06/ExplanationEx06.txt b/natanael/ex06/ExplanationEx06.txt new file mode 100644 index 0000000..e30fdb3 --- /dev/null +++ b/natanael/ex06/ExplanationEx06.txt @@ -0,0 +1,14 @@ +ex06a +There are task 0, task 1, and task 2. Since we give the highest priority to task 2, then task 2 is started first until it finishes. After that, it continues to the lower priority, in this case: task 1. Task 0 has the lowest priority, that is why it runs at the end. + +ex06b +The output is different with the output from ex06a. Since task 1 and task 2 have the same priority, task 1 is running first because it was first queued in the waiting queue of the scheduler. We can see from the looping that task 1 is created and started first rather than task 2. Finally, task 0 runs at the end as it has the lowest priority. + +ex06c +On the half-way execution of the highest priority task (task 2), there are another two tasks (task 0 and task 1) which are set to have higher priority. So, these two tasks are run immediately. After task 0 and task 1 finish, it will automatically continue to finish the task 2. + +ex06d +There are task 0, task 1, and task 2. +From the output, we can see that at the first time task 2 has the highest priority. On its half-way execution, task 2 is modified to be the lowest priority. So, task 2 is delayed. Then the execution will continue to the next highest priority, in this case: task 1. +On its half-way execution of task 1, there is another task that has higher priority, in this case: task 0. So, the execution will continue to run task 0. +In conclusion, execution of a low-priority task is interrupted when a high-priority task is ready to execute. \ No newline at end of file diff --git a/natanael/ex06/Makefile b/natanael/ex06/Makefile new file mode 100644 index 0000000..42b17b3 --- /dev/null +++ b/natanael/ex06/Makefile @@ -0,0 +1,99 @@ +###### CONFIGURATION ###### + +### List of applications to be build +APPLICATIONS = ex06a ex06b ex06c ex06d + +### Note: to override the search path for the xeno-config script, use "make XENO=..." + + +### List of modules to be build +MODULES = + +### Note: to override the kernel source path, use "make KSRC=..." + + + +###### USER SPACE BUILD (no change required normally) ###### +ifeq ($(KERNELRELEASE),) +ifneq ($(APPLICATIONS),) + +### Default Xenomai installation path +XENO ?= /usr/xenomai + +XENOCONFIG=$(shell PATH=$(XENO):$(XENO)/bin:$(PATH) which xeno-config 2>/dev/null) + +### Sanity check +ifeq ($(XENOCONFIG),) +all:: + @echo ">>> Invoke make like this: \"make XENO=/path/to/xeno-config\" <<<" + @echo +endif + + +CC=$(shell $(XENOCONFIG) --cc) + +CFLAGS=$(shell $(XENOCONFIG) --xeno-cflags) $(MY_CFLAGS) + +LDFLAGS=$(shell $(XENOCONFIG) --xeno-ldflags) $(MY_LDFLAGS) -lnative + +# This includes the library path of given Xenomai into the binary to make live +# easier for beginners if Xenomai's libs are not in any default search path. +LDFLAGS+=-Xlinker -rpath -Xlinker $(shell $(XENOCONFIG) --libdir) + +LDFLAGS+= -lrtdk + +all:: $(APPLICATIONS) + +clean:: + $(RM) $(APPLICATIONS) *.o + +endif +endif + + + +###### SPECIAL TARGET RULES ###### +rtprint: rtprint.c + $(CC) $(CFLAGS) $? $(LDFLAGS) -lrtdk -o $@ + + + +###### KERNEL MODULE BUILD (no change required normally) ###### +ifneq ($(MODULES),) + +### Default to sources of currently running kernel +KSRC ?= /lib/modules/$(shell uname -r)/build + +OBJS := ${patsubst %, %.o, $(MODULES)} +CLEANMOD := ${patsubst %, .%*, $(MODULES)} +PWD := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) + +### Kernel 2.6 +ifeq ($(findstring 2.6,$(KSRC)),2.6) + +obj-m := $(OBJS) +EXTRA_CFLAGS := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/posix $(ADD_CFLAGS) + +all:: + $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules + +### Kernel 2.4 +else + +ARCH ?= $(shell uname -i) +INCLUDE := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/compat -I$(KSRC)/include/xenomai/posix +CFLAGS += $(shell $(MAKE) -s -C $(KSRC) CC=$(CC) ARCH=$(ARCH) SUBDIRS=$(PWD) modules) $(INCLUDE) + +all:: $(OBJS) + +endif + +## Target for capturing 2.4 module CFLAGS +modules: + @echo "$(CFLAGS)" + +clean:: + $(RM) $(CLEANMOD) *.o *.ko *.mod.c Module*.symvers + $(RM) -R .tmp* + +endif \ No newline at end of file diff --git a/natanael/ex06/ex06a.c b/natanael/ex06/ex06a.c new file mode 100644 index 0000000..c7ea2bb --- /dev/null +++ b/natanael/ex06/ex06a.c @@ -0,0 +1,99 @@ +/* ex06a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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 + +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); +} + +//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); +} + +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(); +} \ No newline at end of file diff --git a/natanael/ex06/ex06b.c b/natanael/ex06/ex06b.c new file mode 100644 index 0000000..a813092 --- /dev/null +++ b/natanael/ex06/ex06b.c @@ -0,0 +1,101 @@ +/* ex06a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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 + +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); +} + +//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); + + // the same priority + rt_task_set_priority(&demo_task[1],HIGH); + rt_task_set_priority(&demo_task[2],HIGH); + + 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(); +} \ No newline at end of file diff --git a/natanael/ex06/ex06c.c b/natanael/ex06/ex06c.c new file mode 100644 index 0000000..697b42b --- /dev/null +++ b/natanael/ex06/ex06c.c @@ -0,0 +1,106 @@ +/* ex06a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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 + +void demo(void *arg) +{ + RTIME starttime, runtime; + int num=*(int *)arg; + RT_TASK *curtask; + RT_TASK_INFO curtaskinfo; + + curtask=rt_task_self(); + 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); + if(runtime == (EXECTIME/2)){ + if(num == 2){ + rt_task_set_priority(&demo_task[1],MID+10); + rt_task_set_priority(&demo_task[0],LOW+10); + } + } + } + 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); +} + +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(); +} \ No newline at end of file diff --git a/natanael/ex06/ex06d.c b/natanael/ex06/ex06d.c new file mode 100644 index 0000000..7e5f679 --- /dev/null +++ b/natanael/ex06/ex06d.c @@ -0,0 +1,111 @@ +/* ex06a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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 + +void demo(void *arg) +{ + RTIME starttime, runtime; + int num=*(int *)arg; + RT_TASK *curtask; + RT_TASK_INFO curtaskinfo; + + curtask=rt_task_self(); + 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); + if(runtime == (EXECTIME/2)){ + if(num == 0){ + rt_task_set_priority(&demo_task[0],40); + } + else if(num == 1){ + rt_task_set_priority(&demo_task[1],39); + } + else if(num == 2){ + rt_task_set_priority(&demo_task[2],38); + } + } + } + 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); +} + +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(); +} \ No newline at end of file diff --git a/natanael/ex07/ExplanationEx07.txt b/natanael/ex07/ExplanationEx07.txt new file mode 100644 index 0000000..40e8a33 --- /dev/null +++ b/natanael/ex07/ExplanationEx07.txt @@ -0,0 +1,9 @@ +ex07a +There are three tasks with the same priority. The one which was queued first in the scheduler, is run first. After the first task is finished, then it will continue to another task in the queue. + +ex07b +The three tasks have the same priority. By using time slicing, round-robin policy tries to give fair resource allocation for all these tasks. So, from the output we can see that there is a lot of task-switching. + +ex07c +Task 4 which has the highest priority will be run first. Althought task 4 uses round-robin policy it will be run first as it is the highest priority task. +After task 4 finishes, it will continue to run task 0, task 1, and task 2 with the round-robin policy \ No newline at end of file diff --git a/natanael/ex07/Makefile b/natanael/ex07/Makefile new file mode 100644 index 0000000..56be179 --- /dev/null +++ b/natanael/ex07/Makefile @@ -0,0 +1,99 @@ +###### CONFIGURATION ###### + +### List of applications to be build +APPLICATIONS = ex07a ex07b ex07c + +### Note: to override the search path for the xeno-config script, use "make XENO=..." + + +### List of modules to be build +MODULES = + +### Note: to override the kernel source path, use "make KSRC=..." + + + +###### USER SPACE BUILD (no change required normally) ###### +ifeq ($(KERNELRELEASE),) +ifneq ($(APPLICATIONS),) + +### Default Xenomai installation path +XENO ?= /usr/xenomai + +XENOCONFIG=$(shell PATH=$(XENO):$(XENO)/bin:$(PATH) which xeno-config 2>/dev/null) + +### Sanity check +ifeq ($(XENOCONFIG),) +all:: + @echo ">>> Invoke make like this: \"make XENO=/path/to/xeno-config\" <<<" + @echo +endif + + +CC=$(shell $(XENOCONFIG) --cc) + +CFLAGS=$(shell $(XENOCONFIG) --xeno-cflags) $(MY_CFLAGS) + +LDFLAGS=$(shell $(XENOCONFIG) --xeno-ldflags) $(MY_LDFLAGS) -lnative + +# This includes the library path of given Xenomai into the binary to make live +# easier for beginners if Xenomai's libs are not in any default search path. +LDFLAGS+=-Xlinker -rpath -Xlinker $(shell $(XENOCONFIG) --libdir) + +LDFLAGS+= -lrtdk + +all:: $(APPLICATIONS) + +clean:: + $(RM) $(APPLICATIONS) *.o + +endif +endif + + + +###### SPECIAL TARGET RULES ###### +rtprint: rtprint.c + $(CC) $(CFLAGS) $? $(LDFLAGS) -lrtdk -o $@ + + + +###### KERNEL MODULE BUILD (no change required normally) ###### +ifneq ($(MODULES),) + +### Default to sources of currently running kernel +KSRC ?= /lib/modules/$(shell uname -r)/build + +OBJS := ${patsubst %, %.o, $(MODULES)} +CLEANMOD := ${patsubst %, .%*, $(MODULES)} +PWD := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) + +### Kernel 2.6 +ifeq ($(findstring 2.6,$(KSRC)),2.6) + +obj-m := $(OBJS) +EXTRA_CFLAGS := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/posix $(ADD_CFLAGS) + +all:: + $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules + +### Kernel 2.4 +else + +ARCH ?= $(shell uname -i) +INCLUDE := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/compat -I$(KSRC)/include/xenomai/posix +CFLAGS += $(shell $(MAKE) -s -C $(KSRC) CC=$(CC) ARCH=$(ARCH) SUBDIRS=$(PWD) modules) $(INCLUDE) + +all:: $(OBJS) + +endif + +## Target for capturing 2.4 module CFLAGS +modules: + @echo "$(CFLAGS)" + +clean:: + $(RM) $(CLEANMOD) *.o *.ko *.mod.c Module*.symvers + $(RM) -R .tmp* + +endif \ No newline at end of file diff --git a/natanael/ex07/ex07a.c b/natanael/ex07/ex07a.c new file mode 100644 index 0000000..c2e0d60 --- /dev/null +++ b/natanael/ex07/ex07a.c @@ -0,0 +1,99 @@ +/* ex07a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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) +{ + 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); + + // 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_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(); +} \ No newline at end of file diff --git a/natanael/ex07/ex07b.c b/natanael/ex07/ex07b.c new file mode 100644 index 0000000..dad458f --- /dev/null +++ b/natanael/ex07/ex07b.c @@ -0,0 +1,104 @@ +/* ex07a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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) +{ + RTIME starttime, runtime; + int num=*(int *)arg; + RT_TASK *curtask; + RT_TASK_INFO curtaskinfo; + + curtask=rt_task_self(); + + rt_task_set_mode(0,T_RRB ,NULL); + rt_task_slice(curtask,EXECTIME/SPINTIME); + + 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_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(); +} \ No newline at end of file diff --git a/natanael/ex07/ex07c.c b/natanael/ex07/ex07c.c new file mode 100644 index 0000000..d2bbf7e --- /dev/null +++ b/natanael/ex07/ex07c.c @@ -0,0 +1,107 @@ +/* ex07a.c */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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) +{ + RTIME starttime, runtime; + int num=*(int *)arg; + RT_TASK *curtask; + RT_TASK_INFO curtaskinfo; + + curtask=rt_task_self(); + + rt_task_set_mode(0,T_RRB ,NULL); + rt_task_slice(curtask,EXECTIME/SPINTIME); + + 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_start(&demo_task[i], &demo, &i); + } + // Set the latest task priority higher + rt_task_set_priority(&demo_task[3],80); + + 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(); +} \ No newline at end of file