For message passing from task to task, I use the 3 available  
procedures rt_task_send(), rt_task_reply(), rt_task_receive().

The job is when one message emitted from the source to one  
destination, however the message can be catched by an other task (not  
the good correspondant). In Xenomai, when the message is NOT for a  
task, it couldn't be passed to a next task. Tasks can receive any  
message but not being able to relay it to the destination. (there's no  
such function mentionned inside the API doc).

I build an example. (cf code sample)

any help is welcome

code sample :

/*
  *
  *  Created on: 15 avr. 2010
  *      Author: hemichel
  */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <native/task.h>
#include <native/queue.h>
#include <native/intr.h>

#define STACK_SIZE 8192
#define STD_PRIO 1

RT_TASK test_task_ptr,test_task2_ptr,test_task3_ptr;
int int_count = 0;
int end = 0;

#define PEER_RATE_NS 10000000
//                     --s-ms-us-ns
RTIME task_period_ns =   1000000000llu;

void testtask(void *cookie) {
        RT_TASK_MCB mcb_send, mcb_reply;
        int flowid, i, rv;
        unsigned char datasend[16];
        unsigned char datareply[16];

        int count = 0;
        int ret;
        unsigned long overrun;
        ret = rt_task_set_periodic(NULL, TM_NOW, 
rt_timer_ns2ticks(task_period_ns));
        if (ret) {
                printf("error while set periodic, code %d\n",ret);
                return;
        }

        mcb_send.opcode = 0x03;
        datasend[0]='a';
        mcb_send.data = datasend;
        mcb_send.size = sizeof(datasend);

        mcb_reply.size = sizeof(datareply);
        mcb_reply.data = datareply;

        while(!end){
                ret = rt_task_set_mode(0, T_PRIMARY, NULL);
                if (ret) {
                        printf("error while rt_task_set_mode, code %d\n",ret);
                        return;
                }
                ret = rt_task_wait_period(&overrun);
                if (ret) {
                        printf("error while rt_task_wait_period, code 
%d\n",ret);
                        return;
                }
                count++;
                printf("message from testtask: count=%d\n", count);

                rv = 
rt_task_send(&test_task2_ptr,&mcb_send,&mcb_reply,PEER_RATE_NS);
                if (rv < 0) printf("rt_task_send error\n");
                else rt_printf("response mcb_reply=%d\n",mcb_reply.data[0]);
                fflush(NULL);
        }
}


void testtask2(void *cookie) {
        RT_TASK_MCB mcb_rcv, mcb_reply;
        int flowid, i, rv;
        unsigned char datareply[16];

        int count = 12;
        int ret;
        unsigned long overrun;
        ret = rt_task_set_periodic(NULL, TM_NOW, 
rt_timer_ns2ticks(task_period_ns));
        if (ret) {
                printf("error while set periodic, code %d\n",ret);
                return;
        }

        while(!end){
                ret = rt_task_set_mode(0, T_PRIMARY, NULL);
                if (ret) {
                        printf("error while rt_task_set_mode, code %d\n",ret);
                        return;
                }
                ret = rt_task_wait_period(&overrun);
                if (ret) {
                        printf("error while rt_task_wait_period, code 
%d\n",ret);
                        return;
                }

                mcb_rcv.data = (caddr_t)datareply;
                mcb_rcv.size = sizeof(datareply);

                flowid = rt_task_receive(&mcb_rcv,PEER_RATE_NS);
                rt_printf("task 2: flowid=%d rcv.size=%d bytes to receive buf,  
opcode=%d\n",\
                                flowid,mcb_rcv.size,mcb_rcv.opcode);
                if(flowid >= 0)
                {
                        if (mcb_rcv.opcode == 2) {
                                //this is mine
                                mcb_reply.opcode = 0x2;
                                mcb_reply.size = 1;
                                datareply[0]=count;
                                mcb_reply.data = datareply;
                                rt_task_reply(flowid, &mcb_reply);
                                rt_printf("replied from task2 to 
flowid=%d\n",flowid);
                        }
                        else {
                                rt_printf("task2 : not mined\n");
                                 //how to relay the catched msg to next ?
                        }
                }

                fflush(NULL);
        }
}


void testtask3(void *cookie) {
        RT_TASK_MCB mcb_rcv, mcb_reply;
        int flowid, i, rv;
        unsigned char datareply[16];

        int count = 13;
        int ret;
        unsigned long overrun;
        ret = rt_task_set_periodic(NULL, TM_NOW, 
rt_timer_ns2ticks(task_period_ns));
        if (ret) {
                printf("error while set periodic, code %d\n",ret);
                return;
        }

        while(!end){
                ret = rt_task_set_mode(0, T_PRIMARY, NULL);
                if (ret) {
                        printf("error while rt_task_set_mode, code %d\n",ret);
                        return;
                }
                ret = rt_task_wait_period(&overrun);
                if (ret) {
                        printf("error while rt_task_wait_period, code 
%d\n",ret);
                        return;
                }

                mcb_rcv.data = (caddr_t)datareply;
                mcb_rcv.size = sizeof(datareply);

                flowid = rt_task_receive(&mcb_rcv,PEER_RATE_NS);
                rt_printf("task 3 : flowid=%d rcv.size=%d bytes to receive buf, 
 
opcode=%d\n",\
                                flowid,mcb_rcv.size,mcb_rcv.opcode);
                if(flowid >= 0)
                {
                        if (mcb_rcv.opcode == 3) {
                                //this is mine
                                mcb_reply.opcode = 0x3;
                                mcb_reply.size = 1;
                                datareply[0]=count;
                                mcb_reply.data = datareply;
                                rt_task_reply(flowid, &mcb_reply);
                                rt_printf("replied from task3 to 
flowid=%d\n",flowid);
                        }
                        else {
                                rt_printf("task3 : not mined\n");
                                 //how to relay the catched msg to next ?
                        }

                }

                fflush(NULL);
        }
}



Jan Kiszka <[email protected]> a écrit :

> Well, you could start with mapping the existing RTAI API calls in
> xrtai-lab on local Native calls. That will already give you a
> non-distributed port.


_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help

Reply via email to