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);
> };
> ---

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

Reply via email to