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.

Floating point - X in the power of Y

Other Parts Discussed in Thread: CONTROLSUITE

It is required to perform the following single precision floating point calculations with F28335 :

(a) DIV  (b) SQRT  (c)  X in the POWER of Y

The first two are included in the fastRTS Library but none was found for  POWER. 

(1) Can anyone point to POWER calculation solution?

(2) Are there other DIV and SQRT implementations for comparison?

  • Issac,

    Isaac Pilli1 said:

    (1) Can anyone point to POWER calculation solution?

    I believe the regular compiler RTS library will have the POW() function.  Did you try that?  It's not an optimized function, but it should work.

    Isaac Pilli1 said:

    (2) Are there other DIV and SQRT implementations for comparison?

    You can compare the fastRTS library functions against those in the regular compiler RTS library.

     

    Regards,

    - David

  • rts2800_fpu32.lib had been linked and POW is running now.

    (1)  However, its execution duration is ~10000 nSec once running from the internal FLASH at 150MHz clock - does it make sense or indicate any problem?

    (2)  No rts2800_fpu32 library documentation could be found, can you provide a link?

           Specifically, which variable types does POW support as inputs and outputs?

    (3)  In my case it is required that the base X would be a signed (or an unsigned) fraction and the exponent Y would be a signed fraction.

          Can this be achieved with rts2800_fpu32.lib 's POW ? or by other mean?

  • Issac,

    (1) I just tested and get about 972 cycles running from RAM, and 1453 cycles running from flash.  It doesn't seem to be particularly data dependent (+/- a few cycles).  My test cases was using 3.0^2.0 and also 3.1^5.2.  The flash vs. RAM cycles make sense.  Running from flash we'd expect about a 50% increase in cycles (3 cycles from flash for every 2 cycles from RAM, running on F28335 at 150 MHz with the flash wait-states properly configured as RANDWAIT=PAGEWAIT=5).

    You said it was taking ~10000 nsec in your test.  That seems correct for flash at 150 MHz (6.67 ns):

    (10000 ns)/(6.67 ns/cycle) = 1499 cycles

    This basically matches what I benchmarked: 1453 cycles.  Probably some reading error on your measurement.

    The pow() function in the rts library is actually doing a pretty good job.  It uses a floating point numerical method for the computation, and the rts2800_fpu32.lib is compiled for the C28x FPU hardware so the function is taking full advantage of the hardware.

    (2) The RTS library functions are not documented by TI.  These are standard C-library functions.  Just Google "pow() in c".  For example, you'll find this reference: http://www.elook.org/programming/c/pow.html.  pow() takes two double arguments, and returns a double.  On C28x, a double is a 32-bit single-precision floating point value (long double is 64-bit).  You can also look at the source code for the rts library.  It is rtssrc.zip file in the \lib folder of the compiler folder.

    (3) pow() does not take fractional data.  You should convert them to floating point, call pow(), and then convert back to fraction if that is what you need.  Alternately, you could attempt to compute on the fractions directly using the IQNlog() and IQNexp() functions in the IQmath library (available in ControlSuite):

    z = y^x
    ln(z) = ln(y^x)
    ln(z) = x*ln(y)
    e^ln(z) = e^[x*ln(y)]
    z = e^[x*ln(y)]

    If you look at the pow() function source in the RTS library, you'll see that this is the approach it uses as well.  You'd compute the last line using IQNlog() and IQNexp().

    Regards,

    David

  • David,

    Thanks for the comprehensive response: pow() provides the expected results now.

    Interesting to mention that once a 'double' is watched as HEX in CCSV4, there is a bug that provides a different HEX value than the memory value.

    Hence, the supposed to be a simple linker syntax exercise of re-locating pow() into RAM had proven to be time consuming and ended in the ... FLASH memory only.

    Trying to use spru513e paragraph 7.5.4.5 as a reference but could make the location change.

    Attached a command file with the modification and explanations at its top.

    Would be appreciated if you could recommend which modifications to be implemented in order to locate pow() in RAM.

    Ideally, the proposed solution would include an example of how to locate rts2800_fpu32 library in the RAM, while selected functions of this library runs of the FLASH,

    or the other way around (Default FLASH and selected function in the RAM).

     

    Thanks,

    Isaac

    /******************************************************************************
    *                                                                             *
    * Filename:  Locate_rts_pow.cmd                                                *
    *                                                                             *
    ******************************************************************************/
    
    /* This file contains 3 lines that were added in an attemp to move 
       rts8200 from the internal FLASH to the internal RAM (F28335).   
       The lines are marked as 'line added moving RTS2800 to RAM' 
    
       As a result the linker provides LINE_X (see below) warning #10261-D:
       section specifiers matches no sections;
       potential matches are consumed by section specifier at line LINE_Y
    
       
       while compiling without the additional 3 lines the map file contains 
       the following relevant lines, and pow() runs of the FLASH
       00314c4a    00000101     rts2800_fpu32.lib : ctype.obj (.econst:__ctypes_)
       00315192    00000024     rts2800_fpu32.lib : _printfi_nf.obj (.econst:.string)
       0032784a    000004f3     rts2800_fpu32.lib : _printfi_nf.obj (.text)
       0032858a    0000000b     rts2800_fpu32.lib : u_div.obj (.text)
       003285b9    00000007     rts2800_fpu32.lib : memset.obj (.text)
       0032a759    0000000a     rts2800_fpu32.lib : _lock.obj (.cinit)
       003fffc0    00000002     rts2800_fpu32.lib : boot.obj (.reset)
       00209c28    00000004     rts2800_fpu32.lib : _lock.obj (.ebss)
       00328144    00000058                       : pow.obj (.text)
       
    
       but after adding the 3 lines than the map file contains the following lines, 
       and the result does not run at all:
       0000c093    000004f3     rts2800_fpu32.lib : _printfi_nf.obj (.text)
       00314c4a    00000101     rts2800_fpu32.lib : ctype.obj (.econst:__ctypes_)
       00315192    00000024     rts2800_fpu32.lib : _printfi_nf.obj (.econst:.string)
       00329a07    0000000a     rts2800_fpu32.lib : _lock.obj (.cinit)
       003fffc0    00000002     rts2800_fpu32.lib : boot.obj (.reset)
       00209c28    00000004     rts2800_fpu32.lib : _lock.obj (.ebss)
       0000c98d    00000058                       : pow.obj (.text)
       
       It seem that pow() is located indeed in the RAM (0xC98D) but
       it is suspected that it's not within the Prog_Fast section,
       meaning NOT copied from FLASH to the RAM.
    
       Please Advise.
       
    
    */
    
    
    
    /* 
      For reference:
      .bss    = global variables.
      .ebss   = far global variable.
      .data   = constant
      .cinit  = initialised C variables - coped from ROM to RAM.
    */
    
    MEMORY
    {
    PAGE 0 :          /* Program Space */
      PRAMM0M1        : origin = 0x000000, length = 0x000010
    
      PRAML01234      : origin = 0x008000, length = 0x005000  /* On chip ram */
    
      /* Flash Section H-C */
      APP_BEGIN       : origin = 0x300000, length = 0x000008, fill=0x0000   /* Application - Branch instruction */
      APP_HEADER      : origin = 0x300008, length = 0x0000F8, fill=0x0000   /* Application - Header information */
      APP_CODE        : origin = 0x300100, length = 0x02FC00  /* fill=0xFFFF */  /* FIXME: fill is removed to speed up JTAG for development */ /* Application - Code area */  
    
        
      FLASH_COUNT     : origin = 0x32FE00, length = 0x000001, fill=0x0000
      RESERVED        : origin = 0x32FE01, length = 0x0001FF, fill=0x0000
    
      /* Flash Section B */
      BL_BEGIN        : origin = 0x330000, length = 0x000008  /* BootLoader - Branch instruction */
      BL_HEADER       : origin = 0x330008, length = 0x0001F8  /* BootLoader - Header information */
    
      /* Flash Section A */
      CSM_RSVD        : origin = 0x33FF80, length = 0x000076, fill=0x0000   /* Program with all 0x0000 when CSM is in use. */
      CSM_PWL         : origin = 0x33FFF8, length = 0x000008                /* CSM password location */
    
      /* Located in Boot ROM */
      IQTABLES (R)    : origin = 0x3FE000, length = 0x000b50
      IQTABLES2 (R)   : origin = 0x3FEB50, length = 0x00008c
      FPUTABLES       : origin = 0x3FEBDC, length = 0x0006A0  
      RESET           : origin = 0x3FFFC0, length = 0x000002
      ADC_CAL         : origin = 0x380080, length = 0x000009  
      VECTORS         : origin = 0x3FFFC2, length = 0x00003E  
               
    PAGE 1 :          /* Data Space */
      RAMM0M1         : origin = 0x000010, length = 0x0007F0
      FPGA            : origin = 0x004000, length = 0x001000  /* Zone 0 - FPGA*/
      RAML567         : origin = 0x00D000, length = 0x003000
      ESC             : origin = 0x100000, length = 0x100000  /* Zone 6 - ET1100 */
      RAMBLA          : origin = 0x200000, length = 0x000100  /* allocate shared RAM between app and BL */
      RAMX            : origin = 0x200100, length = 0x03FFC0  /* Zone 7 - 4Mbit ram*/
    }
    
    SECTIONS
    {
    	/* Main entry points - must be in correct location*/
      codestart_flash : > APP_BEGIN       PAGE = 0 /* This will need to be removed when bootloader is present */
      .app_header     : > APP_HEADER      PAGE = 0
    
      .rts  { -lrts2800_fpu32.lib (.text) } >  PRAML01234   PAGE = 0  /*  LINE_Y: this is the first line added moving RTS2800 to RAM*/
      .bl_jump        : > BL_BEGIN,       PAGE = 0, TYPE = NOLOAD
      .bl_header      : > BL_HEADER,      PAGE = 0, TYPE = NOLOAD
      .adc_cal        : load = ADC_CAL,   PAGE = 0, TYPE = NOLOAD
    
      /* These should probably be fixed in flash at the same location for all builds */
      IQmathTables    : load = IQTABLES, type = NOLOAD, PAGE = 0
      IQmathTables2   > IQTABLES2, type = NOLOAD, PAGE = 0
                      {
                        IQmath_fpu32.lib<IQNexpTable.obj>(IQmathTablesRam)
                      }
      IQmathTablesRam : load = RAMX,     PAGE = 1
      FPUmathTables   : > FPUTABLES, PAGE = 0, TYPE = NOLOAD 
    
    
      /* These items may go into RAM or Flash */
      codestart       : > APP_CODE      PAGE = 0
      .const          : > APP_CODE      PAGE = 0
      .econst         : > APP_CODE      PAGE = 0
      .switch         : > APP_CODE      PAGE = 0
    
      UAPP_HEADER     : > APP_CODE      PAGE = 0,
                        LOAD_START(_HWLINK_u16UAPP_HEADER_SECT)
    
      temp_prog       : > APP_CODE      PAGE = 0
      .reset          : > RESET,        PAGE = 0, TYPE = DSECT /* not used, */
    
      /* Allocate program areas: */
      .text           : > APP_CODE      PAGE = 0
      .cinit          : > APP_CODE      PAGE = 0
      .pinit          : > APP_CODE      PAGE = 0
    
      Prog_Fast       :   LOAD = APP_CODE,
                          RUN = PRAML01234,
                          {
                    	rts2800_fpu32.lib(.text)    /*  LINE_X : this is the Second line added moving RTS2800 to RAM */
                            IQmath_fpu32.lib(.text)
    			*(rts2800)                  /*  This is the third and last line added moving RTS2800 to RAM */
                            *(IQmath)
                            *(Prog_Fast)
                          }
                          LOAD_START(_HWLINK_u16RTPROG_LoadStart),
                          LOAD_END(_HWLINK_u16RTPROG_LoadEnd),
                          RUN_START(_HWLINK_u16RTPROG_RunStart),
                          PAGE = 0
    
      csmpasswds      : > CSM_PWL     PAGE = 0 , TYPE = NOLOAD
      csm_rsvd        : > CSM_RSVD    PAGE = 0 , TYPE = NOLOAD
       
      /* Allocate uninitalized data sections: */
      .stack          : LOAD = RAMM0M1, 
                        RUN_START(_HWLINK_u16StackStart), 
                        RUN_END(_HWLINK_u16StackEnd), 
                        PAGE = 1 
    
      .bss            : > RAMM0M1     PAGE = 1
      .ebss           : > RAML567,    PAGE = 1
      .ebssX          : {
                           rts2800_fpu32.lib(.ebss)
                        }
    					> RAMX,             PAGE = 1
      
      Data_Params_Temp    : > RAMX,         PAGE = 1						
      Data_Signals_Temp   : > RAMX,         PAGE = 1						
      Data_Fast_Signal    : > RAML567,      PAGE = 1  
      Data_Slow_Signal    : > RAMX,         PAGE = 1
      Data_External       : > RAMX,         PAGE = 1
    
      bootloader_ram_data      : LOAD > RAMBLA
      
    
      /* Allocate initialised data sections */
      Data_Fast_Param     :   RUN   = RAMM0M1     PAGE 1,
                              LOAD  = APP_CODE    PAGE 0,
                              LOAD_START(_HWLINK_u16PARM_LoadStart),
                              LOAD_END(_HWLINK_u16PARM_LoadEnd),
                              RUN_START(_HWLINK_u16PARM_RunStart)
    
      UnusedAllocation    : > ESC,
                            LOAD_START(_HWLINK_u16ESC)
                            
      DATA_FPGA           : > FPGA
                            
    
    }
    
    

  • Issac,

    Yeah, spru513e can be confusing.  Libraries are a little different than regular source files.

    To execute pow() from RAM, you need to do two things.  First, you need to link it so that it loads to flash but runs from RAM, and second you need to manually copy it from flash to RAM.  I think you know this already.  It's just not working for you.

    I would make the default link for the rts2800_fpu32.lib to be flash.  Then if you have select functions you want to run from RAM, you handle those specially.  The rts library will default to flash automatically, since the functions are all in the .text section and you are linking .text to flash.  So, you don't have to take any action to get the rts library into flash.  Now suppose you want the pow() function to be in RAM.  You need to know what section and what object module it resides in.  I can see in the text file you attached that it is in the .text section, pow.obj module:

       00328144    00000058              : pow.obj (.text)

    You would do this in the linker .cmd file:

    Prog_Fast  : LOAD = APP_CODE,    PAGE = 0
                 RUN = PRAML01234,   PAGE = 0
                 {
                    rts2800_fpu32.lib <pow.obj> (.text)
                 }
                 LOAD_START(_HWLINK_u16RTPROG_LoadStart),
                 LOAD_END(_HWLINK_u16RTPROG_LoadEnd),
                 RUN_START(_HWLINK_u16RTPROG_RunStart),

    If you wanted the .text section from ALL objects in the library to go into the section, you would replace the similar line with this:

                    rts2800_fpu32.lib <*> (.text)

    If you wanted EVERY section (e.g., .text for code, maybe .const for lookup tables if used, etc.) from ALL objects in the library to go into the section, you would replace the similar line with this:

                    rts2800_fpu32.lib <*> (*)

    In reality, just linking the pow.obj to RAM might not do it.  Looking at the .map file, pow() looks like it calls other functions such as log, exp, and division.  You'll need to grab those too.  Work with the .map file to figure it out.  You also might need to step through the pow() function and see what other functions it calls (or just look at the source code in the library folder).

    If you have other functions or sections that you want put in Prog_Fast, you can list them as well.  For example, suppose I had used CODE_SECTION pragmas to place some of my own functions into the Prog_Fast section already:

    Prog_Fast   : LOAD = APP_CODE,    PAGE = 0
                  RUN = PRAML01234,   PAGE = 0
                  {
                    rts2800_fpu32.lib <pow.obj> (.text)
                    *(Prog_Fast)
                  }
                  LOAD_START(_HWLINK_u16RTPROG_LoadStart),
                  LOAD_END(_HWLINK_u16RTPROG_LoadEnd),
                  RUN_START(_HWLINK_u16RTPROG_RunStart)

     

    Finally, suppose I had my own source file, call it MyFile.c, and I want the .text section from this file to go into the Prog_Fast section:

    Prog_Fast   : LOAD = APP_CODE,    PAGE = 0
                  RUN = PRAML01234,   PAGE = 0
                  {
                    rts2800_fpu32.lib <pow.obj> (.text)
                    *(Prog_Fast)
                    MyFile.obj (.text)
                  }
                  LOAD_START(_HWLINK_u16RTPROG_LoadStart),
                  LOAD_END(_HWLINK_u16RTPROG_LoadEnd),
                  RUN_START(_HWLINK_u16RTPROG_RunStart)

     

    Regards,

    David

  • David,

    It's all working perfect now while running from the RAM.

    The actual problem was that once the entire library was linked - functions had been used by other portions of the program and this caused it to collapse.

    As I manually added just the required functions - it all started to live again.

    Thanks for your support,

    Isaac

  • David,

    It is required to located few of the intrinsic functions within the fast memory.

    No linker and no intrinsic documentation could be found how to perform this.

    Could you detail the linguistic to locate, for example FS$$TOFD function,  

    within the fast memory via the threaded .cmd file?

     

    Regards,

    Isaac

    RUN = PRAML01234,

    {

        rts2800_fpu32.lib <pow.obj>  (.text)

        rts2800_fpu32.lib <exp.obj>  (.text)

        rts2800_fpu32.lib <ldexp.obj>  (.text)

        /* Needed to locate FS$$TOFD here   */

        IQmath_fpu32.lib(.text)

        *(IQmath)

        *(Prog_Fast)

    }

  • Issac,

    FS$$TOFD is not an intrinsic.  It is a function in the Compiler RTS library.  The library source is in the file rtssrc.zip file in the compiler folder of CCS (e.g., C:\TI\ccsv5\tools\compiler\c2000_6.1.4\lib).  Unzip it, and then you can search the files for the function name.  In this case, FS$$TOFD is found in the file fs_tofd.asm, which is just a shell that includes fs_tofdfpu32.inc.  If you look in fs_tofdfpu32.inc, you'll see the function is in the .text section.  So, you link the .text section from fs_tofd.obj as per my previous post in this thread.

    Regards,

    - David