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