From: Markus Franke <Markus.Franke@domain.hid>
To: mani bhatti <imranbashirbhatti@domain.hid>
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] problem inserting a kernel module
Date: Fri, 19 Jan 2007 16:50:23 +0100 [thread overview]
Message-ID: <45B0E8BF.5090705@domain.hid> (raw)
In-Reply-To: <910933.20673.qm@domain.hid>
[-- 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
next prev parent reply other threads:[~2007-01-19 15:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-19 15:24 [Xenomai-help] problem inserting a kernel module mani bhatti
2007-01-19 15:50 ` Markus Franke [this message]
2007-01-19 17:02 ` mani bhatti
2007-01-19 17:52 ` Jan Kiszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45B0E8BF.5090705@domain.hid \
--to=markus.franke@domain.hid \
--cc=imranbashirbhatti@domain.hid \
--cc=xenomai@xenomai.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.