Hello
I am new in Xenomai and I can't figure out from examples what is the best way 
to send some data from kernel space rt_task to user space rt_task. I have 
created both tasks. In the kernel space task I've created rt_queue and I would 
like bind to it from the user space kernel task but all I've got is -EPERM?? I 
cannot figure out why it happens?
best regards
Marcin Piatek

user space code:

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/mman.h>
# include <sys/io.h>

# include <native/task.h>
# include <native/queue.h>

# define DISP_PRIO   1 /* Highest RT priority */
# define DISP_MODE   T_JOINABLE  /* No flags */
# define DISP_STKSZ  0  /* Stack size (use default one) */

RT_QUEUE my_queue;
RT_TASK my_display;
RT_TASK my_task;


void my_display_func (void * cookie) {
        unsigned long overruns;
        int err=0, hour_counter, second_counter, mili_counter;
        int one = 1;

        int real_answer=0;

        err = rt_queue_bind(&my_queue, "MyQueue", TM_INFINITE);
        if (err!=0) {
            printf("Couldn't bind to queue: \n");
            if (err == -EFAULT)
                printf("-EFAULT\n");
            else if (err == -EINTR)
                printf("-EINTR\n");
            else if (err == -EWOULDBLOCK)
                printf("-EWOULDBLOCK\n");
            else if (err == -ETIMEDOUT)
                printf("-ETIMEDOUT\n");
            else if (err == -EPERM)
                printf("-EPERM\n");
            else if (err == -ENOENT)
                printf("-ENOENT\n");
            return;
        }
        printf("Binded to queue\n");

        err = rt_task_bind(&my_task, "MyTask", TM_INFINITE);
        if (err!=0) {
            printf("Couldn't bind to task: ");
            if (err == -EFAULT)
                printf("-EFAULT\n");
            else if (err == -EINTR)
                printf("-EINTR\n");
            else if (err == -EWOULDBLOCK)
                printf("-EWOULDBLOCK\n");
            else if (err == -ETIMEDOUT)
                printf("-ETIMEDOUT\n");
            else if (err == -EPERM)
                printf("-EPERM\n");
            return;
        }
        printf("Binded to task\n");

//        for (hour_counter=0; hour_counter<10; hour_counter++) {
//              for (second_counter=0; second_counter<3600; second_counter++) {
                        for (mili_counter=0; mili_counter<1000; mili_counter++) 
{
                                rt_queue_read(&my_queue, &real_answer, 
sizeof(int), TM_INFINITE);
                                printf("%d\n", real_answer);
                        }
//              }
//      }

        rt_task_unbind(&my_task);
        rt_queue_unbind(&my_queue);
}

int main (int argc, void *argv[]) {
        int err;

        /* Disable pageing for this program's memory. */
        mlockall(MCL_CURRENT | MCL_FUTURE);

        /* Create a real-time task */
        if ((err = rt_task_create(&my_display, "MyDisplay", DISP_STKSZ, 
DISP_PRIO, DISP_MODE))) {
                printf("Display creating error.\n");
                exit(1);
        }

        /* If successfully created, start the task. */
        rt_task_start(&my_display, &my_display_func, NULL);

        rt_task_join(&my_display);
        
        rt_task_delete(&my_display);
}





module code:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/pci.h>

#include <native/task.h>
#include <native/timer.h>
#include <native/queue.h>

#include "baseaddress.h"

# define TASK_PRIO   99 /* Highest RT priority */
# define TASK_MODE   T_CPU(0)  /* No flags */
# define TASK_STKSZ  4096  /* Stack size (use default one) */
# define TASK_PERIOD 1000000 /* 1ms period */

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Marcin Piatek");

RT_TASK my_task;
RT_QUEUE my_queue;

/**
*       PCI device structs.
*/
struct pci_dev *base_address_pci_dev;
unsigned long io_base_address = 0;      /* RTDAC4 IO base address*/

/**
*       PCI device identification struct.
*/
static struct pci_device_id base_address_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTECO, PCI_DEVICE_ID_INTECO_RTDAC4) },
        {0, },
};
MODULE_DEVICE_TABLE(pci, base_address_ids);

/**
*       PCI driver struct.
*/
static struct pci_driver pci_driver = {
        .name = "iores",
        .id_table = base_address_ids,
        .probe = base_address_probe,
        .remove = base_address_remove,
};

/**
*   Task function
*/

void my_task_func (void * cookie) {
        unsigned long overruns;
        int err, hour_counter, second_counter, mili_counter;

        unsigned int value=0, prev_value=0, msb=0, lsb=0, answer=0;
        int real_answer=0;

        DEBUG_MSG("After start.\n");

        if ((err = rt_task_set_periodic(NULL, TM_NOW, TASK_PERIOD))) {
                DEBUG_MSG("Timer setting error.\n");
                return;
        }

//      for (hour_counter=0; hour_counter<10; hour_counter++) {
//              for (second_counter=0; second_counter<3600; second_counter++) {
                        for (mili_counter=0; mili_counter<1000; mili_counter++) 
{
                                value = inw(io_base_address + 172);
                                msb = inw(io_base_address + 176);
                                lsb = inw(io_base_address + 180);
                                value = msb * 0x10000 + lsb;

                                if (value > prev_value)
                                        answer = (value - prev_value) * 25;
                                else
                                        answer = ((0xFFFFFFFF - prev_value) + 
value + 1) * 25;
                                real_answer = answer - 1000000;
                                prev_value = value;

                                rt_queue_write(&my_queue, &real_answer, 
sizeof(int), Q_NORMAL);
//                                DEBUG_MSG("answer = %d\n", real_answer);
                                rt_task_wait_period(&overruns);
                        }
//              }
//      }
}


/**
*       Initialization function.
*       It register char devices.
*/
static int base_address_init(void) {
    int err;

    if ((err = pci_register_driver(&pci_driver)))
        return err;

    if ((err = rt_queue_create(&my_queue, "MyQueue", sizeof(int)*1000, 1000, 
Q_FIFO))) {
        DEBUG_MSG("Pipe cannot be created.\n");
    }

    err = rt_task_create(&my_task, "MyTask", TASK_STKSZ, TASK_PRIO, TASK_MODE);
    if (!err)
        rt_task_start(&my_task, &my_task_func, NULL);

    return 0;

}

/**
*       Deinitialization function.
*       Unregister char devices.
*/
static void __exit base_address_exit(void) {

    rt_task_delete(&my_task);
    rt_queue_delete(&my_queue);

    pci_unregister_driver(&pci_driver);
}


/**
*       PCI device function invoked when probing device.
*/
int base_address_probe(struct pci_dev *dev, const struct pci_device_id *id) {

    u16 vendor_id, device_id;
    pci_enable_device(dev);
    pci_read_config_word(dev, 0, &vendor_id);
    DEBUG_MSG("vendor id: %x\n", vendor_id);
    pci_read_config_word(dev, 2, &device_id);
    DEBUG_MSG("device id: %x\n", device_id);

    if (vendor_id == PCI_VENDOR_ID_INTECO && device_id == 
PCI_DEVICE_ID_INTECO_RTDAC4) {
        base_address_pci_dev = dev;
        io_base_address = pci_resource_start(base_address_pci_dev, 2);
        DEBUG_MSG("PCI resource address: %lx\n", io_base_address);
        return 0;
    }
    else
        return -1;
}

/**
*       PCI device function invoked when removing device.
*/
void base_address_remove(struct pci_dev *dev) {
}

/**
*       Register module functions.
*/
module_init(base_address_init);
module_exit(base_address_exit);



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

Reply via email to