Re: RTAI and comedi: leaving real time?

On Thu, 2007-05-24 at 22:14 +0200, Paolo Mantegazza wrote:
> L.C. Karssen wrote:
> > Thanks for your help again Paolo!
> > 
> > On Wed, 2007-05-23 at 22:12 +0200, Paolo Mantegazza wrote:
> > 
> >>L.C. Karssen wrote:
> >>
> >>>After getting rid of the syscalls during hard RT as described below, I
> >>>found that the DIO lines are no longer being flipped. Only the analog
> >>>out works. 
> >>>When I replaced the call to comedi_dio_bitfield() with 8 calls to
> >>>comedi_dio_write() (one for each DIO channel) it works again.

> > The point I was trying to make was that I don't see any output on the
> > oscilloscope when looking at the DIO lines. The AO works OK. So it looks
> > like writing DIO with the bitfield-function in hard RT (when
> > #include-ing rtai_comedi.h) doesn't work. 
> > 
> 
> I repeat that sounds strange to me and is worth understanding. I've no 
> chance for such a check at the moment unfortunately.
It gets even stranger. I put a call to comedi_dio_bitfield() in my
comedi initialisation routine (simply set all DIO lines to 0). And there
it works as expected (the initialisation routine contains no RT code).  

Whether I call rt_set_hard_realtime() or not in my output routine
doesn't change the behaviour.

I looked in comedi's dio.c file to see the code for the
comedi_dio_bitfield() routine. It's just a comedi instruction. I copied
that code to my output routine and now it works as expected. Even with
nice 20us timing. 
So I'm happy :-). 

I still don't know why calling bitfield() gave me a flatline on the
oscilloscope, though. :-(


> > 
> > 
> >>
> >>I'm wondering why you do not try to track the problem by making a direct 
> >>call both with comedi and using RTAI call, without hard real mode, just 
> >>to see where the problem is. In my view it is likely just a matter of a 
> >>few printf and prink at right places, possibly including comedi function 
> >>to follow the whole path.
> > 
> > I'm not sure how I should do that. How can I distinguish between
> > comedi_dio_bitfield() being called through the RTAI wrapper (so with
> > rtai_comedi.h) and comedi_dio_bitfield() in its "normal" form (so with
> > the comedilib.h file #included)? I can't have both function definitions
> > in the same program, can I?
> > 
> 
> Why not? I would try to resove any name space conflict by changing the 
> name of the related wrapper in RTAI.
> 
> > 
> >>>So, can anybody tell me if using comedi_dio_bitfield() in hard RT works
> >>>for him/her? In RTAILabs rtai_comedi_dioout.c I see that only
> >>>comedi_dio_write() is used. I also noticed that rtai_comedi.h doesn't
> >>>have a wrapper for the (new) comedi_dio_bitfield2() function (which is
> >>>supposed to supersede the comedi_dio_bitfield() function if I'm not
> >>>mistaken).
> >>
> >>It is simple to add the wrapper and test it, see above. just the 
> >>declaration and a new cal number in rtai_comedi.h the related call and 
> >>table insertion in the module, Likely a cut and paste with few changes.
> > 
> > I tried to do as you suggested. This is what I did:
> > - In /usr/src/rtai/addons/comedi/rtai_comedi.h I added the line
> > 
> > #define _KCOMEDI_DIO_BITFIELD2 		29
> > 
> > just above the deprecated GET_RANGETYPE and after the POLL line. I also
> > copied and edited the prototype of the ordinary bitfield function:
> > 
> > RTAI_PROTO(int, comedi_dio_bitfield2,(void *dev, unsigned int subdev,
> > unsigned int mask, unsigned int *bits, unsigned int base_channel))
> > {
> >         int retval;
> > 	unsigned int lbits;
> >         struct { void *dev; unsigned int subdev; unsigned int mask;
> > unsigned int *bits; unsigned int base_channel; } arg = { dev, subdev,
> > mask, &lbits, base_channel };
> > 	retval = rtai_lxrt(FUN_COMEDI_LXRT_INDX, COMEDI_LXRT_SIZARG,
> > _KCOMEDI_DIO_BITFIELD2, &arg).i[LOW];
> > 	*bits = lbits;
> > 	return retval;
> > 
> > 
> > - In /usr/src/rtai/addons/comedi/kcomedi_module.c I copied and adapted
> > the bitfield RTAI_SYSCALL_MODE line:
> > 
> > static RTAI_SYSCALL_MODE int _comedi_dio_bitfield2(void *dev, unsigned
> > int subdev, unsigned int mask, unsigned int *bits, unsigned int
> > base_channel)
> > {
> >   return comedi_dio_bitfield2(dev, subdev, mask, bits, base_channel);
> > }
> > 
> > Then, in the rtai_comedi_fun[] struct I added the line
> > 
> > ,[_KCOMEDI_DIO_BITFIELD2]        = { 0, _comedi_dio_bitfield2 }
> > 
> > below the line with ,[_KCOMEDI_POLL]                = { 0, comedi_poll }
> > 
> > (so that it was in the same order as in the rtai_comedi.h file. A bit
> > further down I added the line .
> > 
> > ,[_KCOMEDI_DIO_BITFIELD2]        = { 0, comedi_dio_bitfield2 }
> > 
> > 
> > But when I run make in this directory I get a long list of errors,
> > starting with:
> > 
> 
> In kcomedi-module.c add the related code for calling bitfield2 also. 
> Copy and change the existing bitfield, something like:
> 
> static RTAI_SYSCALL_MODE int _comedi_dio_bitfield2(void *dev, unsigned 
> int subdev, unsigned int mask, unsigned int *bits)
> {
>    return comedi_dio_bitfield2(dev, subdev, mask, bits);
> }
As you can see a few lines up, I already did that. 

For completeness, this is a diff of rtai_comedi.h:
--- rtai_comedi_orig.h  2007-05-24 15:26:58.000000000 +0200
+++ rtai_comedi.h       2007-05-23 19:01:44.000000000 +0200
_at__at_ -60,6 +60,7 _at__at_
 #define _KCOMEDI_DO_INSN               26
 #define _KCOMEDI_DO_INSN_LIST          27  // not yet in kcomedilib...
(tl) 
 #define _KCOMEDI_POLL                  28
+#define _KCOMEDI_DIO_BITFIELD2                 29
 
 /* DEPRECATED function
 #define _KCOMEDI_GET_RANGETYPE                 29
_at__at_ -292,6 +293,16 _at__at_
        return retval;
 }
 
+RTAI_PROTO(int, comedi_dio_bitfield2,(void *dev, unsigned int subdev,
unsigned int mask, unsigned int *bits, unsigned int base_channel))
+{
+        int retval;
+       unsigned int lbits;
+        struct { void *dev; unsigned int subdev; unsigned int mask;
unsigned int *bits; unsigned int base_channel; } arg = { dev, subdev,
mask, &lbits, base_channel };
+       retval = rtai_lxrt(FUN_COMEDI_LXRT_INDX, COMEDI_LXRT_SIZARG,
_KCOMEDI_DIO_BITFIELD2, &arg).i[LOW];
+       *bits = lbits;
+       return retval;
+}
+
 RTAI_PROTO(int, comedi_get_n_subdevices,(void *dev))
 {
        struct { void *dev;} arg = { dev };



And this is a diff of kcomedi_module.c:
--- kcomedi-module-orig.c       2007-05-24 15:30:26.000000000 +0200
+++ kcomedi-module.c    2007-05-24 15:30:42.000000000 +0200
_at__at_ -273,10 +273,15 _at__at_
 static RTAI_SYSCALL_MODE int _comedi_poll(void *dev, unsigned int
subdev)
 {
   return comedi_poll(dev, subdev);
 }
 
+static RTAI_SYSCALL_MODE int _comedi_dio_bitfield2(void *dev, unsigned
int subdev, unsigned int mask, unsigned int *bits, unsigned int
base_channel)
+{
+  return comedi_dio_bitfield2(dev, subdev, mask, bits, base_channel);
+}
+
 /* DEPRECATED FUNCTION
 static RTAI_SYSCALL_MODE int _comedi_get_rangetype(unsigned int minor,
unsigned int subdevice, unsigned int chan)
 {
   return comedi_get_rangetype(minor, subdevice, chan);
 }
_at__at_ -343,10 +348,11 _at__at_
   /* NOT YET IMPLEMENTED
   ,[_KCOMEDI_DO_INSN_LIST]        = { 0, _comedi_di_insn_list }
   */
 
   ,[_KCOMEDI_POLL]                = { 0, _comedi_poll }
+  ,[_KCOMEDI_DIO_BITFIELD2]        = { 0, _comedi_dio_bitfield2 }
 
   /*
   ,[_KCOMEDI_GET_RANGETYPE]       = { 0, _comedi_get_rangetype }
   */ 
 
_at__at_ -390,10 +396,11 _at__at_
   /* NOT YET IMPLEMENTED
   ,[_KCOMEDI_DO_INSN_LIST]        = { 0, comedi_di_insn_list }
   */
 
   ,[_KCOMEDI_POLL]                = { 0, comedi_poll }
+  ,[_KCOMEDI_DIO_BITFIELD2]       = { 0, comedi_dio_bitfield2 }
 
   /*
   ,[_KCOMEDI_GET_RANGETYPE]       = { 0, comedi_get_rangetype }
   */
 

If I change line 401 to
,[_KCOMEDI_DIO_BITFIELD2]       = { 0, comedi_dio_bitfield }
the module compiles (although trying to use it would probably give some
sort of failure). So I guess there's another place where I should have
some definition of comedi_dio_bitfield2.
I also noticed that comedi doesn't have any code for
comedi_dio_bitfield2(), only comedilib has it. So maybe it's not fully
implemented yet. 

However, since I've worked around my problem using comedi_do_insn() I'm
not going to delve any deeper into this. 


Anyway, thanks for your help and suggestions,

Lennart.

> 
> That should solve the error.
> 
> Paolo.
> 
> > /usr/src/rtai/addons/comedi/kcomedi-module.c: At top level:
> > /usr/src/rtai/addons/comedi/kcomedi-module.c:401: error:
> > `comedi_dio_bitfield2' undeclared here (not in a function)
> > /usr/src/rtai/addons/comedi/kcomedi-module.c:401: error: initializer
> > element is not constant
> > /usr/src/rtai/addons/comedi/kcomedi-module.c:401: error: (near
> > initialization for `rtai_comedi_fun[29].fun')
> > /usr/src/rtai/addons/comedi/kcomedi-module.c:401: error: initializer
> > element is not constant
> > /usr/src/rtai/addons/comedi/kcomedi-module.c:401: error: (near
> > initialization for `rtai_comedi_fun[29]')
> > 
> > 
> > I have no idea what's missing here. 
> > 

-- 
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
L.C. Karssen
Department of Physics and Astronomy
Faculty of Science
Utrecht University
Princetonplein 1
3584 CC  Utrecht
The Netherlands

tel.: +31 (0)30-253-2208
fax.: +31 (0)30-253-7468
e-mail: L.C.Karssen_at_phys.uu.nl
www: http://www1.phys.uu.nl/wwwaoud
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

Received on 2007-05-24Z14:21:14