Thanks, Jan. It is fixed after I modified my code as you suggested.

Best Regards,
Haobo Zhang 

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 
Sent: May 11, 2007 12:22 PM
To: Zhang, Haobo
Cc: [email protected]; [EMAIL PROTECTED]
Subject: Re: [Xenomai-help] rtdm_iomap_to_user question

Zhang, Haobo wrote:
> Hi Jan,
> 
> Thank you so much for your reply!
> 
> In my driver, I wrote:
> 
> int map_io( struct gpiodrv_context *dev_context, rtdm_user_info_t 
> *user_info, struct MAPPED_IO *io ) {
>       int ret;
> 
>       if ((dev_context == 0) || (user_info == 0) || (io == 0))
>               return -EFAULT;
> 
>       if (dev_context->mapped_user_info != 0)
>       {
>               if ((ret = gpio_unmap_io( dev_context )) != 0)
>                       return ret;
>       }
> 
>       dev_context->mapped_user_info = user_info;
> 
>       ret = rtdm_iomap_to_user( user_info, MPC52xx_PA( 
> MPC52xx_GPIO_WKUP_OFFSET + 0x0C ),
>               1, PROT_READ | PROT_WRITE, (void
> **)&(io->gpio_heart_beat), NULL, NULL );

Hmm, hmm. Looking at our code and the kernel again I would say we should
catch non-page-aligned requests like this and document this pitfall
better.

The mapping code always assumes page-alignment and rounds your physical
address down. So what likely happened here is that you got a mapping,
but with unexpected offset (gpio_heart_beat should point to MPC52xx_PA).

>       
>       if (ret != 0)
>               goto __ERROR;
>       else
>               dev_context->mapped_heart_beat = (void
*)io->gpio_heart_beat;
> 
>       return 0;
> 
> __ERROR:
> 
>       gpio_unmap_io( dev_context );
>       return ret;
> }
> 
> In the application, I wrote:
> 
> int main(int argc, char *argv[])
> {
>       int dev_gpio;
>       struct MAPPED_IO gpio;
> 
>       signal(SIGTERM, clean_exit);    
>       signal(SIGINT, clean_exit);     
>       
>       mlockall( MCL_CURRENT | MCL_FUTURE );
> 
>       rt_task_shadow( &mainapp, "mainapp", 1, 0 );
> 
>       dev_gpio = rt_dev_open( "gpio", 0 );
>       if (dev_gpio < 0)
>       {
>               return -1;
>       }
>       
>       gpio.gpio_heart_beat = NULL;
> 
>       if (rt_dev_ioctl( dev_gpio, 1, &gpio ) != 0)
>       {
>               return -1;
>       }
> 
>       gpio.gpio_heart_beat[0] = 0x01;
> 
>       ...
> }
> 
> I also tried another way by opening "/dev/mem" and then using "mmap" 
> to map the I/O memory addresses in the application. It worked!
> I am very curious about why "rtdm_iomap_to_user" did not work for me. 

When you do precisely the same odd-numbered mapping via mmap on
/dev/mem, you do get the right address at gpio_heart_beat (check if the
start address ends with 0x0b0c)?

We either have to improve rtdm_iomap/mmap_to_user in this regard or
catch unaligned requests. Probably it's easier to catch it so that the
driver writer also realises that this is always about mapping full
pages...

Jan


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

Reply via email to