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
> [email protected]
> https://mail.gna.org/listinfo/xenomai-help

-- 
Nichts ist so praktisch wie eine gute Theorie!
begin:vcard
fn:Markus Franke
n:Franke;Markus
adr;quoted-printable:;;Vettersstra=C3=9Fe 64/722;Chemnitz;Saxony;09126;Germany
email;internet:[EMAIL PROTECTED]
x-mozilla-html:FALSE
url:http://www.tu-chemnitz.de/~franm
version:2.1
end:vcard

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

Reply via email to