three tier message passing and pulses

Hi,

I am trying to use pulses and MsgSend/Msg Receive calls in a three tier
architecture.

The architecture is as follows:


COMPASS (listen data on serial port) {Server} (tier 1)
|
|
Process data ( call it proccessor program) (tier 2)

|
|
Use the process data to control (tier 3)
(Controller)

All the above three are three differrent programs. The way the architecture
is build is that compass sends a MsgDeliverEvevnt whenever it gets data, In
the sense, the process data program attaches a pulse and sends the pulse to
compass which triggers the pulse. Now compass sends a MsgSend to send the
message. The same happens in tier 2 and teir 3 also. The “process data”
process sends a MsgDeliverEvent whenever it has processed the data to the
controller exactly the same.

Now my problem is if I run tier 1 and tier 2 then everything runs fine also
if i run tier 2 and tier 3 then everything runs fine but if try to run all
the three processes then tier 3 process just hangs or sometimes gets data
at a very low rate ( say 0nce in 10 seconds) while it is suppossed to get
data every second.


Any suggesstions?


I have attached the code snippets at the bottom…

Thanks
Srikanth


Compass.c… (tier 1)

while(1) {
event.sigev_notify = SIGEV_UNBLOCK;
TimerTimeout(CLOCK_REALTIME, _NTO_TIMEOUT_SEND
|_NTO_TIMEOUT_RECEIVE,&event,NULL,NULL);
pid = MsgReceive(attacher->chid, &msg, sizeof(compass_msg_t),NULL);

if(pid != -1) {
if (msg.hdr.type == _COMPASS_MSG) {
switch(msg.hdr.subtype) {
case _COMPASS_MSG_MOTION_GIVE_PROXY :
motion_event = msg.motion_give_proxy.event;
motion_rcvid =pid;
MsgReply(pid,EOK, &reply, sizeof(reply));
break;
case _COMPASS_MSG_MOTION_GET_DATA :
MsgReply(pid, EOK ,&motion_reply,
sizeof(compass_reply_motion_get_data_t));
break;
default:
MsgReply(pid, EFAULT, &reply, sizeof(reply));
break;
}
}
else {
printf("%s: Unknown message type %d\n", progname, msg.hdr.type);
//exit(EXIT_FAILURE);
continue;
}
}
if( motion_rcvid != -1 ) {
motion_reply.motion_get_data.roll = 1.2;
motion_reply.motion_get_data.pitch = 1.3;
motion_reply.motion_get_data.heading = 1.4;

if( ( MsgDeliverEvent(motion_rcvid, &motion_event)) ==-1){
perror(“COMPASS:delivery error”);
exit(-1);
}
}

}


Processdata.c(tier 2)
called motion

while(1) {
pid = MsgReceive(motion_chid, &msg, sizeof(msg), NULL);
if(pid != -1) {
if( pid == 0 ) { // Pulse received
switch( msg.hdr.code) {
case MOTION_PULSE_COMPASS_CODE:
getCompassData(compass_pid, &compass_reply);
break;
default:
MsgReply(pid, EFAULT, &reply, sizeof(reply));
printf(“motion: unknown pulse code received\n”);
break;
}
}
else { // User defined motion message received
printf(“motion: t%d st%d\n”,msg.hdr.type,msg.hdr.subtype);
printf(“motion: pid = %d\n”,pid);

if(msg.hdr.type == _MOTION_MSG) {
switch(msg.hdr.subtype) {
case _MOTION_MSG_ROLL_CTL_GIVE_PROXY:
printf(“motion: from roll_ctl\n”);
roll_ctl_proxy =
(msg.roll_ctl_give_proxy.event);
roll_ctl_proxy_id = pid;
MsgReply(pid, EOK, &reply,
sizeof(motion_msg_roll_ctl_give_proxy_t));
break;
case _MOTION_MSG_ROLL_CTL_GET_DATA :
printf(“1\n”);
reply.roll_ctl_get_data.imu_roll_angle = 30;
reply.roll_ctl_get_data.kf_roll_angle = 20;
MsgReply(pid,EOK, &reply,
sizeof(motion_reply_roll_ctl_get_data_t));
printf(“2\n”);
break;
default:
MsgReply(pid, EFAULT, &reply, sizeof(reply));
break;
}
}
else {
printf("%s: Unknown message type%d\n", progname,
msg.hdr.type);
}
}
}
else {

perror(“motion recieved bad pid”);
continue;
}

if( roll_ctl_proxy_id!=-1 ){
if ( (MsgDeliverEvent(roll_ctl_proxy_id, &roll_ctl_proxy)) ==
-1){
perror(“motion to roll_ctl delivery error”);
exit(-1);
}
}
}


Controller.c … (tier 3)

while(1) {
pid = MsgReceive( roll_ctl_chid, &msg, sizeof(msg), NULL);

if( pid != -1 ) {
if( pid == 0 ) { // Pulse received
switch( msg.hdr.code ) {
case ROLL_CTL_PULSE_MOTION_CODE :
printf(“rollc:m\n”);
getMotionData(motion_pid, progname, &imu_roll_angle,
&kf_roll_angle);
printf("%f,%f\n", imu_roll_angle,kf_roll_angle);
break;
default:
printf(“roll_ctl: unknown pulse code received\n”);
break;
}
}
}
}

Srikanth Saripalli <srik@usc.edu> wrote:

I am trying to use pulses and MsgSend/Msg Receive calls in a three tier
architecture.



All the above three are three differrent programs. The way the architecture
is build is that compass sends a MsgDeliverEvevnt whenever it gets data, In
the sense, the process data program attaches a pulse and sends the pulse to
compass which triggers the pulse. Now compass sends a MsgSend to send the
message. The same happens in tier 2 and teir 3 also. The “process data”
process sends a MsgDeliverEvent whenever it has processed the data to the
controller exactly the same.

This sounds overly complex.

It would be much simpler, and cleaner if you just made the Process (tier 2)
a resmgr and sent data to it.

In other words, tier 1 does a MsgSend(); to tier 2 when it has data, the
message would include the data.

tier 3 would do a MsgSend() to tier 2 to request data and block until it
was ready.

the syncronous nature of QNX IPC is benficial to most situations, you should
only use pulses and MsgDeliverEvent when you have a specific need that the
syncronous IPC can not provide. That does not seem to be the case here.
Careful use of threads can ensure that tier 1 is never prevented from getting
it’s data from the serial port while waiting for tier 2 to respond.

Cheers,
Camz.