Blame |
Last modification |
View Log
| RSS feed
#include "hlpdemo.h"
#include <drivers/shark_keyb26.h>
#include "snapshot.h"
//#define ESC 27
/*
#define DEBUG
*/
/* tipologia di task e mutex */
HARD_TASK_MODEL m
;
/* scala temporale del sistema in us */
#define TIMESCALE (100 * 1000)
/* buffer che contiene la configurazione letto in nrt mode */
extern char myfilebuf
[1000];
extern int read_conf
(char *, unsigned int);
extern void print_taskconf
(taskconf_list_t
*);
void trace_info_hlp
(void);
/* tempo dell'avvio */
TIME start
;
/* struttura dati contenente la configurazione */
taskconf_list_t
*taskconf
= NULL
;
/* lista dei mutex del sistema */
mutex_list_t
*mutexes
= NULL
;
#define YMENU 10 /* menu level */
#define XMIN 50
#define XMAX 600
#define YMIN 100
#define YMAX 450
#define YFLOOR(index) YMIN + (50 * (index + 1))
#define COLWHITE rgb16(255,255,255)
#define COLLOAD rgb16(180,180,180)
/*--------------------------------------------------------------*/
/* posizione lungo l'asse x dopo t sec. */
int xpost
(unsigned int t
)
{
int ret
;
ret
= XMIN
+ 10 + (((sys_gettime
(NULL
) - start
) / TIMESCALE
) + t
);
if (ret
> XMAX
)
ret
= XMAX
;
if (ret
< XMIN
)
ret
= XMIN
;
return ret
;
}
/* posizione lungo l'asse x al tempo t corrente */
int xpos
(void)
{
return xpost
(0);
}
typedef struct color_stack
{
int color
;
struct color_stack
*next
;
} color_stack_t
;
void color_stack_push
(int color
, color_stack_t
**head
)
{
color_stack_t
*new
;
new
= (color_stack_t
*)kern_alloc
(sizeof(color_stack_t
));
new
->color
= color
;
new
->next
= *head
;
*head
= new
;
}
int color_stack_pop
(color_stack_t
**head
)
{
int ret
= COLLOAD
;
color_stack_t
*tmp
= *head
;
if (*head
!= NULL
)
{
ret
= (*head
)->color
;
*head
= (*head
)->next
;
kern_free
(tmp
, (sizeof(color_stack_t
)));
}
return ret
;
}
void load
(int time, int i
, int color
, char *name
)
{
int j
;
TIME last
;
char buf
[50];
for (j
= 0; j
< time; j
++)
{
last
= sys_gettime
(NULL
);
grx_line
(xpos
(), YFLOOR
(i
), xpos
(), YFLOOR
(i
) - 10, color
);
sprintf(buf
,
"Time: %.4d, task active: %.5s(PID=%.2d, Shadow=%.2d)",
(int)((sys_gettime
(NULL
) - start
) / TIMESCALE
) + 2,
name
,
exec
,
exec_shadow
);
grx_text
(buf
, 100,100,COLWHITE
,0);
while (sys_gettime
(NULL
) - last
+ (TIMESCALE
/100) < TIMESCALE
);
}
}
TASK Ji
(void *arg
)
{
taskconf_list_t
*cur
= (taskconf_list_t
*)arg
;
action_list_t
*act
;
color_stack_t
*colorstack
;
color_stack_push
(COLLOAD
, &colorstack
);
while (1)
{
act
= cur
->actionlist
;
while (act
)
{
switch (act
->type
)
{
case LOAD
:
load
(act
->time, cur
->i
, colorstack
->color
, cur
->name
);
if (xpos
() == XMAX
)
{
task_kill
(cur
->pid
);
return 0;
}
break;
case LOCK
: /* task lock */
color_stack_push
(act
->mutex
->color
, &colorstack
);
grx_text
(act
->mutex
->name
, xpos
() - 2, YFLOOR
(cur
->i
) + 10, COLWHITE
, 0);
mutex_lock
(&act
->mutex
->m
);
trace_info_hlp
();
break;
case UNLOCK
: /* task unlock */
color_stack_pop
(&colorstack
);
mutex_unlock
(&act
->mutex
->m
);
trace_info_hlp
();
break;
}
act
= act
->next
;
}
task_endcycle
();
}
return 0;
}
void draw_scenario
(void)
{
/* The scenario */
grx_rect
(XMIN
-1, YMIN
-1, XMAX
+1, YMAX
+1, COLWHITE
);
grx_text
("Simulation of HLP tasks", XMIN
, YMENU
+10, COLWHITE
, 0);
grx_text
("SPACE Start demo" , XMIN
, YMENU
+20, COLWHITE
, 0);
grx_text
("ESC exit to DOS" , XMIN
, YMENU
+30, COLWHITE
, 0);
}
void trace_info_hlp
()
{
HLP_mutex_resource_des
*m
;
RLEVEL l
;
HLP_mutex_t
*mutscan
;
HLP_tasklist_t
*taskscan
;
int i
= 0;
char buf
[60];
if (mutexes
)
{
l
= mutexes
->m.
mutexlevel;
m
= (HLP_mutex_resource_des
*)(resource_table
[l
]);
for (mutscan
= m
->mutexlist
; mutscan
; mutscan
= mutscan
->next
)
{
if (mutscan
->owner
!= NIL
)
sprintf(buf
, "mutex: %p owner=%2d, used by", mutscan
, mutscan
->owner
);
else
sprintf(buf
, "mutex: %p no owner, used by", mutscan
);
grx_text
(buf
, 50, 320, COLWHITE
, 0);
for (i
= 1, taskscan
= mutscan
->tasklist
; taskscan
; taskscan
= taskscan
->next
, i
++)
{
sprintf(buf
, "task: %p, pid=%d, preempt=%ld",
taskscan
,
taskscan
->pid
,
taskscan
->preempt
);
grx_text
(buf
, 100, 320+i
*8, COLWHITE
, 0);
}
}
grx_text
("All tasks:", 100, 320 + i
++ * 8, COLWHITE
, 0);
if (taskconf
)
for (taskscan
= m
->tasklist
; taskscan
; taskscan
= taskscan
->next
, i
++)
{
sprintf(buf
,
"task: %p, pid=%d, preempt=%ld",
taskscan
,
taskscan
->pid
,
taskscan
->preempt
);
grx_text
(buf
, 100, 320+i
*8, COLWHITE
, 0);
}
}
else
{
grx_text
("No mutexes", 200, 200, COLWHITE
, 0);
}
}
/* get preemption level inverse proportional to period and starting by 1 */
int get_preemption_level
(taskconf_list_t
*task
)
{
taskconf_list_t
*scan
;
int ret
= 1;
for (scan
= taskconf
; scan
; scan
= scan
->next
)
if (scan
!= task
&& scan
->period
< task
->period
)
ret
++;
return ret
;
}
/****************************** MAIN ******************************/
int main
(int argc
, char **argv
)
{
char c
; /* character from keyboard */
int i
= 0, j
= 0, started
= 0, numtask
= 0, nummutex
= 0;
taskconf_list_t
*curtask
= NULL
;
mutex_list_t
*mutexlist
= NULL
, *curmut
= NULL
;
PID pid
= NIL
;
HLP_mutexattr_t a
;
HLP_RES_MODEL r
;
if (read_conf
(myfilebuf
, 1000) == -1)
{
sys_shutdown_message
("Error reading configuration file");
sys_end
();
}
for (curtask
= taskconf
; curtask
!= NULL
; curtask
= curtask
->next
)
numtask
++;
draw_scenario
();
curtask
= taskconf
;
for (curmut
= mutexes
; curmut
; curmut
= curmut
->next
)
{
HLP_mutexattr_default
(a
);
mutex_init
(&(curmut
->m
), &a
);
}
snapshot_freeslot
(0);
c
= keyb_getch
(BLOCK
);
i
= started
= 0;
do {
if ((c
== ' ') && !started
) {
started
= 1;
start
= sys_gettime
(NULL
);
while (curtask
) {
/* traccio gli assi temporali per ogni task */
grx_line
(XMIN
+ 10, YFLOOR
(i
), XMAX
- 10, YFLOOR
(i
), COLWHITE
);
grx_text
(curtask
->name
, XMIN
- 20, YFLOOR
(i
) - 10, COLWHITE
, 0);
/* disegna frecce di attivazione */
for (j
= 0; xpost
(j
) < XMAX
; j
+= curtask
->period
)
{
grx_line
(xpost
(j
), YFLOOR
(i
), xpost
(j
), YFLOOR
(i
) - 20, COLWHITE
);
grx_line
(xpost
(j
), YFLOOR
(i
) - 20, xpost
(j
) - 5, YFLOOR
(i
) - 15, COLWHITE
);
grx_line
(xpost
(j
), YFLOOR
(i
) - 20, xpost
(j
) + 5, YFLOOR
(i
) - 15, COLWHITE
);
}
hard_task_default_model
(m
);
hard_task_def_level
(m
,0);
hard_task_def_ctrl_jet
(m
);
hard_task_def_periodic
(m
);
hard_task_def_wcet
(m
, (curtask
->wcet
+ 2) * TIMESCALE
);
hard_task_def_mit
(m
, curtask
->period
* TIMESCALE
);
hard_task_def_arg
(m
,(void *)curtask
);
hard_task_def_group
(m
, 1);
/* registro i mutex per il pid */
nummutex
= 0;
mutexlist
= curtask
->mutexlist
;
while(mutexlist
) {
mutexlist
= mutexlist
->next
;
nummutex
++;
}
// HLP_res_default_model(r, get_preemption_level(curtask));
HLP_res_default_model
(r
, 1000 - curtask
->period
);
switch (nummutex
) {
case 0:
pid
= task_create
(curtask
->name
, Ji
, &m
, &r
);
break;
case 1:
pid
= task_createn
(curtask
->name
, Ji
, (TASK_MODEL
*)&m
, &r
,
HLP_usemutex
(&(curtask
->mutexlist
->m
)), NULL
);
break;
case 2:
pid
= task_createn
(curtask
->name
, Ji
, (TASK_MODEL
*)&m
, &r
,
HLP_usemutex
(&(curtask
->mutexlist
->m
)),
HLP_usemutex
(&(curtask
->mutexlist
->next
->m
)), NULL
);
break;
case 3:
pid
= task_createn
(curtask
->name
, Ji
, (TASK_MODEL
*)&m
, &r
,
HLP_usemutex
(&(curtask
->mutexlist
->m
)),
HLP_usemutex
(&(curtask
->mutexlist
->next
->m
)),
HLP_usemutex
(&(curtask
->mutexlist
->next
->next
->m
)), NULL
);
break;
case 4:
pid
= task_createn
(curtask
->name
, Ji
, (TASK_MODEL
*)&m
, &r
,
HLP_usemutex
(&(curtask
->mutexlist
->m
)),
HLP_usemutex
(&(curtask
->mutexlist
->next
->m
)),
HLP_usemutex
(&(curtask
->mutexlist
->next
->next
->m
)),
HLP_usemutex
(&(curtask
->mutexlist
->next
->next
->next
->m
)), NULL
);
break;
default:
sys_shutdown_message
("Too many mutexes! I am stupid!");
sys_end
();
}
if (pid
== NIL
)
{
sys_shutdown_message
("Could not create task %s", curtask
->name
);
sys_end
();
print_taskconf
(curtask
);
return 0;
}
curtask
->pid
= pid
;
curtask
->i
= i
++;
curtask
= curtask
->next
;
}
trace_info_hlp
();
start
= sys_gettime
(NULL
);
group_activate
(1);
}
c
= keyb_getch
(BLOCK
);
if (xpos
() > XMAX
)
{
group_kill
(1);
}
} while (c
!= ESC
);
snapshot_getslot
(0, 640, 480, 2);
snapshot_grab
(0);
sys_end
();
snapshot_save_ppm
(0, "snapshot.ppm");
return 0;
}
/*--------------------------------------------------------------*/