This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

how to do floating point operations on OMAP 3503 from within the Linux device driver ?

 

I am newbie working on Linux Device Driver, I need to do floating point operations in the Linux device driver on OMAP 3503.

I am able to successfully cross compile this code as a user space C program and run it without any issues.

But when I add this code to the touchscreen driver and try to build kernel image we get following errors

--------------------------------------------- kernel/device driver linking errors-----------------------------

linux-02.01.03.11/drivers/input/touchscreen/abc.c:17: undefined reference to `__aeabi_ddiv'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:17: undefined reference to `__aeabi_dmul'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:18: undefined reference to `__aeabi_dcmpge'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:20: undefined reference to `__aeabi_dadd'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:24: undefined reference to `__aeabi_dsub'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:24: undefined reference to `__aeabi_d2uiz'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:24: undefined reference to `__aeabi_ui2d'

linux-02.01.03.11/drivers/input/touchscreen/abc.c:24: undefined reference to `__aeabi_d2uiz'

---------------------------------------------------------------------------------------

---------------------- touchscreen.c code snippet for your reference ------------------

 15 unsigned int round_func(double x, double divisor, double mapratio)

 16 {

 17         x = (x/divisor)*mapratio;

 18         if ( x >= 0 )

 19         {

 20            x = (unsigned int)(x + 0.5);

 21         }

 22         else

 23         {

 24            x = (unsigned int)(x - 0.5);

 25         }

 26     return x;

 27 }

------------------------------------------------------------------------

 

how can I do above shown floating point operations using OMAP 3503 instructions in Linux device driver code?  ( VFPv3, NEON etc )

 

Thanks

---

 

  • Resmi,

    Unfortunately NEON does not support double precision floating point.  All you need to do to enable the VFP is add some compiler flags:

    -O3 -march=armv7-a -mtune=cortex-a8 -mfpu=vfp  -mfloat-abi=softfp

    Try out these, especially the ones in red. Then instead of the floating point library calls you showed above, you should see some VFP commands.  They might look something like the following:

    fldd    d26, [r2, #0]
    faddd   d19, d19, d16
    faddd   d17, d18, d17

    Instead of the normal r0-r15 registers, you should see d0-d31 or s0-s31 registers. This would indicate the VFP is being used.

    If you did want to use the math library, you might try adding -lm flag for the linker to get rid of those undefined references.

  • Thanks Jeff,  but I am not familar with VFP commands/code,  can you provide the VFP code for the following C code ? or provide VFP tutorial on how to use it from Linux kernel?

    unsigned int round_func(double x, double divisor, double mapratio)
     {
            x = (x/divisor)*mapratio;
          if ( x >= 0 )
          {
                 x = (unsigned int)(x + 0.5);
           }
          else
          {
                 x = (unsigned int)(x - 0.5);
           }
      return x;
     }

  • I did some Google searches on the topic and found this:

    Floating point is forbidden in kernel code since the floating point
    registers (and other floating point context) is not saved/restored
    during system calls, for efficiency.

    Steve K

  • Resmi,

    My original answer is only applicable to Application code and not Kernel code as Steve pointed out.

    Also you can not easily link in the math libraries to the kernel .

    So for the kernel, and for this function, you could use fixed point math instead of floating point math.

    There may be some tutorials online for fixed point if you are not familiar with it.  I found a brief one: http://www.biccari.com/docs/Fixed_point_tutorial.pdf

    Jeff L

  • Thanks Jeff,

    however we found a way do it using  integer based algorithm in kernel itself.

    ---