Events.
Correo Fernando-ruiz (E-mail)
correo at fernando-ruiz.com
Wed Jan 10 21:51:27 UTC 2001
Hi Joel and rtems-users.
I have a question about events.
I have implemented an event dispatcher and
I want to known if I am in the right way.
1. Environment.
Two cpu's need to comunicate and the first send a command towards the
second.
The second take a while and sends the reply.
The caller task need to wait the reply until it arrives.
The reply is catched by another task (dispatcher & supervisor).
2. Event handler.
Every task can manage a maximum of 32 events. (RTEMS LIMITS)
The availiable events are known by every task.
To avoid the duplicates in lieu of a constant event
the task call to lock for a new free event availiable
and it is stored in a var.
A events mask for every task is placed in a handlers table.
/*--------------------------------------------*/
typedef struct {
rtems_id id; /* TASK ID */
rtems_event_set event;
} THndEvent;
/*--------------------------------------------*/
static THndEvent tbl_events[MAX_EVENTS]; /* The handlers */
static THndEvent msk_events[TSK_EVENTS]; /* The task mask */
static int last_event; /* this works like a PID inc
every time */
static int max_msk_event;
/*--------------------------------------------*/
rtems_status_code lock_event(rtems_event_set * event) {
rtems_status_code sc;
rtems_event_set * mask,
ignored;
sc=get_msk_events((rtems_id)0,&mask);
if (sc!=RTEMS_SUCCESSFUL) return sc;
*event=RTEMS_EVENT_0;
while (*event&*mask) {
*event<<=1;
if (!*event) return RTEMS_TOO_MANY;
};
rtems_event_receive(*event,RTEMS_NO_WAIT,0,&ignored); /* clear it */
*mask|=*event;
return RTEMS_SUCCESSFUL;
}
With this a new procedure
rtems_status_code set_event(int *handle,rtems_event_set * event) ;
gives a handler and the new event locked.
The first task places this handler in the comand sended towards the
second cpu.
When the reply arrives the dispatcher task calls to
/*--------------------------------------------*/
void free_event(int handle) {
rtems_status_code sc;
if (handle<0) return;
if (handle>=MAX_EVENTS) return;
if (tbl_events[handle].event) {
sc=rtems_event_send(tbl_events[handle].id,tbl_events[handle].event);
if (sc!=RTEMS_SUCCESSFUL) rtems_error(sc,"send event to
%08X",tbl_events[handle].id);
unlock_event(tbl_events[handle].id,tbl_events[handle].event);
tbl_events[handle].id =0;
tbl_events[handle].event=0;
};
}
/*--------------------------------------------*/
freeing the handle and sending the event at the first task.
How the first task waits for this event the process is completed.
====================================================================
Question:
Is this way the right way to resolve this kind of problems?
Where is the place in RTEMS to put the task mask used events?
With this place I can eliminate this
rtems_status_code get_msk_events(rtems_id task_id,rtems_event_set **
msk);
====================================================================
The module includes also:
void send_event(int handle) ; to wake_up asyncronously.
void clear_events(rtems_event_set event); unlock the event and
the handler for current task
rtems_interval msecs2ticks(int msecs) ;
rtems_status_code wait_event(rtems_event_set ev,rtems_interval msecs);
With this last procedure I can use it like rtems_monotonic waiting a
locked event known only by the current task.
/*----------------------------------------------------*/
/*- My shell command to spy the module -*/
/*----------------------------------------------------*/
#include <stdio.h>
#include <shell.h>
int main_events(int argc,char * argv[]) {
int n,i,num;
rtems_event_set ev;
printf("MSK EVTS 1 2 3 \n");
printf("TASK ID 01234567890123456789012345678901\n");
printf("-------- --------------------------------\n");
for (n=0;n<max_msk_event;n++) {
printf("%08X ",msk_events[n].id);
ev=RTEMS_EVENT_0;
for (i=0;i<32;i++) {
putchar(msk_events[n].event&ev?'X':' ');
ev<<=1;
};
putchar('\n');
};
printf("-------- --------------------------------\n");
printf("%d tasks\n",max_msk_event);
printf("-------- --------------------------------\n");
printf("TBL EVTS 1 2 3 \n");
printf("TASK ID 01234567890123456789012345678901 HND\n");
printf("-------- -------------------------------- ---\n");
num=0;
for (n=0;n<MAX_EVENTS;n++) {
if (tbl_events[n].id) {
num++;
printf("%08X ",tbl_events[n].id);
ev=RTEMS_EVENT_0;
for (i=0;i<32;i++) {
putchar(tbl_events[n].event&ev?'X':' ');
ev<<=1;
};
printf(" %3d\n",n);
};
};
printf("-------- --------------------------------\n");
printf("%d events activated\n",num);
printf("-------- --------------------------------\n");
return 0;
}
Thanks for your comments.
Fernando RUIZ CASAS
correo at fernando-ruiz.com
fernando.ruiz at ctv.es
More information about the users
mailing list