All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Trouble with rtdm timers and events
@ 2011-08-10 17:49 Carlos Eduardo de Brito Novaes
  2011-08-10 19:57 ` Carlos Eduardo de Brito Novaes
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-10 17:49 UTC (permalink / raw)
  To: xenomai

Hello to all,

I am learning how to use rtdm_timer and also rtdm_event to use on acquisition 
board. The board itself has a FIFO and can be configurated do fill it in a 
predefined time. The problem is that there is no interrupt generated when the 
FIFO is full or on a given number of samples, so I have to poll the data.

As the conversion time is know (based on board latency, conversion time and 
number os channels to scan), a better approach would be let the board do its 
conversion and at given times, where the data should be ready on FIFO (and 
also, the FIFO is far large than the amount of data retrieved) and then, get 
it, setup a new delay based on the estimated remaining data for the next scan, 
fire an event to unblock an read operation and loop the entire proccess 
again...
Also, there is an user space real time application that will open the rtdm 
device, issue some configurations via ioctl and loop reading the device.

The code specific to timming is working almost as good, I can see the app 
returning a increasing counter by the time it is running. The only issue is 
that the CPU hangs if I try to remove the module or run the app one second 
time (or if I close and then reopen the device)
Any call to configure the rtdm_event  will hang the CPU.

Hope you can give some appointments or tell me what I am doing wrong.
Here is the relevant sections of code, only code specific to xenomai and 
related with the issues.

--- For the app
int main(int argc, char **argv)
{
  int device;
  int ret;
  int32_t sample_number;
  
  ret = mlockall(MCL_CURRENT | MCL_FUTURE);...
  ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);...
  
  sample_number = 0;
  //Open
  device = rt_dev_open(DEVICE_NAME, 0);....

  // IOCTL Start
  ret = rt_dev_ioctl(device, 0x07);...
  
  sleep(3);
  // Read
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  sleep(3);
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  sleep(3);
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  sleep(2);
  ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
  printf("Read %d. Sample %d\n", ret, sample_number);
  
    // IOCTL Stop
  ret = ioctl(device, 0x08);...

  /* close the device */
  ret = rt_dev_close(device);...  
  return 0;
}

---

--- For the Driver
...
static struct rtdm_device RtdmDevice = {
        .struct_version = RTDM_DEVICE_STRUCT_VER,
        .device_flags = RTDM_NAMED_DEVICE,
        .context_size = 0,
        .device_name = DEVICE_NAME,

        .open_nrt = pci18xx_rtdm_open,
        .open_rt  = pci18xx_rtdm_open,


        .ops = {
                .close_nrt = pci18xx_rtdm_close,
                .close_rt  = pci18xx_rtdm_close,
                .read_rt   = pci18xx_rtdm_read_rt,
                .read_nrt   = pci18xx_rtdm_read_rt,
                .write_rt  = pci18xx_rtdm_write_rt,
                .ioctl_rt  = pci18xx_rtdm_ioctl_nrt,
                .ioctl_nrt = pci18xx_rtdm_ioctl_nrt,
        },

        .device_class = RTDM_CLASS_EXPERIMENTAL,
        .device_sub_class = SOME_SUB_CLASS,
        .profile_version = 1,
        .driver_name = DRIVER_NAME,
        .driver_version = RTDM_DRIVER_VER(0, 1, 2),
        .peripheral_name = "Icpdas Daq18xx Board",
        .provider_name = "Carlos Novaes",
        .proc_name = RtdmDevice.device_name,
        .device_id = -1,
};...
...
static int              pci18xx_rtdm_ioctl_nrt(struct rtdm_dev_context 
*context, rtdm_user_info_t *user_info, unsigned int request, void __user *arg)
{
  pci18xx_context_t     *ctx;
  int                   err;
  
  err = 0;
  rtdm_printk("IOCTL Device NRT. Request = %d\n", request);

  ctx = (pci18xx_context_t *)context->dev_private;
  switch (request){
    case IOCTL_START:
      err = pci18xx_start(context, ctx, user_info, arg);
      break;
    case IOCTL_STOP:
      err = pci18xx_stop(ctx, user_info, arg);
      break;
    default:
      return PCI18XX_E_INVALID_IOCTL;
  }
  return PCI18XX_OK;
};...
...
static ssize_t          pci18xx_rtdm_read_rt(struct rtdm_dev_context *context, 
rtdm_user_info_t * user_info, void *buf, size_t nbyte){
  int16_t size;
  int32_t value;
  int err;  
 
  pci18xx_context_t *ctx;
  // following line fails
  //err = rtdm_event_timedwait(&ctx->RtdmReadyEvent,2000000000, NULL);
  
  ctx = (pci18xx_context_t *) context->dev_private;
  size=sizeof(ctx->SampleNumber);
  
  if (rtdm_safe_copy_to_user(user_info, buf, &(ctx->SampleNumber), size)){...
  return size;
};...
...
static int              pci18xx_start(struct rtdm_dev_context *context, 
pci18xx_context_t *ctx, rtdm_user_info_t *user_info, void __user *arg){
  rtdm_timer_init(&ctx->RtdmTimer, pci18xx_timer_proc, context->device-
>device_name);
  // following line fail
  //rtdm_event_init(&ctx->RtdmReadyEvent, 0);
  ctx->Running=1;
  ctx->SampleNumber=0;
  ctx->time = rtdm_clock_read_monotonic();
  ctx->time += 1000000000;
  rtdm_timer_start(&ctx->RtdmTimer, ctx->time, 0, RTDM_TIMERMODE_ABSOLUTE);
  return 0;
};
static int              pci18xx_stop(pci18xx_context_t *ctx, rtdm_user_info_t 
*user_info, void __user *arg){
  rtdm_printk("stop function\n");
  if (ctx->Running){
    ctx->Running=0;
    // following line fail
    //rtdm_event_destroy(&ctx->RtdmReadyEvent);
    rtdm_timer_destroy(&ctx->RtdmTimer);    
  }
  return 0;
};
static void             pci18xx_timer_proc(rtdm_timer_t *timer){
  pci18xx_context_t *ctx;
  int err;
  ctx = container_of(timer, pci18xx_context_t, RtdmTimer);
  ctx->SampleNumber++;
  ctx->time += 1000000000;
  err = rtdm_timer_start_in_handler(&ctx->RtdmTimer, ctx->time, 0, 
RTDM_TIMERMODE_ABSOLUTE);
  // following line fail
  //rtdm_event_pulse(&ctx->RtdmReadyEvent);
};
---


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-10 17:49 [Xenomai-help] Trouble with rtdm timers and events Carlos Eduardo de Brito Novaes
@ 2011-08-10 19:57 ` Carlos Eduardo de Brito Novaes
  2011-08-10 21:10   ` Carlos Eduardo de Brito Novaes
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-10 19:57 UTC (permalink / raw)
  To: xenomai

Sorry, the timer questio is solved, its a wrong call to unix ioctl instead of 
real time version from xenomai. By now I can initialize and even fire events, 
start the app again and again and also load/unload/reload the module without 
errors. The only problem seens to be related with the line
ret = rtdm_event_timedwait(&ctx->RtdmReadyEvent,2000000000, &timeout_seq);
on the read operation. If I uncomment it the first call to read will hang the 
entire CPU. I also changed it to include an timeout sequence with no sucess.
By now, it seens that I have misundertood something. Maybe someone can poit it 
out.

Thanks

--
Carlos Novaes.


Em qua 10 ago 2011, às 14:49:53, Carlos Eduardo de Brito Novaes escreveu:
> Hello to all,
> 
> I am learning how to use rtdm_timer and also rtdm_event to use on
> acquisition board. The board itself has a FIFO and can be configurated do
> fill it in a predefined time. The problem is that there is no interrupt
> generated when the FIFO is full or on a given number of samples, so I have
> to poll the data.
> 
> As the conversion time is know (based on board latency, conversion time and
> number os channels to scan), a better approach would be let the board do
> its conversion and at given times, where the data should be ready on FIFO
> (and also, the FIFO is far large than the amount of data retrieved) and
> then, get it, setup a new delay based on the estimated remaining data for
> the next scan, fire an event to unblock an read operation and loop the
> entire proccess again...
> Also, there is an user space real time application that will open the rtdm
> device, issue some configurations via ioctl and loop reading the device.
> 
> The code specific to timming is working almost as good, I can see the app
> returning a increasing counter by the time it is running. The only issue is
> that the CPU hangs if I try to remove the module or run the app one second
> time (or if I close and then reopen the device)
> Any call to configure the rtdm_event  will hang the CPU.
> 
> Hope you can give some appointments or tell me what I am doing wrong.
> Here is the relevant sections of code, only code specific to xenomai and
> related with the issues.
> 
> --- For the app
> int main(int argc, char **argv)
> {
>   int device;
>   int ret;
>   int32_t sample_number;
> 
>   ret = mlockall(MCL_CURRENT | MCL_FUTURE);...
>   ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);...
> 
>   sample_number = 0;
>   //Open
>   device = rt_dev_open(DEVICE_NAME, 0);....
> 
>   // IOCTL Start
>   ret = rt_dev_ioctl(device, 0x07);...
> 
>   sleep(3);
>   // Read
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
>   sleep(3);
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
>   sleep(3);
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
>   sleep(2);
>   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
>   printf("Read %d. Sample %d\n", ret, sample_number);
> 
>     // IOCTL Stop
>   ret = ioctl(device, 0x08);...
> 
>   /* close the device */
>   ret = rt_dev_close(device);...
>   return 0;
> }
> 
> ---
> 
> --- For the Driver
> ...
> static struct rtdm_device RtdmDevice = {
>         .struct_version = RTDM_DEVICE_STRUCT_VER,
>         .device_flags = RTDM_NAMED_DEVICE,
>         .context_size = 0,
>         .device_name = DEVICE_NAME,
> 
>         .open_nrt = pci18xx_rtdm_open,
>         .open_rt  = pci18xx_rtdm_open,
> 
> 
>         .ops = {
>                 .close_nrt = pci18xx_rtdm_close,
>                 .close_rt  = pci18xx_rtdm_close,
>                 .read_rt   = pci18xx_rtdm_read_rt,
>                 .read_nrt   = pci18xx_rtdm_read_rt,
>                 .write_rt  = pci18xx_rtdm_write_rt,
>                 .ioctl_rt  = pci18xx_rtdm_ioctl_nrt,
>                 .ioctl_nrt = pci18xx_rtdm_ioctl_nrt,
>         },
> 
>         .device_class = RTDM_CLASS_EXPERIMENTAL,
>         .device_sub_class = SOME_SUB_CLASS,
>         .profile_version = 1,
>         .driver_name = DRIVER_NAME,
>         .driver_version = RTDM_DRIVER_VER(0, 1, 2),
>         .peripheral_name = "Icpdas Daq18xx Board",
>         .provider_name = "Carlos Novaes",
>         .proc_name = RtdmDevice.device_name,
>         .device_id = -1,
> };...
> ...
> static int              pci18xx_rtdm_ioctl_nrt(struct rtdm_dev_context
> *context, rtdm_user_info_t *user_info, unsigned int request, void __user
> *arg) {
>   pci18xx_context_t     *ctx;
>   int                   err;
> 
>   err = 0;
>   rtdm_printk("IOCTL Device NRT. Request = %d\n", request);
> 
>   ctx = (pci18xx_context_t *)context->dev_private;
>   switch (request){
>     case IOCTL_START:
>       err = pci18xx_start(context, ctx, user_info, arg);
>       break;
>     case IOCTL_STOP:
>       err = pci18xx_stop(ctx, user_info, arg);
>       break;
>     default:
>       return PCI18XX_E_INVALID_IOCTL;
>   }
>   return PCI18XX_OK;
> };...
> ...
> static ssize_t          pci18xx_rtdm_read_rt(struct rtdm_dev_context
> *context, rtdm_user_info_t * user_info, void *buf, size_t nbyte){
>   int16_t size;
>   int32_t value;
>   int err;
> 
>   pci18xx_context_t *ctx;
>   // following line fails
>   //err = rtdm_event_timedwait(&ctx->RtdmReadyEvent,2000000000, NULL);
> 
>   ctx = (pci18xx_context_t *) context->dev_private;
>   size=sizeof(ctx->SampleNumber);
> 
>   if (rtdm_safe_copy_to_user(user_info, buf, &(ctx->SampleNumber),
> size)){... return size;
> };...
> ...
> static int              pci18xx_start(struct rtdm_dev_context *context,
> pci18xx_context_t *ctx, rtdm_user_info_t *user_info, void __user *arg){
>   rtdm_timer_init(&ctx->RtdmTimer, pci18xx_timer_proc, context->device-
> 
> >device_name);
> 
>   // following line fail
>   //rtdm_event_init(&ctx->RtdmReadyEvent, 0);
>   ctx->Running=1;
>   ctx->SampleNumber=0;
>   ctx->time = rtdm_clock_read_monotonic();
>   ctx->time += 1000000000;
>   rtdm_timer_start(&ctx->RtdmTimer, ctx->time, 0, RTDM_TIMERMODE_ABSOLUTE);
>   return 0;
> };
> static int              pci18xx_stop(pci18xx_context_t *ctx,
> rtdm_user_info_t *user_info, void __user *arg){
>   rtdm_printk("stop function\n");
>   if (ctx->Running){
>     ctx->Running=0;
>     // following line fail
>     //rtdm_event_destroy(&ctx->RtdmReadyEvent);
>     rtdm_timer_destroy(&ctx->RtdmTimer);
>   }
>   return 0;
> };
> static void             pci18xx_timer_proc(rtdm_timer_t *timer){
>   pci18xx_context_t *ctx;
>   int err;
>   ctx = container_of(timer, pci18xx_context_t, RtdmTimer);
>   ctx->SampleNumber++;
>   ctx->time += 1000000000;
>   err = rtdm_timer_start_in_handler(&ctx->RtdmTimer, ctx->time, 0,
> RTDM_TIMERMODE_ABSOLUTE);
>   // following line fail
>   //rtdm_event_pulse(&ctx->RtdmReadyEvent);
> };
> ---


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-10 19:57 ` Carlos Eduardo de Brito Novaes
@ 2011-08-10 21:10   ` Carlos Eduardo de Brito Novaes
  2011-08-11  7:39     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-10 21:10 UTC (permalink / raw)
  To: xenomai

Hello again.
I traced the errors down and now dicovered that calling printf (as it would 
be) turns a real time task in a non real time one. so I chaged the code and it 
is almost working as expected, except for something that now seens to be some 
kind of bug. If I use any sord of rtdm_event_[timed,]wait, the app returns and 
there is a trace on kernel about a null pointer, just after the call to wait. 
It seens similar with
<http://www.mail-archive.com/xenomai@xenomai.org>
And I there is no other references on google. So I will try to recompile with 
some changes and maybe test with another kernel. Hope you can point something
I am running in a AMD Athlon(tm) 64 X2 Dual Core Processor 4000+, kernel 
2.6.38-8, ubuntu natty 11.04 and latest stable xenomai source.
If it will help, I can send the code.

Thanks.

--
Carlos Novaes.

Em qua 10 ago 2011, às 16:57:57, Carlos Eduardo de Brito Novaes escreveu:
> Sorry, the timer questio is solved, its a wrong call to unix ioctl instead
> of real time version from xenomai. By now I can initialize and even fire
> events, start the app again and again and also load/unload/reload the
> module without errors. The only problem seens to be related with the line
> ret = rtdm_event_timedwait(&ctx->RtdmReadyEvent,2000000000, &timeout_seq);
> on the read operation. If I uncomment it the first call to read will hang
> the entire CPU. I also changed it to include an timeout sequence with no
> sucess. By now, it seens that I have misundertood something. Maybe someone
> can poit it out.
> 
> Thanks
> 
> --
> Carlos Novaes.
> 
> Em qua 10 ago 2011, às 14:49:53, Carlos Eduardo de Brito Novaes escreveu:
> > Hello to all,
> > 
> > I am learning how to use rtdm_timer and also rtdm_event to use on
> > acquisition board. The board itself has a FIFO and can be configurated do
> > fill it in a predefined time. The problem is that there is no interrupt
> > generated when the FIFO is full or on a given number of samples, so I
> > have to poll the data.
> > 
> > As the conversion time is know (based on board latency, conversion time
> > and number os channels to scan), a better approach would be let the
> > board do its conversion and at given times, where the data should be
> > ready on FIFO (and also, the FIFO is far large than the amount of data
> > retrieved) and then, get it, setup a new delay based on the estimated
> > remaining data for the next scan, fire an event to unblock an read
> > operation and loop the entire proccess again...
> > Also, there is an user space real time application that will open the
> > rtdm device, issue some configurations via ioctl and loop reading the
> > device.
> > 
> > The code specific to timming is working almost as good, I can see the app
> > returning a increasing counter by the time it is running. The only issue
> > is that the CPU hangs if I try to remove the module or run the app one
> > second time (or if I close and then reopen the device)
> > Any call to configure the rtdm_event  will hang the CPU.
> > 
> > Hope you can give some appointments or tell me what I am doing wrong.
> > Here is the relevant sections of code, only code specific to xenomai and
> > related with the issues.
> > 
> > --- For the app
> > int main(int argc, char **argv)
> > {
> > 
> >   int device;
> >   int ret;
> >   int32_t sample_number;
> >   
> >   ret = mlockall(MCL_CURRENT | MCL_FUTURE);...
> >   ret = rt_task_shadow(&rt_task_desc, NULL, 1, 0);...
> >   
> >   sample_number = 0;
> >   //Open
> >   device = rt_dev_open(DEVICE_NAME, 0);....
> >   
> >   // IOCTL Start
> >   ret = rt_dev_ioctl(device, 0x07);...
> >   
> >   sleep(3);
> >   // Read
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   sleep(3);
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   sleep(3);
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   sleep(2);
> >   ret = rt_dev_read (device, &sample_number, sizeof(sample_number));
> >   printf("Read %d. Sample %d\n", ret, sample_number);
> >   
> >     // IOCTL Stop
> >   
> >   ret = ioctl(device, 0x08);...
> >   
> >   /* close the device */
> >   ret = rt_dev_close(device);...
> >   return 0;
> > 
> > }
> > 
> > ---
> > 
> > --- For the Driver
> > ...
> > static struct rtdm_device RtdmDevice = {
> > 
> >         .struct_version = RTDM_DEVICE_STRUCT_VER,
> >         .device_flags = RTDM_NAMED_DEVICE,
> >         .context_size = 0,
> >         .device_name = DEVICE_NAME,
> >         
> >         .open_nrt = pci18xx_rtdm_open,
> >         .open_rt  = pci18xx_rtdm_open,
> >         
> >         
> >         .ops = {
> >         
> >                 .close_nrt = pci18xx_rtdm_close,
> >                 .close_rt  = pci18xx_rtdm_close,
> >                 .read_rt   = pci18xx_rtdm_read_rt,
> >                 .read_nrt   = pci18xx_rtdm_read_rt,
> >                 .write_rt  = pci18xx_rtdm_write_rt,
> >                 .ioctl_rt  = pci18xx_rtdm_ioctl_nrt,
> >                 .ioctl_nrt = pci18xx_rtdm_ioctl_nrt,
> >         
> >         },
> >         
> >         .device_class = RTDM_CLASS_EXPERIMENTAL,
> >         .device_sub_class = SOME_SUB_CLASS,
> >         .profile_version = 1,
> >         .driver_name = DRIVER_NAME,
> >         .driver_version = RTDM_DRIVER_VER(0, 1, 2),
> >         .peripheral_name = "Icpdas Daq18xx Board",
> >         .provider_name = "Carlos Novaes",
> >         .proc_name = RtdmDevice.device_name,
> >         .device_id = -1,
> > 
> > };...
> > ...
> > static int              pci18xx_rtdm_ioctl_nrt(struct rtdm_dev_context
> > *context, rtdm_user_info_t *user_info, unsigned int request, void __user
> > *arg) {
> > 
> >   pci18xx_context_t     *ctx;
> >   int                   err;
> >   
> >   err = 0;
> >   rtdm_printk("IOCTL Device NRT. Request = %d\n", request);
> >   
> >   ctx = (pci18xx_context_t *)context->dev_private;
> >   switch (request){
> >   
> >     case IOCTL_START:
> >       err = pci18xx_start(context, ctx, user_info, arg);
> >       break;
> >     
> >     case IOCTL_STOP:
> >       err = pci18xx_stop(ctx, user_info, arg);
> >       break;
> >     
> >     default:
> >       return PCI18XX_E_INVALID_IOCTL;
> >   
> >   }
> >   return PCI18XX_OK;
> > 
> > };...
> > ...
> > static ssize_t          pci18xx_rtdm_read_rt(struct rtdm_dev_context
> > *context, rtdm_user_info_t * user_info, void *buf, size_t nbyte){
> > 
> >   int16_t size;
> >   int32_t value;
> >   int err;
> >   
> >   pci18xx_context_t *ctx;
> >   // following line fails
> >   //err = rtdm_event_timedwait(&ctx->RtdmReadyEvent,2000000000, NULL);
> >   
> >   ctx = (pci18xx_context_t *) context->dev_private;
> >   size=sizeof(ctx->SampleNumber);
> >   
> >   if (rtdm_safe_copy_to_user(user_info, buf, &(ctx->SampleNumber),
> > 
> > size)){... return size;
> > };...
> > ...
> > static int              pci18xx_start(struct rtdm_dev_context *context,
> > pci18xx_context_t *ctx, rtdm_user_info_t *user_info, void __user *arg){
> > 
> >   rtdm_timer_init(&ctx->RtdmTimer, pci18xx_timer_proc, context->device-
> > >
> > >device_name);
> > >
> >   // following line fail
> >   //rtdm_event_init(&ctx->RtdmReadyEvent, 0);
> >   ctx->Running=1;
> >   ctx->SampleNumber=0;
> >   ctx->time = rtdm_clock_read_monotonic();
> >   ctx->time += 1000000000;
> >   rtdm_timer_start(&ctx->RtdmTimer, ctx->time, 0,
> >   RTDM_TIMERMODE_ABSOLUTE); return 0;
> > 
> > };
> > static int              pci18xx_stop(pci18xx_context_t *ctx,
> > rtdm_user_info_t *user_info, void __user *arg){
> > 
> >   rtdm_printk("stop function\n");
> >   if (ctx->Running){
> >   
> >     ctx->Running=0;
> >     // following line fail
> >     //rtdm_event_destroy(&ctx->RtdmReadyEvent);
> >     rtdm_timer_destroy(&ctx->RtdmTimer);
> >   
> >   }
> >   return 0;
> > 
> > };
> > static void             pci18xx_timer_proc(rtdm_timer_t *timer){
> > 
> >   pci18xx_context_t *ctx;
> >   int err;
> >   ctx = container_of(timer, pci18xx_context_t, RtdmTimer);
> >   ctx->SampleNumber++;
> >   ctx->time += 1000000000;
> >   err = rtdm_timer_start_in_handler(&ctx->RtdmTimer, ctx->time, 0,
> > 
> > RTDM_TIMERMODE_ABSOLUTE);
> > 
> >   // following line fail
> >   //rtdm_event_pulse(&ctx->RtdmReadyEvent);
> > 
> > };
> > ---


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-10 21:10   ` Carlos Eduardo de Brito Novaes
@ 2011-08-11  7:39     ` Gilles Chanteperdrix
  2011-08-11 14:31       ` Carlos Eduardo de Brito Novaes
  0 siblings, 1 reply; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-08-11  7:39 UTC (permalink / raw)
  To: Carlos Eduardo de Brito Novaes; +Cc: xenomai

On 08/10/2011 11:10 PM, Carlos Eduardo de Brito Novaes wrote:
> Hello again.
> I traced the errors down and now dicovered that calling printf (as it would 
> be) turns a real time task in a non real time one. so I chaged the code and it 
> is almost working as expected, except for something that now seens to be some 
> kind of bug. If I use any sord of rtdm_event_[timed,]wait, the app returns and 
> there is a trace on kernel about a null pointer, just after the call to wait. 
> It seens similar with
> <http://www.mail-archive.com/xenomai@xenomai.org>
> And I there is no other references on google. So I will try to recompile with 
> some changes and maybe test with another kernel. Hope you can point something
> I am running in a AMD Athlon(tm) 64 X2 Dual Core Processor 4000+, kernel 
> 2.6.38-8, ubuntu natty 11.04 and latest stable xenomai source.
> If it will help, I can send the code.

Please try and reduce the code to a simple, self-contained test case
which we can run to reproduce the issue. It is the only way we can help.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11  7:39     ` Gilles Chanteperdrix
@ 2011-08-11 14:31       ` Carlos Eduardo de Brito Novaes
  2011-08-11 15:00         ` Gilles Chanteperdrix
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-11 14:31 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

[-- Attachment #1: Type: Text/Plain, Size: 7751 bytes --]

Here it comes.
I found out that if wait is called inside an IOCTL, there is no hangs at all, 
everything work as expected, except from te fact that it seens a litle bit 
strange (to me) to use ioctl to read or write, I would expect to use the 
correspondent rad and write functions and ioctl to setup something.
I tried to reduce the code, in the tarball there are one Makefile, one c file 
for the module and one c file for the app. There is one define line on the 
module file, comment it ou to get the hangs. The app will simply open the 
device, issue an wait ioctl (dummy if the module is compiled to wait in 
read_rt) and the do the actual reading (it hangs on my system if i tell the 
module to wait on the read_rt function).

Here comes the kernel log from one run that does the error but fortunately 
does not hang the entire system.

[  208.986250] Xenomai: RTDM: RT open handler is deprecated, driver requires 
update.
[  208.986256] Xenomai: RTDM: RT close handler is deprecated, driver requires 
update.
[  215.500264] Open Device RT
[  215.500268] rtdm_timer_start returned 0
[  215.500270] IOCTL Device RT. Request = 9
[  215.600264] timer proc function
[  215.600268] rtdm_timer_start_in_handler returned 0
[  215.600270] Read Device RT
[  215.600272] IOCTL Device RT. Request = 9
[  215.700243] timer proc function
[  215.700246] rtdm_timer_start_in_handler returned 0
[  215.700248] Read Device RT
[  215.700250] IOCTL Device RT. Request = 9
[  215.800223] timer proc function
[  215.800227] rtdm_timer_start_in_handler returned 0
[  215.800229] Read Device RT
[  215.800230] IOCTL Device RT. Request = 9
[  215.900205] timer proc function
[  215.900209] rtdm_timer_start_in_handler returned 0
[  215.900211] Read Device RT
[  215.900213] IOCTL Device RT. Request = 9
[  216.000190] timer proc function
[  216.000194] rtdm_timer_start_in_handler returned 0
[  216.000196] Read Device RT
[  216.000197] IOCTL Device RT. Request = 9
[  216.100165] timer proc function
[  216.100170] rtdm_timer_start_in_handler returned 0
[  216.100172] Read Device RT
[  216.100173] IOCTL Device RT. Request = 9
[  216.200169] timer proc function
[  216.200174] rtdm_timer_start_in_handler returned 0
[  216.200176] Read Device RT
[  216.200177] Close Device RT
[  235.671035] Xenomai: RTDM: RT open handler is deprecated, driver requires 
update.
[  235.671041] Xenomai: RTDM: RT close handler is deprecated, driver requires 
update.
[  237.814763] Open Device RT
[  237.814767] rtdm_timer_start returned 0
[  237.814769] IOCTL Device RT. Request = 9
[  237.814771] Read Device RT
[  237.814803] BUG: unable to handle kernel NULL pointer dereference at 
00000000000000c0
[  237.814808] IP: [<ffffffff811408b8>] rtdm_event_timedwait+0x78/0x1a0
[  237.814819] PGD 4557e067 PUD 4f8e1067 PMD 0 
[  237.814823] Oops: 0000 [#1] SMP 
[  237.814827] last sysfs file: 
/sys/devices/pci0000:00/0000:00:0d.0/0000:04:00.0/local_cpus
[  237.814831] CPU 0 
[  237.814834] Modules linked in: testcase_wait_hang binfmt_misc rfcomm sco 
bnep l2cap dm_crypt snd_hda_codec_realtek vmnet vmblock vsock vmci vmmon ppdev 
snd_hda_intel snd_usb_audio snd_usbmidi_lib snd_hda_codec snd_hwdep snd_pcm 
snd_seq_midi snd_seq_midi_event snd_seq snd_rawmidi amd64_edac_mod btusb 
edac_core uvcvideo bluetooth videodev v4l2_compat_ioctl32 snd_timer 
snd_seq_device parport_pc psmouse k8temp asus_atk0110 snd serio_raw 
i2c_nforce2 edac_mce_amd soundcore snd_page_alloc lp parport uvesafb forcedeth 
ahci libahci pata_amd [last unloaded: testcase_wait_hang]
[  237.814878] 
[  237.814881] Pid: 4553, comm: testcase_wait_h Not tainted 2.6.38.8-
xenomai-01 #1 System manufacturer System Product Name/M2N-X
[  237.814888] RIP: 0010:[<ffffffff811408b8>]  [<ffffffff811408b8>] 
rtdm_event_timedwait+0x78/0x1a0
[  237.814894] RSP: 0018:ffff88003a207d28  EFLAGS: 00010246
[  237.814897] RAX: 00000000ffffffff RBX: 0000000000000000 RCX: 000000000000001f
[  237.814900] RDX: 0000000000000000 RSI: 000000003b9aca00 RDI: 
00000000000000a8
[  237.814903] RBP: ffff88003a207d68 R08: 00007f0905e3a238 R09: 00007fff9f313e50
[  237.814906] R10: 00007fff9f314480 R11: 0000000000000206 R12: 
00000000000000a8
[  237.814909] R13: 000000000000ea60 R14: 0000000000000028 R15: ffff88003a207d80
[  237.814913] FS:  00007f0906864720(0000) GS:ffff88007fc00000(0000) 
knlGS:00000000f5fb6710
[  237.814916] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  237.814919] CR2: 00000000000000c0 CR3: 0000000079773000 CR4: 
00000000000006f0
[  237.814922] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 
0000000000000000
[  237.814925] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  237.814929] Process testcase_wait_h (pid: 4553, threadinfo ffff88003a204000, 
task ffff880041a98000)
[  237.814935] Stack:
[  237.814937]  00007fff9f314720 0000000000000028 ffff88003a207d48 
00007fff9f314720
[  237.814942]  ffffc90010909600 00007fff9f314720 0000000000000028 ffff880041a98000
[  237.814947]  ffff88003a207d98 ffffffffa0297135 ffff88003a207f58 0000003a8b52e88e
[  237.814952] Call Trace:
[  237.814959]  [<ffffffffa0297135>] testcase_read_rt+0x45/0x90 
[testcase_wait_hang]
[  237.814964]  [<ffffffff8113dd1a>] __rt_dev_read+0x6a/0xc0
[  237.814968]  [<ffffffff81141266>] sys_rtdm_read+0x26/0x30
[  237.814972]  [<ffffffff81109688>] hisyscall_event+0x1e8/0x4c0
[  237.814978]  [<ffffffff81310e90>] ? rb_insert_color+0x110/0x150
[  237.814983]  [<ffffffff810c5bed>] __ipipe_dispatch_event+0x11d/0x1e0
[  237.814989]  [<ffffffff8101eebf>] __ipipe_syscall_root+0x5f/0x140
[  237.814995]  [<ffffffff815c42c1>] __ipipe_syscall_root_thunk+0x35/0x6a
[  237.815001]  [<ffffffff81002ec4>] ? system_call_after_swapgs+0x54/0x79
[  237.815004] Code: 8f 00 83 e3 01 65 8b 14 25 30 c6 00 00 39 c2 0f 84 8e 00 
00 00 b8 ff ff ff ff f0 0f b1 15 31 22 8f 00 83 f8 ff 0f 85 fd 00 00 00 <49> 8b 44 
24 18 a9 00 00 00 01 0f 85 e2 00 00 00 a9 00 00 00 02 
[  237.815049] RIP  [<ffffffff811408b8>] rtdm_event_timedwait+0x78/0x1a0
[  237.815053]  RSP <ffff88003a207d28>
[  237.815055] CR2: 00000000000000c0
[  237.815059] ---[ end trace af39d7f5f5df4bfd ]---
[  237.823941] Close Device NRT
[  237.914730] timer proc function
[  237.914735] rtdm_timer_start_in_handler returned 0
[  238.014707] timer proc function
[  238.014711] rtdm_timer_start_in_handler returned 0
[  238.114687] timer proc function
[  238.114690] rtdm_timer_start_in_handler returned 0
... goes on forever as the timer was not shut down properly.



Em qui 11 ago 2011, às 04:39:16, Gilles Chanteperdrix escreveu:
> On 08/10/2011 11:10 PM, Carlos Eduardo de Brito Novaes wrote:
> > Hello again.
> > I traced the errors down and now dicovered that calling printf (as it
> > would be) turns a real time task in a non real time one. so I chaged the
> > code and it is almost working as expected, except for something that now
> > seens to be some kind of bug. If I use any sord of
> > rtdm_event_[timed,]wait, the app returns and there is a trace on kernel
> > about a null pointer, just after the call to wait. It seens similar with
> > <http://www.mail-archive.com/xenomai@xenomai.org>
> > And I there is no other references on google. So I will try to recompile
> > with some changes and maybe test with another kernel. Hope you can point
> > something I am running in a AMD Athlon(tm) 64 X2 Dual Core Processor
> > 4000+, kernel 2.6.38-8, ubuntu natty 11.04 and latest stable xenomai
> > source.
> > If it will help, I can send the code.
> 
> Please try and reduce the code to a simple, self-contained test case
> which we can run to reproduce the issue. It is the only way we can help.

[-- Attachment #2: testcase_wait_hang.tar.bz2 --]
[-- Type: application/x-bzip-compressed-tar, Size: 3684 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11 14:31       ` Carlos Eduardo de Brito Novaes
@ 2011-08-11 15:00         ` Gilles Chanteperdrix
  2011-08-11 17:56           ` Carlos Eduardo de Brito Novaes
  0 siblings, 1 reply; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-08-11 15:00 UTC (permalink / raw)
  To: Carlos Eduardo de Brito Novaes; +Cc: xenomai

On 08/11/2011 04:31 PM, Carlos Eduardo de Brito Novaes wrote:
> Here it comes.
> I found out that if wait is called inside an IOCTL, there is no hangs at all, 
> everything work as expected, except from te fact that it seens a litle bit 
> strange (to me) to use ioctl to read or write, I would expect to use the 
> correspondent rad and write functions and ioctl to setup something.
> I tried to reduce the code, in the tarball there are one Makefile, one c file 
> for the module and one c file for the app. There is one define line on the 
> module file, comment it ou to get the hangs. The app will simply open the 
> device, issue an wait ioctl (dummy if the module is compiled to wait in 
> read_rt) and the do the actual reading (it hangs on my system if i tell the 
> module to wait on the read_rt function).
> 
> Here comes the kernel log from one run that does the error but fortunately
> does not hang the entire system.

Yes, you can use rtdm_event_wait in read or write. The fact that it
hangs or results in bugs is probably due to the fact that you are
corrupting some memory. Your testcase contains too much code. If you
want to test rtdm_event_wait / rtdm_event_pulse, simply do one driver,
with one ioctl which does the rtdm_event_wait, and the timer which does
the rtdm_event_pulse.

The copy_to_user in the read callback overflows the source area, but
that is not your problem.

Also, do not use open_rt and close_rt in new code as they are deprecated.

-- 
					    Gilles.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11 15:00         ` Gilles Chanteperdrix
@ 2011-08-11 17:56           ` Carlos Eduardo de Brito Novaes
  2011-08-11 18:01             ` Gilles Chanteperdrix
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-11 17:56 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

[-- Attachment #1: Type: Text/Plain, Size: 2779 bytes --]

Hello again,

I did what you said, changed the open/close to non real time, removed every 
portion of code that is not related with the fault (the read_rt is still there 
since is where the problem arrises and also another ioctl to start timer since 
the open/close are moved out of real time context). There is also the wait 
ioctl to show that the code works when wait is done inside ioctl.
The problem persists, but no hangs perceived. Just the application returns too 
fast and there is the kernel message on NULL pointer derreference, so I also 
tried to recompile with another kernel version, the vanilla 2.6.38-8 from 
kernel.org and the adeos patch (on the previous tests I was using the same 
with additional ubuntu patches). Even now the app returns imediately after 
call read with rtdm_event_wait and there is the same kernel log.
I dont think there is any memory corruption due to the module code since there 
is no dynamic allocations, little pointer operations mainly related to the 
context hadler witch is allocated by xenomai on rtdm_dev_register.
I send you the new tarball.

Thanks for your support.

--
Carlos Novaes.

Em qui 11 ago 2011, às 12:00:16, Gilles Chanteperdrix escreveu:
> On 08/11/2011 04:31 PM, Carlos Eduardo de Brito Novaes wrote:
> > Here it comes.
> > I found out that if wait is called inside an IOCTL, there is no hangs at
> > all, everything work as expected, except from te fact that it seens a
> > litle bit strange (to me) to use ioctl to read or write, I would expect
> > to use the correspondent rad and write functions and ioctl to setup
> > something. I tried to reduce the code, in the tarball there are one
> > Makefile, one c file for the module and one c file for the app. There is
> > one define line on the module file, comment it ou to get the hangs. The
> > app will simply open the device, issue an wait ioctl (dummy if the
> > module is compiled to wait in read_rt) and the do the actual reading (it
> > hangs on my system if i tell the module to wait on the read_rt
> > function).
> > 
> > Here comes the kernel log from one run that does the error but
> > fortunately does not hang the entire system.
> 
> Yes, you can use rtdm_event_wait in read or write. The fact that it
> hangs or results in bugs is probably due to the fact that you are
> corrupting some memory. Your testcase contains too much code. If you
> want to test rtdm_event_wait / rtdm_event_pulse, simply do one driver,
> with one ioctl which does the rtdm_event_wait, and the timer which does
> the rtdm_event_pulse.
> 
> The copy_to_user in the read callback overflows the source area, but
> that is not your problem.
> 
> Also, do not use open_rt and close_rt in new code as they are deprecated.

[-- Attachment #2: testcase_wait_hang.tar.bz2 --]
[-- Type: application/x-bzip-compressed-tar, Size: 3542 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11 17:56           ` Carlos Eduardo de Brito Novaes
@ 2011-08-11 18:01             ` Gilles Chanteperdrix
  2011-08-11 18:12               ` Carlos Eduardo de Brito Novaes
  0 siblings, 1 reply; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-08-11 18:01 UTC (permalink / raw)
  To: Carlos Eduardo de Brito Novaes; +Cc: xenomai

On 08/11/2011 07:56 PM, Carlos Eduardo de Brito Novaes wrote:
> Hello again,
> 
> I did what you said, changed the open/close to non real time, removed every 
> portion of code that is not related with the fault (the read_rt is still there 
> since is where the problem arrises and also another ioctl to start timer since 
> the open/close are moved out of real time context). There is also the wait 
> ioctl to show that the code works when wait is done inside ioctl.
> The problem persists, but no hangs perceived. Just the application returns too 
> fast and there is the kernel message on NULL pointer derreference, so I also 
> tried to recompile with another kernel version, the vanilla 2.6.38-8 from 
> kernel.org and the adeos patch (on the previous tests I was using the same 
> with additional ubuntu patches). Even now the app returns imediately after 
> call read with rtdm_event_wait and there is the same kernel log.
> I dont think there is any memory corruption due to the module code since there 
> is no dynamic allocations, little pointer operations mainly related to the 
> context hadler witch is allocated by xenomai on rtdm_dev_register.
> I send you the new tarball.
> 
> Thanks for your support.

The copy_to_user is still overflowing. And in fact, it is probably the
cause of the bug you observe, I had not read your example carefully.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11 18:01             ` Gilles Chanteperdrix
@ 2011-08-11 18:12               ` Carlos Eduardo de Brito Novaes
  2011-08-11 19:34                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-11 18:12 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

I really did not understand why nor even what exactly it means to overflow the 
source area, but I forgot to mention that I commented it out, so the 
copy_to_user is not being called at all.

Thanks

--
Carlos Novaaes.

Em qui 11 ago 2011, às 15:01:18, você escreveu:
> The copy_to_user is still overflowing. And in fact, it is probably the
> cause of the bug you observe, I had not read your example carefully.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11 18:12               ` Carlos Eduardo de Brito Novaes
@ 2011-08-11 19:34                 ` Gilles Chanteperdrix
  2011-08-11 22:28                   ` Carlos Eduardo de Brito Novaes
  0 siblings, 1 reply; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-08-11 19:34 UTC (permalink / raw)
  To: Carlos Eduardo de Brito Novaes; +Cc: xenomai

On 08/11/2011 08:12 PM, Carlos Eduardo de Brito Novaes wrote:
> I really did not understand why nor even what exactly it means to overflow the 
> source area, but I forgot to mention that I commented it out, so the 
> copy_to_user is not being called at all.

It means that sizeof(sample_number) is 40, and neither the zone you are
copying from, neither the zone you are copying to is 40 bytes large
(except for the first call to read).

Also, there is no problem starting a timer in open_nrt and close_nrt
handlers.

So, here is a simple self-contained testcase which does what you are
trying to do. And which works. So, I insist, you should really inspect
your code carefully, the bugs you have do not seem to come from xenomai.

Module code:
#include <rtdm/rtdm_driver.h>

struct device_ctx {
	rtdm_event_t event;
	rtdm_timer_t timer;
};

MODULE_LICENSE("GPL");
MODULE_AUTHOR("gch");

static void test_timer(rtdm_timer_t *timer)
{
	struct device_ctx *ctx = container_of(timer, struct device_ctx, timer);

	rtdm_event_pulse(&ctx->event);
	rtdm_timer_start_in_handler(&ctx->timer,
			      rtdm_clock_read_monotonic() + 100000000,
			      0, RTDM_TIMERMODE_ABSOLUTE);
}

static int test_open(struct rtdm_dev_context *context,
		     rtdm_user_info_t *user_info,
		     int oflags)
{
	struct device_ctx *ctx = (struct device_ctx *)context->dev_private;
	int rc;

	rc = rtdm_timer_init(&ctx->timer, test_timer, "timer");
	if (rc < 0)
		return rc;

	rtdm_event_init(&ctx->event, 0);

	rc = rtdm_timer_start(&ctx->timer,
			      rtdm_clock_read_monotonic() + 100000000,
			      0, RTDM_TIMERMODE_ABSOLUTE);
	if (rc < 0) {
		rtdm_timer_destroy(&ctx->timer);
		rtdm_event_destroy(&ctx->event);
		return rc;
	}

	return 0;
}

static int test_close(struct rtdm_dev_context *context,
		      rtdm_user_info_t *user_info)
{
	struct device_ctx *ctx = (struct device_ctx *)context->dev_private;

	rtdm_timer_destroy(&ctx->timer);
	rtdm_event_destroy(&ctx->event);

	return 0;
}

static ssize_t test_read(struct rtdm_dev_context *context,
			 rtdm_user_info_t *user_info, void *buf, size_t size)
{
	struct device_ctx *ctx = (struct device_ctx *)context->dev_private;
	rtdm_toseq_t to;
	ssize_t rc;

	rtdm_toseq_init(&to, 1000000000);

	rc = rtdm_event_timedwait(&ctx->event, 1000000000, &to);
	printk("rtdm_event_timedwait: %d\n", rc);

	return rc;
}

static struct rtdm_device device = {
	struct_version: RTDM_DEVICE_STRUCT_VER,

	device_flags: RTDM_NAMED_DEVICE,
	context_size: sizeof(struct device_ctx),
	device_name:  "test",

	open_rt: NULL,
	open_nrt: test_open,

	ops: {
		close_rt: NULL,
		close_nrt: test_close,

		ioctl_rt: NULL,
		ioctl_nrt: NULL,

		read_rt: test_read,
		read_nrt: NULL,

		write_rt: NULL,
		write_nrt: NULL,

		recvmsg_rt: NULL,
		recvmsg_nrt: NULL,

		sendmsg_rt: NULL,
		sendmsg_nrt: NULL,
	},

	device_class: RTDM_CLASS_EXPERIMENTAL,
	device_sub_class: 0,
	profile_version: 1,
	driver_name: "xeno_switchtest",
	driver_version: RTDM_DRIVER_VER(0, 1, 1),
	peripheral_name: "Context Switch Test",
	provider_name: "Gilles Chanteperdrix",
	proc_name: device.device_name,
};

int __init rtdm_test_init(void)
{
	return rtdm_dev_register(&device);
}

void rtdm_test_exit(void)
{
	rtdm_dev_unregister(&device, 1000);
}

module_init(rtdm_test_init);
module_exit(rtdm_test_exit);

Application code:
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/mman.h>

int main(void)
{
	int i, rc, fd;

	mlockall(MCL_CURRENT | MCL_FUTURE);

	fd = open("/dev/test", O_RDONLY);
	if (fd < 0) {
		perror("open(rtdm_test)");
		return EXIT_FAILURE;
	}

	for (i = 0; i < 10; i++) {
		char buf[40];

		rc = read(fd, buf, sizeof(buf));
		if (rc < 0) {
			perror("read");
			pause();
			return EXIT_FAILURE;
		}
	}

	return EXIT_SUCCESS;
}

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xenomai-help] Trouble with rtdm timers and events
  2011-08-11 19:34                 ` Gilles Chanteperdrix
@ 2011-08-11 22:28                   ` Carlos Eduardo de Brito Novaes
  0 siblings, 0 replies; 11+ messages in thread
From: Carlos Eduardo de Brito Novaes @ 2011-08-11 22:28 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

Solved,
It really was a bug on my code, in the read_rt. I was referring to device 
context before get it. Thank you very much for the help, for the code and for 
the time spent. Also, sorry for not being able to catch this stupid bug 
before.

Thanks

--
Carlos Novaes.


Em qui 11 ago 2011, às 16:34:08, Gilles Chanteperdrix escreveu:
> On 08/11/2011 08:12 PM, Carlos Eduardo de Brito Novaes wrote:
> > I really did not understand why nor even what exactly it means to
> > overflow the source area, but I forgot to mention that I commented it
> > out, so the copy_to_user is not being called at all.
> 
> It means that sizeof(sample_number) is 40, and neither the zone you are
> copying from, neither the zone you are copying to is 40 bytes large
> (except for the first call to read).
> 
> Also, there is no problem starting a timer in open_nrt and close_nrt
> handlers.
> 
> So, here is a simple self-contained testcase which does what you are
> trying to do. And which works. So, I insist, you should really inspect
> your code carefully, the bugs you have do not seem to come from xenomai.
> 
> Module code:
> #include <rtdm/rtdm_driver.h>
> 
> struct device_ctx {
> 	rtdm_event_t event;
> 	rtdm_timer_t timer;
> };
> 
> MODULE_LICENSE("GPL");
> MODULE_AUTHOR("gch");
> 
> static void test_timer(rtdm_timer_t *timer)
> {
> 	struct device_ctx *ctx = container_of(timer, struct device_ctx, timer);
> 
> 	rtdm_event_pulse(&ctx->event);
> 	rtdm_timer_start_in_handler(&ctx->timer,
> 			      rtdm_clock_read_monotonic() + 100000000,
> 			      0, RTDM_TIMERMODE_ABSOLUTE);
> }
> 
> static int test_open(struct rtdm_dev_context *context,
> 		     rtdm_user_info_t *user_info,
> 		     int oflags)
> {
> 	struct device_ctx *ctx = (struct device_ctx *)context->dev_private;
> 	int rc;
> 
> 	rc = rtdm_timer_init(&ctx->timer, test_timer, "timer");
> 	if (rc < 0)
> 		return rc;
> 
> 	rtdm_event_init(&ctx->event, 0);
> 
> 	rc = rtdm_timer_start(&ctx->timer,
> 			      rtdm_clock_read_monotonic() + 100000000,
> 			      0, RTDM_TIMERMODE_ABSOLUTE);
> 	if (rc < 0) {
> 		rtdm_timer_destroy(&ctx->timer);
> 		rtdm_event_destroy(&ctx->event);
> 		return rc;
> 	}
> 
> 	return 0;
> }
> 
> static int test_close(struct rtdm_dev_context *context,
> 		      rtdm_user_info_t *user_info)
> {
> 	struct device_ctx *ctx = (struct device_ctx *)context->dev_private;
> 
> 	rtdm_timer_destroy(&ctx->timer);
> 	rtdm_event_destroy(&ctx->event);
> 
> 	return 0;
> }
> 
> static ssize_t test_read(struct rtdm_dev_context *context,
> 			 rtdm_user_info_t *user_info, void *buf, size_t size)
> {
> 	struct device_ctx *ctx = (struct device_ctx *)context->dev_private;
> 	rtdm_toseq_t to;
> 	ssize_t rc;
> 
> 	rtdm_toseq_init(&to, 1000000000);
> 
> 	rc = rtdm_event_timedwait(&ctx->event, 1000000000, &to);
> 	printk("rtdm_event_timedwait: %d\n", rc);
> 
> 	return rc;
> }
> 
> static struct rtdm_device device = {
> 	struct_version: RTDM_DEVICE_STRUCT_VER,
> 
> 	device_flags: RTDM_NAMED_DEVICE,
> 	context_size: sizeof(struct device_ctx),
> 	device_name:  "test",
> 
> 	open_rt: NULL,
> 	open_nrt: test_open,
> 
> 	ops: {
> 		close_rt: NULL,
> 		close_nrt: test_close,
> 
> 		ioctl_rt: NULL,
> 		ioctl_nrt: NULL,
> 
> 		read_rt: test_read,
> 		read_nrt: NULL,
> 
> 		write_rt: NULL,
> 		write_nrt: NULL,
> 
> 		recvmsg_rt: NULL,
> 		recvmsg_nrt: NULL,
> 
> 		sendmsg_rt: NULL,
> 		sendmsg_nrt: NULL,
> 	},
> 
> 	device_class: RTDM_CLASS_EXPERIMENTAL,
> 	device_sub_class: 0,
> 	profile_version: 1,
> 	driver_name: "xeno_switchtest",
> 	driver_version: RTDM_DRIVER_VER(0, 1, 1),
> 	peripheral_name: "Context Switch Test",
> 	provider_name: "Gilles Chanteperdrix",
> 	proc_name: device.device_name,
> };
> 
> int __init rtdm_test_init(void)
> {
> 	return rtdm_dev_register(&device);
> }
> 
> void rtdm_test_exit(void)
> {
> 	rtdm_dev_unregister(&device, 1000);
> }
> 
> module_init(rtdm_test_init);
> module_exit(rtdm_test_exit);
> 
> Application code:
> #include <stdio.h>
> #include <stdlib.h>
> 
> #include <unistd.h>
> #include <sys/fcntl.h>
> #include <sys/mman.h>
> 
> int main(void)
> {
> 	int i, rc, fd;
> 
> 	mlockall(MCL_CURRENT | MCL_FUTURE);
> 
> 	fd = open("/dev/test", O_RDONLY);
> 	if (fd < 0) {
> 		perror("open(rtdm_test)");
> 		return EXIT_FAILURE;
> 	}
> 
> 	for (i = 0; i < 10; i++) {
> 		char buf[40];
> 
> 		rc = read(fd, buf, sizeof(buf));
> 		if (rc < 0) {
> 			perror("read");
> 			pause();
> 			return EXIT_FAILURE;
> 		}
> 	}
> 
> 	return EXIT_SUCCESS;
> }


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-08-11 22:28 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-10 17:49 [Xenomai-help] Trouble with rtdm timers and events Carlos Eduardo de Brito Novaes
2011-08-10 19:57 ` Carlos Eduardo de Brito Novaes
2011-08-10 21:10   ` Carlos Eduardo de Brito Novaes
2011-08-11  7:39     ` Gilles Chanteperdrix
2011-08-11 14:31       ` Carlos Eduardo de Brito Novaes
2011-08-11 15:00         ` Gilles Chanteperdrix
2011-08-11 17:56           ` Carlos Eduardo de Brito Novaes
2011-08-11 18:01             ` Gilles Chanteperdrix
2011-08-11 18:12               ` Carlos Eduardo de Brito Novaes
2011-08-11 19:34                 ` Gilles Chanteperdrix
2011-08-11 22:28                   ` Carlos Eduardo de Brito Novaes

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.