Building XGATE for ICC

strict warning: Only variables should be passed by reference in /homepages/26/d141797381/htdocs/drupal-6.38/sites/all/modules/webfm/webfm.module on line 2409.

The process for building a new project for xgate is as follows:

  • Build the program with ICC12.  If this is a new program, or if the demo has been modified, the XGate thread and variable addresses will be unknown and the generated machine code within the .S19 file will not execute properly on the target.
  • Inspect the map file for memory variables shared between the cpu and xgate.  For this demo the 32 bit variable tick_counter is shared between the application and the xgate rti thread.  The following snippet is from XGATE_RTI_DEMO.mp:
       Area                               Addr   Size   Decimal Bytes (Attributes)
       --------------------------------   ----   ----   ------- ----- ------------
                                    bss   2012   0023 =     35. bytes (rel,con,rom)
    
              Addr  Global Symbol
             -----  --------------------------------
              2012  __bss_start
              2012  _tick_counter
              2016  xgate.c:xg_vectors_rpage
              2018  xgate.c:xg_vectors_addr
              2035  __bss_end
    

    The hex variable address 2012 is now placed back into the xg_threads.s file as follows:

       ; Address of tick_counter long variable is found in .mp file
       RTI_THREAD_DATA = 0x2012
    

    This address is passed to the xgate rti thread via register R1 when it starts execution.

  • The next step is to update the addresses inside the SetupXGATE() function of xgate.c.  This is an exercise in pattern recognition since you have to inspect the output (XGATE_RTI_DEMO.s19) to locate the xgate code.  The hex that you need to look for is inside the listing file for the xgate assembler code (xg_threads.lis).  Familiarity with S2 file formatting is required to parse address and data.

    Note that there is a XGATE_RAM define at the top of xgate.c that permits you to skip the ram copy procedure if you prefer to run xgate from flash, however this will throttle the co-processor to the same clock speed as the cpu.  Running out of ram allows up to double the performance.

    The xgate thread vector table begins after the 2K register space at address 0x780800 and ends at 0x7809e8.  Note that the cpu sees these addresses as 0x8800 and 0x89e8 (the 16K flash window lies between 0x8000 and 0xC000) when the ppage register is set to E0.  SetupXGATE() uses these addresses as arguments for copying the xgate thread vector table from flash to ram.

       // Copy the thread vector table to RAM
       // XDT512 has 20K of RAM starting at xgate address of 0xB000 (0x8000 for XDP512 with 32K RAM)
       // thread vector table spans 0x8800 to 0x89e8 in flash window (ppage = E0)
       // (verify table in .s19 between 0x780800 and 0x7809E8)
       // returned xg_addr is the next free address for first thread
       xg_addr = CopyXGateVectorsToRam((void*)0xB000, (void*)0x8800, (void*)0x89e8);
    

    Note that the RAM address of 0xB000 is the start of the 20K ram space of the XDT512 (XDP512 chips have 32K of ram and would copy the code to 0x8000 instead).  The return value is the end address of the copied vector table and the starting point for the first xgate thread that will be copied next.  This start address for the next thread must also be placed back into the vector table via the UpdateXGateThreadVector() function so that when the thread is scheduled to run it will be directed to the proper ram address.

       // Change the RTI vector to point to start of RTI thread in RAM
       UpdateXGateThreadVector(Vrti, xg_addr);
    

    Next we copy the RTI thread to ram using the start and end addresses found in our .s19 file.  In this demo the thread is located between 0x780A14 and 0x780A30 (Note: 0x780A30 is the address after the _RTS instruction (0x0200)).

       // Copy the RTI thread to address pointed to by RTI vector
       // (verify RTI thread in .s19 between 0x780A14 and 0x780A30)
       xg_thread.s12_flash_page  = 0xe0;           // ppage for RTI flash window
       xg_thread.s12_start       = (void*)0x8a14;  // start of RTI thread in flash window
       xg_thread.s12_stop        = (void*)0x8a30;  // end of RTI thread in flash window
       // xg_add is the next free address for next thread
       xg_addr = CopyXGateThreadToRam(xg_addr, &xg_thread);
    

    Lastly the XGVBR register is set to the start of the xgate thread vector table, the RTI interrupt is routed to xgate and the co-processor is started.

  • Build the project again to generate the correct .S19 file.
  • Upload the .S19 file to the target.  I use the NoICE debugger for this purpose.   The following is the output from the DB9 uart connector at 115200 baud:
    **xgate tests**                                                                                                                 
    (0) LED test 0                                                                                                                  
    (1) LED test 1 
    

    Hitting a 0 or 1 key inside your serial terminal will now run small test functions that utilize the RTI timer interrupt.