#include #include #include #include #include #define RVK 40 /* Thread Data-Structure for 3 threads. */ cyg_thread thread_s[3]; /* Stack Space for 3 threads */ char stack[3][CYGNUM_HAL_STACK_SIZE_TYPICAL]; /* Handles for threads. Also thread entry functions */ cyg_handle_t modeA_thread1, modeA_thread2, modeA_thread3; cyg_thread_entry_t thread1A_entry, thread2A_entry, thread3A_entry; /* Forward-Definition of functions */ void thread1A_alarm_func(cyg_handle_t, cyg_addrword_t); void thread2A_alarm_func(cyg_handle_t, cyg_addrword_t); void thread3A_alarm_func(cyg_handle_t, cyg_addrword_t); /* Alarms and Counters related Data Structures */ cyg_handle_t thread_counter[3], system_clockH[3], thread_alarmH[3]; cyg_alarm thread_alarm[3]; void safe_printf(char *fmt, ...) { CYG_INTERRUPT_STATE old_intr; va_list ap; HAL_DISABLE_INTERRUPTS(old_intr); va_start(ap, fmt); diag_vprintf(fmt, ap); HAL_RESTORE_INTERRUPTS(old_intr); } int loops_per_tick; void init_loops_per_tick(void) { int old_ticks, new_ticks; int j; if (loops_per_tick != 0) return; loops_per_tick = 0; old_ticks = (int) cyg_current_time(); // Wait for time to roll while ((new_ticks = (int)cyg_current_time()) == old_ticks) ; // Now, see how many loops can happen before the next tick old_ticks = new_ticks; // Wait for time to roll while ((new_ticks = (int)cyg_current_time()) == old_ticks) { for (j = 0; j < 10000; j++) ; loops_per_tick++; } safe_printf("%d loops per tick\n", loops_per_tick); } /* Kernel Flags */ cyg_flag_t flag[3]; /* Starting the application. */ void cyg_user_start(void) { /* Create 3 threads 1A, 2A, 3A . */ cyg_thread_create(3,thread1A_entry,(cyg_addrword_t) 0,"Mode A thread 1", (void *) stack[0],CYGNUM_HAL_STACK_SIZE_TYPICAL,&modeA_thread1,&thread_s[0]); cyg_thread_create(4,thread2A_entry,(cyg_addrword_t) 0,"Mode A thread 2", (void *) stack[1],CYGNUM_HAL_STACK_SIZE_TYPICAL,&modeA_thread2,&thread_s[1]); cyg_thread_create(5,thread3A_entry,(cyg_addrword_t) 0,"Mode A thread 3", (void *) stack[2],CYGNUM_HAL_STACK_SIZE_TYPICAL,&modeA_thread3,&thread_s[2]); /* Intialize the Kernel Flags */ cyg_flag_init(&flag[0]); cyg_flag_init(&flag[1]); cyg_flag_init(&flag[2]); /* Initialize the alarms Period of each thread is (200/240/120) ticks of real-time clock. */ cyg_thread_resume(modeA_thread1); cyg_thread_resume(modeA_thread2); cyg_thread_resume(modeA_thread3); } void thread1A_entry(cyg_addrword_t data) { int i,j; init_loops_per_tick(); system_clockH[0] = cyg_real_time_clock(); cyg_clock_to_counter(system_clockH[0], &thread_counter[0]); cyg_alarm_create(thread_counter[0],thread1A_alarm_func, (cyg_addrword_t) 0, &thread_alarmH[0], &thread_alarm[0]); cyg_alarm_initialize(thread_alarmH[0],cyg_current_time()+200,200); for(;;) { /* The following code executes for 40 ticks (approx) . This was determined experimentally. */ safe_printf("Thread 1A :: Time Before Processing :: is %u\n", (unsigned int) cyg_current_time()); for(i=0;i<40*loops_per_tick;i++) { for(j=0;j<10000;j++) { ; } } safe_printf("Thread 1A :: Time After Processing :: %u\n", (unsigned int) cyg_current_time()); /* Wait for Kernel Flag to Signal. */ cyg_flag_wait(&flag[0],0x1, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR); } } void thread2A_entry(cyg_addrword_t data) { int i,j; init_loops_per_tick(); system_clockH[1] = cyg_real_time_clock(); cyg_clock_to_counter(system_clockH[1], &thread_counter[1]); cyg_alarm_create(thread_counter[1],thread2A_alarm_func, (cyg_addrword_t) 0, &thread_alarmH[1], &thread_alarm[1]); cyg_alarm_initialize(thread_alarmH[1],cyg_current_time()+240,240); for(;;) { /* The following code executes for 80 ticks (approx) . This was determined experimentally. */ safe_printf("Thread 2A :: Time Before Processing is %u \n", (unsigned int) cyg_current_time()); for(i=0;i<80*loops_per_tick;i++) { for(j=0;j<10000;j++) { ; } } safe_printf("Thread 2A :: Time After Processing is %u \n", (unsigned int) cyg_current_time()); /* Wait for Kernel Flag to Signal. */ cyg_flag_wait(&flag[1],0x1, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR); } } void thread3A_entry(cyg_addrword_t data) { int i,j; init_loops_per_tick(); system_clockH[2] = cyg_real_time_clock(); cyg_clock_to_counter(system_clockH[2], &thread_counter[2]); cyg_alarm_create(thread_counter[2],thread3A_alarm_func, (cyg_addrword_t) 0, &thread_alarmH[2], &thread_alarm[2]); cyg_alarm_initialize(thread_alarmH[2],cyg_current_time()+160,160); for(;;) { /* The following code executes for 40 ticks (approx) . This was determined experimentally. */ safe_printf("Thread 3A :: Time Before Processing is %u \n", (unsigned int) cyg_current_time()); for(i=0;i<40*loops_per_tick;i++) { for(j=0;j<10000;j++) { ; } } safe_printf("Thread 3A :: Time After Processing is %u \n", (unsigned int) cyg_current_time()); /* Wait for Kernel Flag to Signal. */ cyg_flag_wait(&flag[2],0x1, CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR); } } /* Alarm-Handlers that suspend the various threads. */ void thread1A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data) { safe_printf("Thread 1 finished at :: %u \n", (unsigned int) cyg_current_time()); cyg_flag_setbits(&flag[0], 0x1); } void thread2A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data) { safe_printf("Thread 2 finished at :: %u \n", (unsigned int) cyg_current_time()); cyg_flag_setbits(&flag[1], 0x1); } void thread3A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data) { safe_printf("Thread 3 finished at :: %u \n", (unsigned int) cyg_current_time()); cyg_flag_setbits(&flag[2], 0x1); }