Rev 1173 |
Rev 1211 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Giacomo Guidi <giacomo@gandalf.sssup.it>
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Advanced Timer Demo
*
*/
#include "kernel/kern.h"
#include "ll/i386/cons.h"
#include "ll/i386/advtimer.h"
#include "drivers/keyb.h"
#define UPDATE_PERIOD 10000
#define UPDATE_WCET 1000
extern signed long long clk_per_msec
;
extern signed long last_delta_clk_per_msec
;
extern signed long total_delta_clk_per_msec
;
extern unsigned char use_tsc
;
extern unsigned char use_cmos
;
void program_key_end
(KEY_EVT
*k
)
{
sys_end
();
}
TASK Update
(void *arg
)
{
struct timespec actual_timer
;
long nsec
,sec
,min
,hrs
,day
;
long mean_delay
,tot_delay
,num_delay
;
long total_percent
;
signed long long start
,end
,res
;
struct timespec s_test
,startts
,endts
;
task_nopreempt
();
num_delay
= tot_delay
= mean_delay
= 0;
while (1) {
if (clk_per_msec
!= 0) {
rdtscll
(start
);
sys_gettime
(&actual_timer
);
rdtscll
(end
);
res
= end
- start
;
rdtscll
(start
);
rdtscll
(end
);
res
-= (end
- start
);
s_test.
tv_nsec = res
* 1000000 / clk_per_msec
;
} else {
sys_gettime
(&startts
);
sys_gettime
(&actual_timer
);
sys_gettime
(&endts
);
SUBTIMESPEC
(&endts
,&startts
,&s_test
);
sys_gettime
(&startts
);
sys_gettime
(&endts
);
SUBTIMESPEC
(&endts
,&startts
,&endts
);
SUBTIMESPEC
(&s_test
,&endts
,&s_test
);
}
if (tot_delay
< 1000000000) {
tot_delay
+= s_test.
tv_nsec;
num_delay
++;
mean_delay
= tot_delay
/ num_delay
;
}
nsec
= actual_timer.
tv_nsec;
sec
= actual_timer.
tv_sec;
min
= sec
/ 60;
sec
%= 60;
hrs
= min
/ 60;
min
%= 60;
day
= hrs
/ 24;
hrs
%= 24;
if (use_tsc
)
if (use_cmos
)
printf_xy
(0,4,WHITE
,"Timer Mode: TSC + CMOS");
else
printf_xy
(0,4,WHITE
,"Timer Mode: TSC");
else
printf_xy
(0,4,WHITE
,"Timer Mode: 8254");
printf_xy
(0,5,WHITE
,"Actual Clk/msec: %12ld",(long)clk_per_msec
);
printf_xy
(0,6,WHITE
,"Actual Timer: %2ld d %2ld h %2ld m %2ld s %12ld ns",day
,hrs
,min
,sec
,(long)nsec
);
printf_xy
(0,8,WHITE
,"CMOS Adjustement setting");
printf_xy
(0,9,WHITE
,"CMOS last delta Clk/msec: %12ld",(long)last_delta_clk_per_msec
);
if (total_delta_clk_per_msec
!= 0)
total_percent
= clk_per_msec
/ abs(total_delta_clk_per_msec
);
else
total_percent
= 0;
printf_xy
(0,10,WHITE
,"CMOS total delta Clk/msec: %12ld (1/%ld)",(long)total_delta_clk_per_msec
,total_percent
);
printf_xy
(0,12,WHITE
,"Timer Access Delay: %12ld ns",mean_delay
);
task_endcycle
();
}
sys_end
();
}
void set_screen
()
{
printf_xy
(20,0,WHITE
," Advanced Timer Demo ");
printf_xy
(20,1,WHITE
,"Giacomo Guidi <giacomo@gandalf.sssup.it>");
printf_xy
(20,2,WHITE
," Press Alt + c to exit ");
}
int main
(int argc
, char **argv
)
{
HARD_TASK_MODEL mp
; //Show current setting
PID update
;
KEY_EVT k
;
k.
flag = ALTL_BIT
;
k.
scan = KEY_C
;
k.
ascii = 'c';
keyb_hook
(k
,program_key_end
);
set_screen
();
hard_task_default_model
(mp
);
hard_task_def_ctrl_jet
(mp
);
hard_task_def_group
(mp
, 1);
hard_task_def_wcet
(mp
,UPDATE_WCET
);
hard_task_def_mit
(mp
,UPDATE_PERIOD
);
hard_task_def_usemath
(mp
);
update
= task_create
("Update", Update
, &mp
, NULL
);
if (update
!= NIL
) task_activate
(update
);
return 0;
}