* [Xenomai-help] problem inserting a kernel module
@ 2007-01-19 15:24 mani bhatti
2007-01-19 15:50 ` Markus Franke
0 siblings, 1 reply; 4+ messages in thread
From: mani bhatti @ 2007-01-19 15:24 UTC (permalink / raw)
To: xenomai
[-- Attachment #1.1: Type: text/plain, Size: 482 bytes --]
Hi all
i have a problem inserting the realtimedriver.ko module from captain.at
actually everything works well module is made with out any error from make file and user.c also compiles but when i try to insert following error appears
insmod: error inserting './realtimedriver.ko': -1 Unknown symbol in module
Is there any error inside module.Thanks.
i have attached all files.thanks
---------------------------------
Everyone is raving about the all-new Yahoo! Mail beta.
[-- Attachment #1.2: Type: text/html, Size: 598 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 211431340-realtimedriver.c --]
[-- Type: text/x-csrc; name="realtimedriver.c", Size: 12970 bytes --]
#include <linux/mman.h>
#include <rtdm/rtdm_driver.h>
#include "inc.h"
char dummy_buffer[BUFSIZE];
int events;
int ioctlvalue;
// our driver context struct: used for storing various information
struct demodrv_context {
rtdm_irq_t irq_handle;
rtdm_lock_t lock;
int dev_id;
u64 last_timestamp;
rtdm_event_t irq_event;
volatile unsigned long irq_event_lock;
volatile int irq_events;
int64_t timeout;
void *buf;
rtdm_user_info_t *mapped_user_info;
void *mapped_user_addr;
};
#ifdef USEMMAP
static void demo_vm_open(struct vm_area_struct *vma)
{
printk("opening %p, private_data = %p\n", vma,
vma->vm_private_data);
}
static void demo_vm_close(struct vm_area_struct *vma)
{
printk("releasing %p, private_data = %p\n", vma,
vma->vm_private_data);
}
static struct vm_operations_struct mmap_ops = {
.open = demo_vm_open,
.close = demo_vm_close,
};
#endif
/**********************************************************/
/* INTERRUPT HANDLING */
/**********************************************************/
static int demo_interrupt(rtdm_irq_t *irq_context)
{
struct demodrv_context *ctx;
int dev_id;
// timestamp, if needed, can be obtained list this:
// u64 timestamp = rtdm_clock_read();
int ret = RTDM_IRQ_HANDLED; // usual return value
ctx = rtdm_irq_get_arg(irq_context, struct demodrv_context);
dev_id = ctx->dev_id;
rtdm_lock_get(&ctx->lock);
// do stuff
#ifdef TIMERINT
if (events > 100) {
rtdm_event_signal(&ctx->irq_event);
events = 0;
}
#else
rtdm_event_signal(&ctx->irq_event);
#endif
events++;
rtdm_lock_put(&ctx->lock);
// those return values were dropped from the RTDM
// ret = RTDM_IRQ_ENABLE | RTDM_IRQ_PROPAGATE;
#ifdef TIMERINT
// Only propagate the timer interrupt, so that linux sees it.
// Forwarding interrupts to the non-realtime domain is not a common
// use-case of realtime device drivers, so usually DON'T DO THIS.
// But here we grab the important timer interrupt, so we need to propagate it.
return XN_ISR_PROPAGATE;
#else
// signal interrupt is handled and don't propagate the interrupt to linux
return RTDM_IRQ_HANDLED;
#endif
}
/**********************************************************/
/* DRIVER OPEN */
/**********************************************************/
int demo_open_rt(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info,
int oflags)
{
struct demodrv_context *my_context;
#ifdef USEMMAP
unsigned long vaddr;
#endif
int dev_id = context->device->device_id;
int ret;
// get the context for our driver - used to store driver info
my_context = (struct demodrv_context *)context->dev_private;
#ifdef USEMMAP
// allocate and prepare memory for our buffer
my_context->buf = kmalloc(BUFFER_SIZE, 0);
/* mark pages reserved so that remap_pfn_range works */
for (vaddr = (unsigned long)my_context->buf;
vaddr < (unsigned long)my_context->buf + BUFFER_SIZE;
vaddr += PAGE_SIZE)
SetPageReserved(virt_to_page(vaddr));
// write some test value to the start of our buffer
*(int *)my_context->buf = 1234;
my_context->mapped_user_addr = NULL;
#endif
// we also have an interrupt handler:
#ifdef TIMERINT
ret = rtdm_irq_request(&my_context->irq_handle, TIMER_INT,
demo_interrupt,
0, context->device->proc_name, my_context);
#else
ret = rtdm_irq_request(&my_context->irq_handle, PAR_INT,
demo_interrupt,
0, context->device->proc_name, my_context);
#endif
if (ret < 0)
return ret;
/* IPC initialisation - cannot fail with used parameters */
rtdm_lock_init(&my_context->lock);
rtdm_event_init(&my_context->irq_event, 0);
my_context->dev_id = dev_id;
my_context->irq_events = 0;
my_context->irq_event_lock = 0;
my_context->timeout = 0; // wait INFINITE
#ifndef TIMERINT
//set port to interrupt mode; pins are output
outb_p(0x10, BASEPORT + 2);
#endif
// enable interrupt in RTDM
rtdm_irq_enable(&my_context->irq_handle);
return 0;
}
/**********************************************************/
/* DRIVER CLOSE */
/**********************************************************/
int demo_close_rt(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info)
{
struct demodrv_context *my_context;
rtdm_lockctx_t lock_ctx;
#ifdef USEMMAP
unsigned long vaddr;
#endif
// get the context
my_context = (struct demodrv_context *)context->dev_private;
#ifdef USEMMAP
// printk some test value
printk("%d\n", *((int *)my_context->buf + 10));
// munmap our buffer
if (my_context->mapped_user_addr) {
int ret = rtdm_munmap(my_context->mapped_user_info,
my_context->mapped_user_addr,
BUFFER_SIZE);
printk("rtdm_munmap = %p, %d\n", my_context->mapped_user_info,
ret);
}
/* clear pages reserved */
for (vaddr = (unsigned long)my_context->buf;
vaddr < (unsigned long)my_context->buf + BUFFER_SIZE;
vaddr += PAGE_SIZE)
ClearPageReserved(virt_to_page(vaddr));
kfree(my_context->buf);
#endif
// if we need to do some stuff with preemption disabled:
rtdm_lock_get_irqsave(&my_context->lock, lock_ctx);
// other stuff here
rtdm_lock_put_irqrestore(&my_context->lock, lock_ctx);
// free irq in RTDM
rtdm_irq_free(&my_context->irq_handle);
// destroy our interrupt signal/event
rtdm_event_destroy(&my_context->irq_event);
return 0;
}
/**********************************************************/
/* DRIVER IOCTL */
/**********************************************************/
int demo_ioctl_rt(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info,
int request,
void *arg)
{
struct demodrv_context *my_context;
#ifdef USEMMAP
int err;
#endif
int ret = 0;
my_context = (struct demodrv_context *)context->dev_private;
switch (request) {
case MMAP: // set mmap pointer
#ifdef USEMMAP
printk("buf = %p:%x\n", my_context->buf, *(int*)my_context->buf);
err = rtdm_mmap_to_user(user_info, my_context->buf,BUFFER_SIZE, PROT_READ|PROT_WRITE, (void **)arg,&mmap_ops,(void *)0x12345678);
if (!err) {
my_context->mapped_user_info = user_info;
my_context->mapped_user_addr = *(void **)arg;
}
printk("rtdm_mmap = %p %d\n", my_context->mapped_user_info,err);
#else
return -EPERM;
#endif
break;
case GETVALUE: // write "ioctlvalue" to user
if (user_info) {
if (!rtdm_rw_user_ok(user_info, arg, sizeof(int)) ||
rtdm_copy_to_user(user_info, arg, &ioctlvalue,
sizeof(int)))
return -EFAULT;
} else
memcpy(arg, &ioctlvalue, sizeof(int));
break;
case SETVALUE: // read "ioctlvalue" from user
if (user_info) {
if (!rtdm_read_user_ok(user_info, arg, sizeof(int)) ||
rtdm_copy_from_user(user_info, &ioctlvalue, arg,
sizeof(int)))
return -EFAULT;
}
break;
default:
ret = -ENOTTY;
}
return ret;
}
/**********************************************************/
/* DRIVER READ */
/**********************************************************/
int demo_read_rt(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info, void *buf, size_t nbyte)
{
struct demodrv_context *ctx;
int dev_id;
// rtdm_lockctx_t lock_ctx;
char *out_pos = (char *)buf;
rtdm_toseq_t timeout_seq;
int ret;
// zero bytes requested ? return!
if (nbyte == 0)
return 0;
// check if R/W actions to user-space are allowed
if (user_info && !rtdm_rw_user_ok(user_info, buf, nbyte))
return -EFAULT;
ctx = (struct demodrv_context *)context->dev_private;
dev_id = ctx->dev_id;
// in case we need to check if reading is allowed (locking)
/* if (test_and_set_bit(0, &ctx->in_lock))
return -EBUSY;
*/
/* // if we need to do some stuff with preemption disabled:
rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
// stuff here
rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
*/
// wait: if ctx->timeout = 0, it will block infintely until
// rtdm_event_signal(&ctx->irq_event); is called from our
// interrupt routine
ret = rtdm_event_timedwait(&ctx->irq_event, ctx->timeout,
&timeout_seq);
// now write the requested stuff to user-space
if (rtdm_copy_to_user(user_info, out_pos,
dummy_buffer, BUFSIZE) != 0) {
ret = -EFAULT;
} else {
ret = BUFSIZE;
}
return ret;
}
/**********************************************************/
/* DRIVER WRITE */
/**********************************************************/
int demo_write_rt(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info,
const void *buf, size_t nbyte)
{
struct demodrv_context *ctx;
int dev_id;
char *in_pos = (char *)buf;
int ret;
if (nbyte == 0)
return 0;
if (user_info && !rtdm_read_user_ok(user_info, buf, nbyte))
return -EFAULT;
ctx = (struct demodrv_context *)context->dev_private;
dev_id = ctx->dev_id;
// make write operation atomic
/* ret = rtdm_mutex_timedlock(&ctx->out_lock,
ctx->config.rx_timeout, &timeout_seq);
if (ret)
return ret; */
/* // if we need to do some stuff with preemption disabled:
rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
// stuff here
rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
*/
// now copy the stuff from user-space to our kernel dummy_buffer
if (rtdm_copy_from_user(user_info, dummy_buffer,in_pos, BUFSIZE) != 0)
{
ret = -EFAULT;
} else {
ret = BUFSIZE;
}
// used when it is atomic
// rtdm_mutex_unlock(&ctx->out_lock);
return ret;
}
/**********************************************************/
/* DRIVER OPERATIONS */
/**********************************************************/
static struct rtdm_device demo_device = {
struct_version: RTDM_DEVICE_STRUCT_VER,
device_flags: RTDM_NAMED_DEVICE,
context_size: sizeof(struct demodrv_context),
device_name: DEV_FILE,
/* open and close functions are not real-time safe due kmalloc
and kfree. If you do not use kmalloc and kfree, and you made
sure that there is no syscall in the open/close handler, you
can declare the open_rt and close_rt handler.
*/
open_rt: NULL,
open_nrt: demo_open_rt,
ops: {
close_rt: NULL,
close_nrt: demo_close_rt,
ioctl_rt: NULL,
ioctl_nrt: demo_ioctl_rt, // rtdm_mmap_to_user is not RT safe
read_rt: demo_read_rt,
read_nrt: NULL,
write_rt: demo_write_rt,
write_nrt: NULL,
recvmsg_rt: NULL,
recvmsg_nrt: NULL,
sendmsg_rt: NULL,
sendmsg_nrt: NULL,
},
device_class: RTDM_CLASS_EXPERIMENTAL,
device_sub_class: 222,
driver_name: DRV_NAME,
peripheral_name: DEV_FILE_NAME,
provider_name: "-",
proc_name: demo_device.device_name,
};
/**********************************************************/
/* INIT DRIVER */
/**********************************************************/
int init_module(void)
{
return rtdm_dev_register(&demo_device);
}
/**********************************************************/
/* CLEANUP DRIVER */
/**********************************************************/
void cleanup_module(void)
{
rtdm_dev_unregister(&demo_device, 1000);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("RTDM Real Time Driver Example");
[-- Attachment #3: 402397780-Makefile --]
[-- Type: application/octet-stream, Size: 2785 bytes --]
####################################################################
# MAKEFILE TEMPLATE FOR KERNEL MODULES AND USER SPACE APPLICATIONS #
# V0.3 (C) 2006 www.captain.at #####################################
####################################################################
### Names of the kernel module(s) and user space application(s) ####
### separated by spaces ##########################################
### (omit names if no module(s) or application(s) is(are) built) ###
KERNELMODULES ?= realtimedriver
USERAPPS ?= user
### SKIN = xeno, posix etc.
SKIN ?= xeno
UNAME := $(shell uname -r)
KERNELSOURCEDIR ?= /lib/modules/$(UNAME)/build
### Xenomai directory, xeno-config and library directory ###########
XENO_DIR ?= /usr/xenomai
XENO_CONFIG ?= $(XENO_DIR)/bin/xeno-config
XENO_LIB_DIR ?= $(shell $(XENO_CONFIG) --library-dir)
### User space application compile options #########################
USERAPP_LIBS ?= -lnative -lrtdm
USERAPP_LDFLAGS ?= $(shell $(XENO_CONFIG) --$(SKIN)-ldflags)
USERAPP_CFLAGS ?= $(shell $(XENO_CONFIG) --$(SKIN)-cflags)
### General configuration stuff ####################################
CC = $(shell $(XENO_CONFIG) --cc)
####################################################################
#### Usually you don't need to modify this file below this line ####
####################################################################
################ KERNEL MODULE START ###############################
OBJS := ${patsubst %, %.o, $(KERNELMODULES)}
CLEANTHIS := ${patsubst %, .%*, $(KERNELMODULES)}
ifneq ($(KERNELMODULES),)
ifeq ($(findstring 2.6,$(KERNELSOURCEDIR)),2.6)
### KERNEL 2.6 #####################################################
obj-m := $(OBJS)
EXTRA_CFLAGS := -I$(XENO_DIR)/include
PWD := $(shell pwd)
all:: $(USERAPPS)
$(MAKE) -C $(KERNELSOURCEDIR) SUBDIRS=$(PWD) modules
else ###############################################################
### KERNEL 2.4 #####################################################
HELP := -I$(KERNELSOURCEDIR)/include/xenomai/compat -I$(XENO_DIR)/include
INCLUDE := -I$(KERNELSOURCEDIR)/include $(HELP)
CFLAGS := -O2 -Wall -DMODULE -D__KERNEL__ -DLINUX $(INCLUDE)
all:: $(OBJS) $(USERAPPS)
endif
endif
clean::
$(RM) $(CLEANTHIS) *.cmd *.o *.ko *.mod.c
$(RM) -R .tmp*
################ KERNEL MODULE END #################################
################ USER APPLICATIONS START ###########################
ifneq ($(USERAPPS),)
USERSP := ${patsubst %, %.c, $(USERAPPS)}
$(USERAPPS): $(USERSP)
$(CC) -o $@ $< $(USERAPP_CFLAGS) $(USERAPP_LDFLAGS) $(USERAPP_LIBS)
endif
clean::
$(RM) $(USERAPPS)
################# USER APPLICATIONS END ############################
.PHONY: clean
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 1570998766-user.c --]
[-- Type: text/x-csrc; name="user.c", Size: 5757 bytes --]
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <native/task.h>
#include <native/timer.h>
#include <rtdm/rtdm.h>
#include "inc.h"
unsigned int my_state = 0;
int timer_started = 0;
int my_fd = -1;
int shutdownnow = 0;
RT_TASK my_task;
// --s-ms-us-ns
RTIME my_task_period_ns = 1000000000llu;
#ifdef USEMMAP
void *mmappointer;
#endif
/**********************************************************/
/* CLOSE RT DRIVER */
/**********************************************************/
static int close_file( int fd, unsigned char *name) {
int ret,i=0;
do {
i++;
ret = rt_dev_close(fd);
switch(-ret){
case EBADF: printf("%s -> invalid fd or context\n",name);
break;
case EAGAIN: printf("%s -> EAGAIN (%d times)\n",name,i);
rt_task_sleep(50000); // wait 50us
break;
case 0: printf("%s -> closed\n",name);
break;
default: printf("%s -> ???\n",name);
break;
}
} while (ret == -EAGAIN && i < 10);
return ret;
}
/**********************************************************/
/* CLEANING UP */
/**********************************************************/
void cleanup_all(void) {
if (my_state & STATE_FILE_OPENED) {
close_file( my_fd, DEV_FILE " (user)");
my_state &= ~STATE_FILE_OPENED;
}
if (my_state & STATE_TASK_CREATED) {
printf("delete my_task\n");
rt_task_delete(&my_task);
my_state &= ~STATE_TASK_CREATED;
}
if (timer_started) {
printf("stop timer\n");
rt_timer_stop();
}
}
void catch_signal(int sig) {
shutdownnow = 1;
cleanup_all();
printf("exit\n");
return;
}
/**********************************************************/
/* REAL TIME TASK */
/**********************************************************/
void my_task_proc(void *arg) {
int ret;
ssize_t sz = sizeof(RTIME);
ssize_t written = 0;
ssize_t read = 0;
int counter = 0;
int readbackcounter;
unsigned char buf[17] = "CAPTAIN WAS HERE\0";
unsigned char buf2[17] = "XXXXXXXXXXXXXXXX\0";
/* no periodic task, due blocking read from the RT driver (see below
too)
ret = rt_task_set_periodic(NULL, TM_NOW,
rt_timer_ns2ticks(my_task_period_ns));
if (ret) {
printf("error while set periodic, code %d\n",ret);
goto exit_my_task;
}
*/
#ifdef USEMMAP
printf("ioctl = %d\n", rt_dev_ioctl(my_fd, MMAP, &mmappointer));
printf("*p = %d, p = %p\n", *((int *)mmappointer), mmappointer);
#endif
while (1) {
sprintf(buf, "CAPTAIN %d", counter);
counter++;
if (counter > 100) counter = 0;
/* switch to primary mode */
ret = rt_task_set_mode(0, T_PRIMARY, NULL);
if (ret) {
printf("error while rt_task_set_mode, code %d\n",ret);
goto exit_my_task;
}
/* // rt_dev_read blocks, so we can't use rt_task_wait_period here,
// otherwise we get a ETIMEDOUT 110 = Connection timed out
// after the next rt_task_wait_period
ret = rt_task_wait_period(NULL);
if (ret) {
printf("error while rt_task_wait_period, code %d\n",ret);
goto exit_my_task;
}
*/
sz = sizeof(buf);
written = rt_dev_write(my_fd, &buf, sizeof(buf));
printf("WRITE: written=%d sz=%d\n", written, sz);
if (written != sz ) {
if (written < 0 ) {
printf("error while rt_dev_write, code %d\n",written);
} else {
printf("only %d / %d byte transmitted\n",written, sz);
}
goto exit_my_task;
}
sz = sizeof(buf2);
read = rt_dev_read(my_fd, &buf2, sizeof(buf2));
if (read == sz ) {
printf("READ: read=%s\n",buf2);
} else {
if (read < 0 ) {
printf("error while rt_dev_read, code %d\n",read);
} else {
printf("only %d / %d byte received \n",read,sz);
}
}
// read blocks, so check if user hit CTRL-C meanwhile
// otherwise we segfault when mmap'ing
if (shutdownnow == 1) break;
#ifdef USEMMAP
*((int *)mmappointer + 10) = counter + 1000;
printf("MMAP: *((int *)mmappointer + 10) = %d\n",
*((int *)mmappointer + 10));
#endif
rt_dev_ioctl(my_fd, SETVALUE, &counter);
rt_dev_ioctl(my_fd, GETVALUE, &readbackcounter);
printf("IOCTL: readbackcounter=%d\n", readbackcounter);
}
exit_my_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, DEV_FILE " (write)")) {
my_state &= ~STATE_FILE_OPENED;
}
}
printf("exit\n");
}
/**********************************************************/
/* MAIN: mainly RT task initialization */
/**********************************************************/
int main(int argc, char* argv[]) {
int ret = 0;
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
printf("PRESS CTRL-C to EXIT\n");
/* no memory-swapping for this programm */
mlockall(MCL_CURRENT | MCL_FUTURE);
/* open DEV_FILE */
my_fd = rt_dev_open( DEV_FILE, 0);
if (my_fd < 0) {
printf("can't open %s\n", DEV_FILE);
goto error;
}
my_state |= STATE_FILE_OPENED;
printf("%s opened\n", DEV_FILE);
/* create my_task */
ret = rt_task_create(&my_task,"my_task",0,50,0);
if (ret) {
printf("failed to create my_task, code %d\n",ret);
goto error;
}
my_state |= STATE_TASK_CREATED;
printf("my_task created\n");
/* start my_task */
printf("starting my_task\n");
ret = rt_task_start(&my_task,&my_task_proc,NULL);
if (ret) {
printf("failed to start my_task, code %d\n",ret);
goto error;
}
pause();
return 0;
error:
cleanup_all();
return ret;
}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 1672826649-inc.h --]
[-- Type: text/x-chdr; name="inc.h", Size: 632 bytes --]
// if TIMERINT is defined, the linux timer interrupt is used
// otherwise the parallel port interrupt is used
#define TIMERINT
// if USEMMAP IS defined, also MMAP operations will be made
#define USEMMAP
#define DEV_FILE "demodev0"
#define DEV_FILE_NAME "demodev"
#define DRV_NAME "demodrv"
#define BUFFER_SIZE 100000
#define BUFSIZE 17
#define PAR_INT 7
#define TIMER_INT 0
#define BASEPORT 0x378
#define MMAP 0
#define GETVALUE 1
#define SETVALUE 2
#define STATE_FILE_OPENED 1
#define STATE_TASK_CREATED 2
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Xenomai-help] problem inserting a kernel module
2007-01-19 15:24 [Xenomai-help] problem inserting a kernel module mani bhatti
@ 2007-01-19 15:50 ` Markus Franke
2007-01-19 17:02 ` mani bhatti
0 siblings, 1 reply; 4+ messages in thread
From: Markus Franke @ 2007-01-19 15:50 UTC (permalink / raw)
To: mani bhatti; +Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 21943 bytes --]
Well, some symbols which are referenced by your module are not found in
the kernel. A "dmesg()"-call should provide you some information about
the missing symbols. Maybe you missed inserting the "RTDM"-kernel module?
Regards,
Markus
mani bhatti wrote:
> Hi all
> i have a problem inserting the realtimedriver.ko module from captain.at
> actually everything works well module is made with out any error from make file and user.c also compiles but when i try to insert following error appears
>
> insmod: error inserting './realtimedriver.ko': -1 Unknown symbol in module
>
> Is there any error inside module.Thanks.
> i have attached all files.thanks
>
>
>
>
>
> ---------------------------------
> Everyone is raving about the all-new Yahoo! Mail beta.
>
>
> ------------------------------------------------------------------------
>
> #include <linux/mman.h>
> #include <rtdm/rtdm_driver.h>
> #include "inc.h"
>
> char dummy_buffer[BUFSIZE];
> int events;
> int ioctlvalue;
>
> // our driver context struct: used for storing various information
> struct demodrv_context {
> rtdm_irq_t irq_handle;
> rtdm_lock_t lock;
> int dev_id;
> u64 last_timestamp;
> rtdm_event_t irq_event;
> volatile unsigned long irq_event_lock;
> volatile int irq_events;
> int64_t timeout;
> void *buf;
> rtdm_user_info_t *mapped_user_info;
> void *mapped_user_addr;
> };
>
> #ifdef USEMMAP
> static void demo_vm_open(struct vm_area_struct *vma)
> {
> printk("opening %p, private_data = %p\n", vma,
> vma->vm_private_data);
> }
> static void demo_vm_close(struct vm_area_struct *vma)
> {
> printk("releasing %p, private_data = %p\n", vma,
> vma->vm_private_data);
> }
> static struct vm_operations_struct mmap_ops = {
> .open = demo_vm_open,
> .close = demo_vm_close,
> };
> #endif
>
> /**********************************************************/
> /* INTERRUPT HANDLING */
> /**********************************************************/
> static int demo_interrupt(rtdm_irq_t *irq_context)
> {
> struct demodrv_context *ctx;
> int dev_id;
> // timestamp, if needed, can be obtained list this:
> // u64 timestamp = rtdm_clock_read();
> int ret = RTDM_IRQ_HANDLED; // usual return value
>
> ctx = rtdm_irq_get_arg(irq_context, struct demodrv_context);
> dev_id = ctx->dev_id;
>
> rtdm_lock_get(&ctx->lock);
>
> // do stuff
> #ifdef TIMERINT
> if (events > 100) {
> rtdm_event_signal(&ctx->irq_event);
> events = 0;
> }
> #else
> rtdm_event_signal(&ctx->irq_event);
> #endif
> events++;
>
> rtdm_lock_put(&ctx->lock);
> // those return values were dropped from the RTDM
> // ret = RTDM_IRQ_ENABLE | RTDM_IRQ_PROPAGATE;
>
> #ifdef TIMERINT
> // Only propagate the timer interrupt, so that linux sees it.
> // Forwarding interrupts to the non-realtime domain is not a common
> // use-case of realtime device drivers, so usually DON'T DO THIS.
> // But here we grab the important timer interrupt, so we need to propagate it.
> return XN_ISR_PROPAGATE;
> #else
> // signal interrupt is handled and don't propagate the interrupt to linux
> return RTDM_IRQ_HANDLED;
> #endif
> }
>
> /**********************************************************/
> /* DRIVER OPEN */
> /**********************************************************/
> int demo_open_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> int oflags)
> {
> struct demodrv_context *my_context;
> #ifdef USEMMAP
> unsigned long vaddr;
> #endif
> int dev_id = context->device->device_id;
> int ret;
>
> // get the context for our driver - used to store driver info
> my_context = (struct demodrv_context *)context->dev_private;
>
> #ifdef USEMMAP
> // allocate and prepare memory for our buffer
> my_context->buf = kmalloc(BUFFER_SIZE, 0);
> /* mark pages reserved so that remap_pfn_range works */
> for (vaddr = (unsigned long)my_context->buf;
> vaddr < (unsigned long)my_context->buf + BUFFER_SIZE;
> vaddr += PAGE_SIZE)
> SetPageReserved(virt_to_page(vaddr));
> // write some test value to the start of our buffer
> *(int *)my_context->buf = 1234;
>
> my_context->mapped_user_addr = NULL;
> #endif
>
> // we also have an interrupt handler:
> #ifdef TIMERINT
> ret = rtdm_irq_request(&my_context->irq_handle, TIMER_INT,
> demo_interrupt,
> 0, context->device->proc_name, my_context);
> #else
> ret = rtdm_irq_request(&my_context->irq_handle, PAR_INT,
> demo_interrupt,
> 0, context->device->proc_name, my_context);
> #endif
> if (ret < 0)
> return ret;
>
> /* IPC initialisation - cannot fail with used parameters */
> rtdm_lock_init(&my_context->lock);
> rtdm_event_init(&my_context->irq_event, 0);
> my_context->dev_id = dev_id;
>
> my_context->irq_events = 0;
> my_context->irq_event_lock = 0;
> my_context->timeout = 0; // wait INFINITE
>
> #ifndef TIMERINT
> //set port to interrupt mode; pins are output
> outb_p(0x10, BASEPORT + 2);
> #endif
> // enable interrupt in RTDM
> rtdm_irq_enable(&my_context->irq_handle);
> return 0;
> }
>
> /**********************************************************/
> /* DRIVER CLOSE */
> /**********************************************************/
> int demo_close_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info)
> {
> struct demodrv_context *my_context;
> rtdm_lockctx_t lock_ctx;
> #ifdef USEMMAP
> unsigned long vaddr;
> #endif
> // get the context
> my_context = (struct demodrv_context *)context->dev_private;
>
> #ifdef USEMMAP
> // printk some test value
> printk("%d\n", *((int *)my_context->buf + 10));
>
> // munmap our buffer
> if (my_context->mapped_user_addr) {
> int ret = rtdm_munmap(my_context->mapped_user_info,
> my_context->mapped_user_addr,
> BUFFER_SIZE);
> printk("rtdm_munmap = %p, %d\n", my_context->mapped_user_info,
> ret);
> }
>
> /* clear pages reserved */
> for (vaddr = (unsigned long)my_context->buf;
> vaddr < (unsigned long)my_context->buf + BUFFER_SIZE;
> vaddr += PAGE_SIZE)
> ClearPageReserved(virt_to_page(vaddr));
>
> kfree(my_context->buf);
> #endif
>
> // if we need to do some stuff with preemption disabled:
> rtdm_lock_get_irqsave(&my_context->lock, lock_ctx);
> // other stuff here
> rtdm_lock_put_irqrestore(&my_context->lock, lock_ctx);
>
> // free irq in RTDM
> rtdm_irq_free(&my_context->irq_handle);
> // destroy our interrupt signal/event
> rtdm_event_destroy(&my_context->irq_event);
> return 0;
> }
>
> /**********************************************************/
> /* DRIVER IOCTL */
> /**********************************************************/
> int demo_ioctl_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> int request,
> void *arg)
> {
> struct demodrv_context *my_context;
> #ifdef USEMMAP
> int err;
> #endif
> int ret = 0;
> my_context = (struct demodrv_context *)context->dev_private;
>
> switch (request) {
> case MMAP: // set mmap pointer
> #ifdef USEMMAP
> printk("buf = %p:%x\n", my_context->buf, *(int*)my_context->buf);
>
> err = rtdm_mmap_to_user(user_info, my_context->buf,BUFFER_SIZE, PROT_READ|PROT_WRITE, (void **)arg,&mmap_ops,(void *)0x12345678);
> if (!err) {
> my_context->mapped_user_info = user_info;
> my_context->mapped_user_addr = *(void **)arg;
> }
> printk("rtdm_mmap = %p %d\n", my_context->mapped_user_info,err);
> #else
> return -EPERM;
> #endif
> break;
> case GETVALUE: // write "ioctlvalue" to user
> if (user_info) {
> if (!rtdm_rw_user_ok(user_info, arg, sizeof(int)) ||
> rtdm_copy_to_user(user_info, arg, &ioctlvalue,
> sizeof(int)))
> return -EFAULT;
> } else
> memcpy(arg, &ioctlvalue, sizeof(int));
> break;
> case SETVALUE: // read "ioctlvalue" from user
> if (user_info) {
> if (!rtdm_read_user_ok(user_info, arg, sizeof(int)) ||
> rtdm_copy_from_user(user_info, &ioctlvalue, arg,
> sizeof(int)))
> return -EFAULT;
> }
> break;
> default:
> ret = -ENOTTY;
> }
> return ret;
> }
>
> /**********************************************************/
> /* DRIVER READ */
> /**********************************************************/
> int demo_read_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info, void *buf, size_t nbyte)
> {
> struct demodrv_context *ctx;
> int dev_id;
> // rtdm_lockctx_t lock_ctx;
> char *out_pos = (char *)buf;
> rtdm_toseq_t timeout_seq;
> int ret;
>
> // zero bytes requested ? return!
> if (nbyte == 0)
> return 0;
>
> // check if R/W actions to user-space are allowed
> if (user_info && !rtdm_rw_user_ok(user_info, buf, nbyte))
> return -EFAULT;
>
> ctx = (struct demodrv_context *)context->dev_private;
> dev_id = ctx->dev_id;
>
> // in case we need to check if reading is allowed (locking)
> /* if (test_and_set_bit(0, &ctx->in_lock))
> return -EBUSY;
> */
> /* // if we need to do some stuff with preemption disabled:
> rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
> // stuff here
> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
> */
>
> // wait: if ctx->timeout = 0, it will block infintely until
> // rtdm_event_signal(&ctx->irq_event); is called from our
> // interrupt routine
> ret = rtdm_event_timedwait(&ctx->irq_event, ctx->timeout,
> &timeout_seq);
>
> // now write the requested stuff to user-space
> if (rtdm_copy_to_user(user_info, out_pos,
> dummy_buffer, BUFSIZE) != 0) {
> ret = -EFAULT;
> } else {
> ret = BUFSIZE;
> }
> return ret;
> }
>
> /**********************************************************/
> /* DRIVER WRITE */
> /**********************************************************/
> int demo_write_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> const void *buf, size_t nbyte)
> {
> struct demodrv_context *ctx;
> int dev_id;
> char *in_pos = (char *)buf;
> int ret;
>
> if (nbyte == 0)
> return 0;
> if (user_info && !rtdm_read_user_ok(user_info, buf, nbyte))
> return -EFAULT;
>
> ctx = (struct demodrv_context *)context->dev_private;
> dev_id = ctx->dev_id;
>
> // make write operation atomic
> /* ret = rtdm_mutex_timedlock(&ctx->out_lock,
> ctx->config.rx_timeout, &timeout_seq);
> if (ret)
> return ret; */
>
> /* // if we need to do some stuff with preemption disabled:
> rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
> // stuff here
> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
> */
>
> // now copy the stuff from user-space to our kernel dummy_buffer
> if (rtdm_copy_from_user(user_info, dummy_buffer,in_pos, BUFSIZE) != 0)
> {
> ret = -EFAULT;
> } else {
> ret = BUFSIZE;
> }
>
> // used when it is atomic
> // rtdm_mutex_unlock(&ctx->out_lock);
> return ret;
> }
>
> /**********************************************************/
> /* DRIVER OPERATIONS */
> /**********************************************************/
> static struct rtdm_device demo_device = {
> struct_version: RTDM_DEVICE_STRUCT_VER,
>
> device_flags: RTDM_NAMED_DEVICE,
> context_size: sizeof(struct demodrv_context),
> device_name: DEV_FILE,
>
> /* open and close functions are not real-time safe due kmalloc
> and kfree. If you do not use kmalloc and kfree, and you made
> sure that there is no syscall in the open/close handler, you
> can declare the open_rt and close_rt handler.
> */
> open_rt: NULL,
> open_nrt: demo_open_rt,
>
> ops: {
> close_rt: NULL,
> close_nrt: demo_close_rt,
>
> ioctl_rt: NULL,
> ioctl_nrt: demo_ioctl_rt, // rtdm_mmap_to_user is not RT safe
>
> read_rt: demo_read_rt,
> read_nrt: NULL,
>
> write_rt: demo_write_rt,
> write_nrt: NULL,
>
> recvmsg_rt: NULL,
> recvmsg_nrt: NULL,
>
> sendmsg_rt: NULL,
> sendmsg_nrt: NULL,
> },
>
> device_class: RTDM_CLASS_EXPERIMENTAL,
> device_sub_class: 222,
> driver_name: DRV_NAME,
> peripheral_name: DEV_FILE_NAME,
> provider_name: "-",
> proc_name: demo_device.device_name,
> };
>
> /**********************************************************/
> /* INIT DRIVER */
> /**********************************************************/
> int init_module(void)
> {
> return rtdm_dev_register(&demo_device);
> }
>
> /**********************************************************/
> /* CLEANUP DRIVER */
> /**********************************************************/
> void cleanup_module(void)
> {
> rtdm_dev_unregister(&demo_device, 1000);
> }
>
> MODULE_LICENSE("GPL");
> MODULE_DESCRIPTION("RTDM Real Time Driver Example");
>
>
> ------------------------------------------------------------------------
>
> #include <stdio.h>
> #include <signal.h>
> #include <unistd.h>
> #include <sys/mman.h>
>
> #include <native/task.h>
> #include <native/timer.h>
> #include <rtdm/rtdm.h>
> #include "inc.h"
>
> unsigned int my_state = 0;
> int timer_started = 0;
> int my_fd = -1;
> int shutdownnow = 0;
> RT_TASK my_task;
> // --s-ms-us-ns
> RTIME my_task_period_ns = 1000000000llu;
>
> #ifdef USEMMAP
> void *mmappointer;
> #endif
>
> /**********************************************************/
> /* CLOSE RT DRIVER */
> /**********************************************************/
> static int close_file( int fd, unsigned char *name) {
> int ret,i=0;
> do {
> i++;
> ret = rt_dev_close(fd);
> switch(-ret){
> case EBADF: printf("%s -> invalid fd or context\n",name);
> break;
> case EAGAIN: printf("%s -> EAGAIN (%d times)\n",name,i);
> rt_task_sleep(50000); // wait 50us
> break;
> case 0: printf("%s -> closed\n",name);
> break;
> default: printf("%s -> ???\n",name);
> break;
> }
> } while (ret == -EAGAIN && i < 10);
> return ret;
> }
>
> /**********************************************************/
> /* CLEANING UP */
> /**********************************************************/
> void cleanup_all(void) {
> if (my_state & STATE_FILE_OPENED) {
> close_file( my_fd, DEV_FILE " (user)");
> my_state &= ~STATE_FILE_OPENED;
> }
> if (my_state & STATE_TASK_CREATED) {
> printf("delete my_task\n");
> rt_task_delete(&my_task);
> my_state &= ~STATE_TASK_CREATED;
> }
> if (timer_started) {
> printf("stop timer\n");
> rt_timer_stop();
> }
> }
>
> void catch_signal(int sig) {
> shutdownnow = 1;
> cleanup_all();
> printf("exit\n");
> return;
> }
>
> /**********************************************************/
> /* REAL TIME TASK */
> /**********************************************************/
> void my_task_proc(void *arg) {
> int ret;
> ssize_t sz = sizeof(RTIME);
> ssize_t written = 0;
> ssize_t read = 0;
> int counter = 0;
> int readbackcounter;
> unsigned char buf[17] = "CAPTAIN WAS HERE\0";
> unsigned char buf2[17] = "XXXXXXXXXXXXXXXX\0";
> /* no periodic task, due blocking read from the RT driver (see below
> too)
> ret = rt_task_set_periodic(NULL, TM_NOW,
> rt_timer_ns2ticks(my_task_period_ns));
> if (ret) {
> printf("error while set periodic, code %d\n",ret);
> goto exit_my_task;
> }
> */
>
> #ifdef USEMMAP
> printf("ioctl = %d\n", rt_dev_ioctl(my_fd, MMAP, &mmappointer));
> printf("*p = %d, p = %p\n", *((int *)mmappointer), mmappointer);
> #endif
>
> while (1) {
> sprintf(buf, "CAPTAIN %d", counter);
> counter++;
> if (counter > 100) counter = 0;
> /* switch to primary mode */
> ret = rt_task_set_mode(0, T_PRIMARY, NULL);
> if (ret) {
> printf("error while rt_task_set_mode, code %d\n",ret);
> goto exit_my_task;
> }
>
> /* // rt_dev_read blocks, so we can't use rt_task_wait_period here,
> // otherwise we get a ETIMEDOUT 110 = Connection timed out
> // after the next rt_task_wait_period
> ret = rt_task_wait_period(NULL);
> if (ret) {
> printf("error while rt_task_wait_period, code %d\n",ret);
> goto exit_my_task;
> }
> */
> sz = sizeof(buf);
> written = rt_dev_write(my_fd, &buf, sizeof(buf));
> printf("WRITE: written=%d sz=%d\n", written, sz);
> if (written != sz ) {
> if (written < 0 ) {
> printf("error while rt_dev_write, code %d\n",written);
> } else {
> printf("only %d / %d byte transmitted\n",written, sz);
> }
> goto exit_my_task;
> }
>
> sz = sizeof(buf2);
> read = rt_dev_read(my_fd, &buf2, sizeof(buf2));
> if (read == sz ) {
> printf("READ: read=%s\n",buf2);
> } else {
> if (read < 0 ) {
> printf("error while rt_dev_read, code %d\n",read);
> } else {
> printf("only %d / %d byte received \n",read,sz);
> }
> }
>
> // read blocks, so check if user hit CTRL-C meanwhile
> // otherwise we segfault when mmap'ing
> if (shutdownnow == 1) break;
>
> #ifdef USEMMAP
> *((int *)mmappointer + 10) = counter + 1000;
> printf("MMAP: *((int *)mmappointer + 10) = %d\n",
> *((int *)mmappointer + 10));
> #endif
>
> rt_dev_ioctl(my_fd, SETVALUE, &counter);
> rt_dev_ioctl(my_fd, GETVALUE, &readbackcounter);
> printf("IOCTL: readbackcounter=%d\n", readbackcounter);
>
>
> }
> exit_my_task:
> if (my_state & STATE_FILE_OPENED) {
> if (!close_file( my_fd, DEV_FILE " (write)")) {
> my_state &= ~STATE_FILE_OPENED;
> }
> }
> printf("exit\n");
> }
>
> /**********************************************************/
> /* MAIN: mainly RT task initialization */
> /**********************************************************/
> int main(int argc, char* argv[]) {
> int ret = 0;
> signal(SIGTERM, catch_signal);
> signal(SIGINT, catch_signal);
>
> printf("PRESS CTRL-C to EXIT\n");
> /* no memory-swapping for this programm */
> mlockall(MCL_CURRENT | MCL_FUTURE);
>
>
> /* open DEV_FILE */
> my_fd = rt_dev_open( DEV_FILE, 0);
> if (my_fd < 0) {
> printf("can't open %s\n", DEV_FILE);
> goto error;
> }
> my_state |= STATE_FILE_OPENED;
> printf("%s opened\n", DEV_FILE);
>
> /* create my_task */
> ret = rt_task_create(&my_task,"my_task",0,50,0);
> if (ret) {
> printf("failed to create my_task, code %d\n",ret);
> goto error;
> }
> my_state |= STATE_TASK_CREATED;
> printf("my_task created\n");
>
> /* start my_task */
> printf("starting my_task\n");
> ret = rt_task_start(&my_task,&my_task_proc,NULL);
> if (ret) {
> printf("failed to start my_task, code %d\n",ret);
> goto error;
> }
>
> pause();
> return 0;
>
> error:
> cleanup_all();
> return ret;
> }
>
>
> ------------------------------------------------------------------------
>
> // if TIMERINT is defined, the linux timer interrupt is used
> // otherwise the parallel port interrupt is used
> #define TIMERINT
>
> // if USEMMAP IS defined, also MMAP operations will be made
> #define USEMMAP
>
> #define DEV_FILE "demodev0"
> #define DEV_FILE_NAME "demodev"
> #define DRV_NAME "demodrv"
>
> #define BUFFER_SIZE 100000
> #define BUFSIZE 17
> #define PAR_INT 7
> #define TIMER_INT 0
> #define BASEPORT 0x378
> #define MMAP 0
> #define GETVALUE 1
> #define SETVALUE 2
>
> #define STATE_FILE_OPENED 1
> #define STATE_TASK_CREATED 2
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help
--
Nichts ist so praktisch wie eine gute Theorie!
[-- Attachment #2: Markus.Franke.vcf --]
[-- Type: text/x-vcard, Size: 245 bytes --]
begin:vcard
fn:Markus Franke
n:Franke;Markus
adr;quoted-printable:;;Vettersstra=C3=9Fe 64/722;Chemnitz;Saxony;09126;Germany
email;internet:Markus.Franke@domain.hid
x-mozilla-html:FALSE
url:http://www.tu-chemnitz.de/~franm
version:2.1
end:vcard
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Xenomai-help] problem inserting a kernel module
2007-01-19 15:50 ` Markus Franke
@ 2007-01-19 17:02 ` mani bhatti
2007-01-19 17:52 ` Jan Kiszka
0 siblings, 1 reply; 4+ messages in thread
From: mani bhatti @ 2007-01-19 17:02 UTC (permalink / raw)
To: Markus.Franke; +Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 25909 bytes --]
I have got following message
No module found in object
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
realtimedriver: Unknown symbol _rtdm_synch_flush
realtimedriver: Unknown symbol rtdm_event_signal
realtimedriver: Unknown symbol rtdm_event_timedwait
realtimedriver: Unknown symbol rtdm_dev_unregister
realtimedriver: Unknown symbol rtdm_dev_register
Markus Franke <Markus.Franke@domain.hid> wrote: Well, some symbols which are referenced by your module are not found in
the kernel. A "dmesg()"-call should provide you some information about
the missing symbols. Maybe you missed inserting the "RTDM"-kernel module?
Regards,
Markus
mani bhatti wrote:
> Hi all
> i have a problem inserting the realtimedriver.ko module from captain.at
> actually everything works well module is made with out any error from make file and user.c also compiles but when i try to insert following error appears
>
> insmod: error inserting './realtimedriver.ko': -1 Unknown symbol in module
>
> Is there any error inside module.Thanks.
> i have attached all files.thanks
>
>
>
>
>
> ---------------------------------
> Everyone is raving about the all-new Yahoo! Mail beta.
>
>
> ------------------------------------------------------------------------
>
> #include
> #include
> #include "inc.h"
>
> char dummy_buffer[BUFSIZE];
> int events;
> int ioctlvalue;
>
> // our driver context struct: used for storing various information
> struct demodrv_context {
> rtdm_irq_t irq_handle;
> rtdm_lock_t lock;
> int dev_id;
> u64 last_timestamp;
> rtdm_event_t irq_event;
> volatile unsigned long irq_event_lock;
> volatile int irq_events;
> int64_t timeout;
> void *buf;
> rtdm_user_info_t *mapped_user_info;
> void *mapped_user_addr;
> };
>
> #ifdef USEMMAP
> static void demo_vm_open(struct vm_area_struct *vma)
> {
> printk("opening %p, private_data = %p\n", vma,
> vma->vm_private_data);
> }
> static void demo_vm_close(struct vm_area_struct *vma)
> {
> printk("releasing %p, private_data = %p\n", vma,
> vma->vm_private_data);
> }
> static struct vm_operations_struct mmap_ops = {
> .open = demo_vm_open,
> .close = demo_vm_close,
> };
> #endif
>
> /**********************************************************/
> /* INTERRUPT HANDLING */
> /**********************************************************/
> static int demo_interrupt(rtdm_irq_t *irq_context)
> {
> struct demodrv_context *ctx;
> int dev_id;
> // timestamp, if needed, can be obtained list this:
> // u64 timestamp = rtdm_clock_read();
> int ret = RTDM_IRQ_HANDLED; // usual return value
>
> ctx = rtdm_irq_get_arg(irq_context, struct demodrv_context);
> dev_id = ctx->dev_id;
>
> rtdm_lock_get(&ctx->lock);
>
> // do stuff
> #ifdef TIMERINT
> if (events > 100) {
> rtdm_event_signal(&ctx->irq_event);
> events = 0;
> }
> #else
> rtdm_event_signal(&ctx->irq_event);
> #endif
> events++;
>
> rtdm_lock_put(&ctx->lock);
> // those return values were dropped from the RTDM
> // ret = RTDM_IRQ_ENABLE | RTDM_IRQ_PROPAGATE;
>
> #ifdef TIMERINT
> // Only propagate the timer interrupt, so that linux sees it.
> // Forwarding interrupts to the non-realtime domain is not a common
> // use-case of realtime device drivers, so usually DON'T DO THIS.
> // But here we grab the important timer interrupt, so we need to propagate it.
> return XN_ISR_PROPAGATE;
> #else
> // signal interrupt is handled and don't propagate the interrupt to linux
> return RTDM_IRQ_HANDLED;
> #endif
> }
>
> /**********************************************************/
> /* DRIVER OPEN */
> /**********************************************************/
> int demo_open_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> int oflags)
> {
> struct demodrv_context *my_context;
> #ifdef USEMMAP
> unsigned long vaddr;
> #endif
> int dev_id = context->device->device_id;
> int ret;
>
> // get the context for our driver - used to store driver info
> my_context = (struct demodrv_context *)context->dev_private;
>
> #ifdef USEMMAP
> // allocate and prepare memory for our buffer
> my_context->buf = kmalloc(BUFFER_SIZE, 0);
> /* mark pages reserved so that remap_pfn_range works */
> for (vaddr = (unsigned long)my_context->buf;
> vaddr < (unsigned long)my_context->buf + BUFFER_SIZE;
> vaddr += PAGE_SIZE)
> SetPageReserved(virt_to_page(vaddr));
> // write some test value to the start of our buffer
> *(int *)my_context->buf = 1234;
>
> my_context->mapped_user_addr = NULL;
> #endif
>
> // we also have an interrupt handler:
> #ifdef TIMERINT
> ret = rtdm_irq_request(&my_context->irq_handle, TIMER_INT,
> demo_interrupt,
> 0, context->device->proc_name, my_context);
> #else
> ret = rtdm_irq_request(&my_context->irq_handle, PAR_INT,
> demo_interrupt,
> 0, context->device->proc_name, my_context);
> #endif
> if (ret < 0)
> return ret;
>
> /* IPC initialisation - cannot fail with used parameters */
> rtdm_lock_init(&my_context->lock);
> rtdm_event_init(&my_context->irq_event, 0);
> my_context->dev_id = dev_id;
>
> my_context->irq_events = 0;
> my_context->irq_event_lock = 0;
> my_context->timeout = 0; // wait INFINITE
>
> #ifndef TIMERINT
> //set port to interrupt mode; pins are output
> outb_p(0x10, BASEPORT + 2);
> #endif
> // enable interrupt in RTDM
> rtdm_irq_enable(&my_context->irq_handle);
> return 0;
> }
>
> /**********************************************************/
> /* DRIVER CLOSE */
> /**********************************************************/
> int demo_close_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info)
> {
> struct demodrv_context *my_context;
> rtdm_lockctx_t lock_ctx;
> #ifdef USEMMAP
> unsigned long vaddr;
> #endif
> // get the context
> my_context = (struct demodrv_context *)context->dev_private;
>
> #ifdef USEMMAP
> // printk some test value
> printk("%d\n", *((int *)my_context->buf + 10));
>
> // munmap our buffer
> if (my_context->mapped_user_addr) {
> int ret = rtdm_munmap(my_context->mapped_user_info,
> my_context->mapped_user_addr,
> BUFFER_SIZE);
> printk("rtdm_munmap = %p, %d\n", my_context->mapped_user_info,
> ret);
> }
>
> /* clear pages reserved */
> for (vaddr = (unsigned long)my_context->buf;
> vaddr < (unsigned long)my_context->buf + BUFFER_SIZE;
> vaddr += PAGE_SIZE)
> ClearPageReserved(virt_to_page(vaddr));
>
> kfree(my_context->buf);
> #endif
>
> // if we need to do some stuff with preemption disabled:
> rtdm_lock_get_irqsave(&my_context->lock, lock_ctx);
> // other stuff here
> rtdm_lock_put_irqrestore(&my_context->lock, lock_ctx);
>
> // free irq in RTDM
> rtdm_irq_free(&my_context->irq_handle);
> // destroy our interrupt signal/event
> rtdm_event_destroy(&my_context->irq_event);
> return 0;
> }
>
> /**********************************************************/
> /* DRIVER IOCTL */
> /**********************************************************/
> int demo_ioctl_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> int request,
> void *arg)
> {
> struct demodrv_context *my_context;
> #ifdef USEMMAP
> int err;
> #endif
> int ret = 0;
> my_context = (struct demodrv_context *)context->dev_private;
>
> switch (request) {
> case MMAP: // set mmap pointer
> #ifdef USEMMAP
> printk("buf = %p:%x\n", my_context->buf, *(int*)my_context->buf);
>
> err = rtdm_mmap_to_user(user_info, my_context->buf,BUFFER_SIZE, PROT_READ|PROT_WRITE, (void **)arg,&mmap_ops,(void *)0x12345678);
> if (!err) {
> my_context->mapped_user_info = user_info;
> my_context->mapped_user_addr = *(void **)arg;
> }
> printk("rtdm_mmap = %p %d\n", my_context->mapped_user_info,err);
> #else
> return -EPERM;
> #endif
> break;
> case GETVALUE: // write "ioctlvalue" to user
> if (user_info) {
> if (!rtdm_rw_user_ok(user_info, arg, sizeof(int)) ||
> rtdm_copy_to_user(user_info, arg, &ioctlvalue,
> sizeof(int)))
> return -EFAULT;
> } else
> memcpy(arg, &ioctlvalue, sizeof(int));
> break;
> case SETVALUE: // read "ioctlvalue" from user
> if (user_info) {
> if (!rtdm_read_user_ok(user_info, arg, sizeof(int)) ||
> rtdm_copy_from_user(user_info, &ioctlvalue, arg,
> sizeof(int)))
> return -EFAULT;
> }
> break;
> default:
> ret = -ENOTTY;
> }
> return ret;
> }
>
> /**********************************************************/
> /* DRIVER READ */
> /**********************************************************/
> int demo_read_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info, void *buf, size_t nbyte)
> {
> struct demodrv_context *ctx;
> int dev_id;
> // rtdm_lockctx_t lock_ctx;
> char *out_pos = (char *)buf;
> rtdm_toseq_t timeout_seq;
> int ret;
>
> // zero bytes requested ? return!
> if (nbyte == 0)
> return 0;
>
> // check if R/W actions to user-space are allowed
> if (user_info && !rtdm_rw_user_ok(user_info, buf, nbyte))
> return -EFAULT;
>
> ctx = (struct demodrv_context *)context->dev_private;
> dev_id = ctx->dev_id;
>
> // in case we need to check if reading is allowed (locking)
> /* if (test_and_set_bit(0, &ctx->in_lock))
> return -EBUSY;
> */
> /* // if we need to do some stuff with preemption disabled:
> rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
> // stuff here
> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
> */
>
> // wait: if ctx->timeout = 0, it will block infintely until
> // rtdm_event_signal(&ctx->irq_event); is called from our
> // interrupt routine
> ret = rtdm_event_timedwait(&ctx->irq_event, ctx->timeout,
> &timeout_seq);
>
> // now write the requested stuff to user-space
> if (rtdm_copy_to_user(user_info, out_pos,
> dummy_buffer, BUFSIZE) != 0) {
> ret = -EFAULT;
> } else {
> ret = BUFSIZE;
> }
> return ret;
> }
>
> /**********************************************************/
> /* DRIVER WRITE */
> /**********************************************************/
> int demo_write_rt(struct rtdm_dev_context *context,
> rtdm_user_info_t *user_info,
> const void *buf, size_t nbyte)
> {
> struct demodrv_context *ctx;
> int dev_id;
> char *in_pos = (char *)buf;
> int ret;
>
> if (nbyte == 0)
> return 0;
> if (user_info && !rtdm_read_user_ok(user_info, buf, nbyte))
> return -EFAULT;
>
> ctx = (struct demodrv_context *)context->dev_private;
> dev_id = ctx->dev_id;
>
> // make write operation atomic
> /* ret = rtdm_mutex_timedlock(&ctx->out_lock,
> ctx->config.rx_timeout, &timeout_seq);
> if (ret)
> return ret; */
>
> /* // if we need to do some stuff with preemption disabled:
> rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
> // stuff here
> rtdm_lock_put_irqrestore(&ctx->lock, lock_ctx);
> */
>
> // now copy the stuff from user-space to our kernel dummy_buffer
> if (rtdm_copy_from_user(user_info, dummy_buffer,in_pos, BUFSIZE) != 0)
> {
> ret = -EFAULT;
> } else {
> ret = BUFSIZE;
> }
>
> // used when it is atomic
> // rtdm_mutex_unlock(&ctx->out_lock);
> return ret;
> }
>
> /**********************************************************/
> /* DRIVER OPERATIONS */
> /**********************************************************/
> static struct rtdm_device demo_device = {
> struct_version: RTDM_DEVICE_STRUCT_VER,
>
> device_flags: RTDM_NAMED_DEVICE,
> context_size: sizeof(struct demodrv_context),
> device_name: DEV_FILE,
>
> /* open and close functions are not real-time safe due kmalloc
> and kfree. If you do not use kmalloc and kfree, and you made
> sure that there is no syscall in the open/close handler, you
> can declare the open_rt and close_rt handler.
> */
> open_rt: NULL,
> open_nrt: demo_open_rt,
>
> ops: {
> close_rt: NULL,
> close_nrt: demo_close_rt,
>
> ioctl_rt: NULL,
> ioctl_nrt: demo_ioctl_rt, // rtdm_mmap_to_user is not RT safe
>
> read_rt: demo_read_rt,
> read_nrt: NULL,
>
> write_rt: demo_write_rt,
> write_nrt: NULL,
>
> recvmsg_rt: NULL,
> recvmsg_nrt: NULL,
>
> sendmsg_rt: NULL,
> sendmsg_nrt: NULL,
> },
>
> device_class: RTDM_CLASS_EXPERIMENTAL,
> device_sub_class: 222,
> driver_name: DRV_NAME,
> peripheral_name: DEV_FILE_NAME,
> provider_name: "-",
> proc_name: demo_device.device_name,
> };
>
> /**********************************************************/
> /* INIT DRIVER */
> /**********************************************************/
> int init_module(void)
> {
> return rtdm_dev_register(&demo_device);
> }
>
> /**********************************************************/
> /* CLEANUP DRIVER */
> /**********************************************************/
> void cleanup_module(void)
> {
> rtdm_dev_unregister(&demo_device, 1000);
> }
>
> MODULE_LICENSE("GPL");
> MODULE_DESCRIPTION("RTDM Real Time Driver Example");
>
>
> ------------------------------------------------------------------------
>
> #include
> #include
> #include
> #include
>
> #include
> #include
> #include
> #include "inc.h"
>
> unsigned int my_state = 0;
> int timer_started = 0;
> int my_fd = -1;
> int shutdownnow = 0;
> RT_TASK my_task;
> // --s-ms-us-ns
> RTIME my_task_period_ns = 1000000000llu;
>
> #ifdef USEMMAP
> void *mmappointer;
> #endif
>
> /**********************************************************/
> /* CLOSE RT DRIVER */
> /**********************************************************/
> static int close_file( int fd, unsigned char *name) {
> int ret,i=0;
> do {
> i++;
> ret = rt_dev_close(fd);
> switch(-ret){
> case EBADF: printf("%s -> invalid fd or context\n",name);
> break;
> case EAGAIN: printf("%s -> EAGAIN (%d times)\n",name,i);
> rt_task_sleep(50000); // wait 50us
> break;
> case 0: printf("%s -> closed\n",name);
> break;
> default: printf("%s -> ???\n",name);
> break;
> }
> } while (ret == -EAGAIN && i < 10);
> return ret;
> }
>
> /**********************************************************/
> /* CLEANING UP */
> /**********************************************************/
> void cleanup_all(void) {
> if (my_state & STATE_FILE_OPENED) {
> close_file( my_fd, DEV_FILE " (user)");
> my_state &= ~STATE_FILE_OPENED;
> }
> if (my_state & STATE_TASK_CREATED) {
> printf("delete my_task\n");
> rt_task_delete(&my_task);
> my_state &= ~STATE_TASK_CREATED;
> }
> if (timer_started) {
> printf("stop timer\n");
> rt_timer_stop();
> }
> }
>
> void catch_signal(int sig) {
> shutdownnow = 1;
> cleanup_all();
> printf("exit\n");
> return;
> }
>
> /**********************************************************/
> /* REAL TIME TASK */
> /**********************************************************/
> void my_task_proc(void *arg) {
> int ret;
> ssize_t sz = sizeof(RTIME);
> ssize_t written = 0;
> ssize_t read = 0;
> int counter = 0;
> int readbackcounter;
> unsigned char buf[17] = "CAPTAIN WAS HERE\0";
> unsigned char buf2[17] = "XXXXXXXXXXXXXXXX\0";
> /* no periodic task, due blocking read from the RT driver (see below
> too)
> ret = rt_task_set_periodic(NULL, TM_NOW,
> rt_timer_ns2ticks(my_task_period_ns));
> if (ret) {
> printf("error while set periodic, code %d\n",ret);
> goto exit_my_task;
> }
> */
>
> #ifdef USEMMAP
> printf("ioctl = %d\n", rt_dev_ioctl(my_fd, MMAP, &mmappointer));
> printf("*p = %d, p = %p\n", *((int *)mmappointer), mmappointer);
> #endif
>
> while (1) {
> sprintf(buf, "CAPTAIN %d", counter);
> counter++;
> if (counter > 100) counter = 0;
> /* switch to primary mode */
> ret = rt_task_set_mode(0, T_PRIMARY, NULL);
> if (ret) {
> printf("error while rt_task_set_mode, code %d\n",ret);
> goto exit_my_task;
> }
>
> /* // rt_dev_read blocks, so we can't use rt_task_wait_period here,
> // otherwise we get a ETIMEDOUT 110 = Connection timed out
> // after the next rt_task_wait_period
> ret = rt_task_wait_period(NULL);
> if (ret) {
> printf("error while rt_task_wait_period, code %d\n",ret);
> goto exit_my_task;
> }
> */
> sz = sizeof(buf);
> written = rt_dev_write(my_fd, &buf, sizeof(buf));
> printf("WRITE: written=%d sz=%d\n", written, sz);
> if (written != sz ) {
> if (written < 0 ) {
> printf("error while rt_dev_write, code %d\n",written);
> } else {
> printf("only %d / %d byte transmitted\n",written, sz);
> }
> goto exit_my_task;
> }
>
> sz = sizeof(buf2);
> read = rt_dev_read(my_fd, &buf2, sizeof(buf2));
> if (read == sz ) {
> printf("READ: read=%s\n",buf2);
> } else {
> if (read < 0 ) {
> printf("error while rt_dev_read, code %d\n",read);
> } else {
> printf("only %d / %d byte received \n",read,sz);
> }
> }
>
> // read blocks, so check if user hit CTRL-C meanwhile
> // otherwise we segfault when mmap'ing
> if (shutdownnow == 1) break;
>
> #ifdef USEMMAP
> *((int *)mmappointer + 10) = counter + 1000;
> printf("MMAP: *((int *)mmappointer + 10) = %d\n",
> *((int *)mmappointer + 10));
> #endif
>
> rt_dev_ioctl(my_fd, SETVALUE, &counter);
> rt_dev_ioctl(my_fd, GETVALUE, &readbackcounter);
> printf("IOCTL: readbackcounter=%d\n", readbackcounter);
>
>
> }
> exit_my_task:
> if (my_state & STATE_FILE_OPENED) {
> if (!close_file( my_fd, DEV_FILE " (write)")) {
> my_state &= ~STATE_FILE_OPENED;
> }
> }
> printf("exit\n");
> }
>
> /**********************************************************/
> /* MAIN: mainly RT task initialization */
> /**********************************************************/
> int main(int argc, char* argv[]) {
> int ret = 0;
> signal(SIGTERM, catch_signal);
> signal(SIGINT, catch_signal);
>
> printf("PRESS CTRL-C to EXIT\n");
> /* no memory-swapping for this programm */
> mlockall(MCL_CURRENT | MCL_FUTURE);
>
>
> /* open DEV_FILE */
> my_fd = rt_dev_open( DEV_FILE, 0);
> if (my_fd < 0) {
> printf("can't open %s\n", DEV_FILE);
> goto error;
> }
> my_state |= STATE_FILE_OPENED;
> printf("%s opened\n", DEV_FILE);
>
> /* create my_task */
> ret = rt_task_create(&my_task,"my_task",0,50,0);
=== message truncated ===begin:vcard
fn:Markus Franke
n:Franke;Markus
adr;quoted-printable:;;Vettersstra=C3=9Fe 64/722;Chemnitz;Saxony;09126;Germany
email;internet:Markus.Franke@domain.hid
x-mozilla-html:FALSE
url:http://www.tu-chemnitz.de/~franm
version:2.1
end:vcard
---------------------------------
Want to start your own business? Learn how on Yahoo! Small Business.
[-- Attachment #2: Type: text/html, Size: 30828 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Xenomai-help] problem inserting a kernel module
2007-01-19 17:02 ` mani bhatti
@ 2007-01-19 17:52 ` Jan Kiszka
0 siblings, 0 replies; 4+ messages in thread
From: Jan Kiszka @ 2007-01-19 17:52 UTC (permalink / raw)
To: mani bhatti; +Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 700 bytes --]
mani bhatti wrote:
> I have got following message
>
> No module found in object
...
> realtimedriver: Unknown symbol rtdm_event_signal
> realtimedriver: Unknown symbol rtdm_event_timedwait
> realtimedriver: Unknown symbol rtdm_dev_unregister
> realtimedriver: Unknown symbol rtdm_dev_register
>
Hmm, all this "rtdm", hmm, what the heck could this mean?
>
>
> Markus Franke <Markus.Franke@domain.hid> wrote: Well, some symbols which are referenced by your module are not found in
> the kernel. A "dmesg()"-call should provide you some information about
> the missing symbols. Maybe you missed inserting the "RTDM"-kernel module?
But the solution is soooo close...
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-01-19 17:52 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-19 15:24 [Xenomai-help] problem inserting a kernel module mani bhatti
2007-01-19 15:50 ` Markus Franke
2007-01-19 17:02 ` mani bhatti
2007-01-19 17:52 ` Jan Kiszka
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.