/*****************************************/ /* Sistemas de Tempo-Real, 2003/2004 */ /* Paulo Pedreiras, Oct.2003 */ /* */ /* Demonstracao do uso do Shark */ /* */ /* AULA 3 - aula3a.c */ /* */ /* Application file */ /*****************************************/ /***************************/ /* Periodic task test */ /***************************/ #include #include #include #define T0_Load 200000 #define T1_Load 500000 #define T2_Load 500000 #define T3_Load 1000000 /* Some global task attributes and vars */ #define TASK_WCET 1000 TIME wcrt[4]; unsigned short pp_addr=0x378; unsigned pp_val=0x00; /* Utility functions */ void set_pbit(unsigned char bit_id) { unsigned char bit_pos=0x01; pp_val |= bit_pos<wcrt[0]) wcrt[0]=t2-t1; /* Instance complete */ task_endcycle(); } } TASK utask1(void) { unsigned char app_id; unsigned char inst_c=0; /* constant assignment of id */ app_id=1; /* initialization within task0 */ wcrt[app_id]=0; /* wait for next instance for regular execution */ task_endcycle(); /* Task body */ while (1) { /* Toggle paralel port data bit */ inst_c++; if(inst_c%2 == 0) reset_pbit(app_id); else set_pbit(app_id); /* switch on character on right position */ putc_xy(10+app_id*5,10,50,'x'); /* wait on loop, simulating load */ TIME t1; t1=sys_gettime(NULL); while(sys_gettime(NULL) < t1+T1_Load); /* measure the worst-case response time */ TIME t2; t2=sys_gettime(NULL); if((t2-t1)>wcrt[1]) wcrt[1]=t2-t1; /* switch on character on right position */ putc_xy(10+app_id*5,10,0,' '); /* Instance complete */ task_endcycle(); } } TASK utask2(void) { unsigned char app_id; unsigned char inst_c=0; /* constant assignment of id */ app_id=2; /* initialization within task0 */ wcrt[app_id]=0; /* wait for next instance for regular execution */ task_endcycle(); /* Task body */ while (1) { /* Toggle paralel port data bit */ inst_c++; if(inst_c%2 == 0) reset_pbit(app_id); else set_pbit(app_id); /* switch on character on right position */ putc_xy(10+app_id*5,10,50,'x'); /* wait on loop, simulating load */ TIME t1; t1=sys_gettime(NULL); while(sys_gettime(NULL) < t1+T2_Load); /* measure the worst-case response time */ TIME t2; t2=sys_gettime(NULL); if((t2-t1)>wcrt[2]) wcrt[2]=t2-t1; /* switch on character on right position */ putc_xy(10+app_id*5,10,0,' '); /* Instance complete */ task_endcycle(); } } TASK utask3(void) { unsigned char app_id; unsigned char inst_c=0; /* constant assignment of id */ app_id=3; /* initialization within task0 */ wcrt[app_id]=0; /* wait for next instance for regular execution */ task_endcycle(); /* Task body */ while (1) { /* Toggle paralel port data bit */ inst_c++; if(inst_c%2 == 0) reset_pbit(app_id); else set_pbit(app_id); /* switch on character on right position */ putc_xy(10+app_id*5,10,50,'x'); /* wait on loop, simulating load */ TIME t1; t1=sys_gettime(NULL); while(sys_gettime(NULL) < t1+T3_Load); /* measure the worst-case response time */ TIME t2; t2=sys_gettime(NULL); if((t2-t1)>wcrt[3]) wcrt[3]=t2-t1; /* switch on character on right position */ putc_xy(10+app_id*5,10,0,' '); /* Instance complete */ task_endcycle(); } } /****************************************************************/ /* This function is called when Alt-X is pressed. It simply shutdown the system using sys_end. Note that the byebye() function is called only if we exit from the system using sys_end()!!!! */ void my_end(KEY_EVT* e) { sys_end(); } /******************************************************************/ /* This function is called when the system exit correctly after Alt-X. It exits from the graphic mode and then it prints a small greeting. Note that: - The function calls grx_exit, so it must be registered using RUNLEVEL_BEFORE_EXIT (RUNLEVEL_AFTER_EXIT does not work because at that point the kernel is already returned in real mode!!!) - When an exception is raised, the exception handler is called. Since the exception handler already exits from the graphic mode, this funcion has not to be called. For this reason: . we registered byebye using the flag NO_AT_ABORT . the exception handler exits using sys_abort; in that way byebye is NOT called */ void byebye(void *arg) { kern_printf("Bye Bye!\n"); } /****************************** MAIN ******************************/ int main(int argc, char **argv) { KEY_EVT emerg; HARD_TASK_MODEL mh; PID pid[4]; unsigned char jet_info[80], wcrt_info[80]; TIME max_t[4]; /* Set the closing function */ sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT); keyb_set_map(engMap); /* set the keyboard handler to exit correctly */ emerg.ascii = 'x'; emerg.scan = KEY_X; emerg.flag = ALTL_BIT; keyb_hook(emerg,my_end); emerg.ascii = 'x'; emerg.scan = KEY_X; emerg.flag = ALTR_BIT; keyb_hook(emerg,my_end); /* a small banner */ cprintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); cprintf("aula3-1 Demo\n"); cprintf("Press Alt-X to exit\n"); /* Task creation */ /* Task's common attributes*/ hard_task_default_model(mh); hard_task_def_ctrl_jet (mh); hard_task_def_wcet (mh, TASK_WCET); /* Task's specific attributes */ hard_task_def_arg (mh, NULL); hard_task_def_mit (mh, 1000000); hard_task_def_group (mh, 2); pid[0] = task_create("utask0", utask0, &mh, NULL); if (pid[0] == NIL) { perror("Could not create task "); sys_abort(1); } /* Task's specific attributes */ hard_task_def_arg (mh, NULL); hard_task_def_mit (mh, 2000000); hard_task_def_group (mh, 2); pid[1] = task_create("utask1", utask1, &mh, NULL); if (pid[1] == NIL) { perror("Could not create task "); sys_abort(1); } /* Task's specific attributes */ hard_task_def_arg (mh, NULL); hard_task_def_mit (mh, 3000000); hard_task_def_group (mh, 2); pid[2] = task_create("utask2", utask2, &mh, NULL); if (pid[2] == NIL) { perror("Could not create task "); sys_abort(1); } /* Task's specific attributes */ hard_task_def_arg (mh, NULL); hard_task_def_mit (mh, 4000000); hard_task_def_group (mh, 2); pid[3] = task_create("utask3", utask3, &mh, NULL); if (pid[3] == NIL) { perror("Could not create task "); sys_abort(1); } group_activate(2); while(1) { /* get the kernel measure of the job execution times (JET) */ jet_getstat(pid[0],NULL,&max_t[0],NULL,NULL); jet_getstat(pid[1],NULL,&max_t[1],NULL,NULL); jet_getstat(pid[2],NULL,&max_t[2],NULL,NULL); jet_getstat(pid[3],NULL,&max_t[3],NULL,NULL); sprintf(jet_info,"jet= %lu %lu %lu %lu",max_t[0],max_t[1],max_t[2],max_t[3]); puts_xy(5,1,WHITE,jet_info); /* print the worst-case response time */ sprintf(wcrt_info,"wcrt= %lu %lu %lu %lu",wcrt[0],wcrt[1],wcrt[2],wcrt[3]); puts_xy(5,2,WHITE,wcrt_info); } /* this main task does not end.The demo will finish if a Alt-X key is pressed. */ }