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.

CCS/UCD3138: Using ramfunc in UCD3138

Part Number: UCD3138

Tool/software: Code Composer Studio

Hi,

I'm trying to place my standard interrupt function in RAM, that code could be executed faster.

I'm using Code Composer Studio Version: 6.1.0.00104, and try to put __attribute__(ramfunc) before my standard interrupt,

but it doesnt work.

Is ramfunc supported in this CCS version? Is there any examples showing how to do ramfunc in UCD3138?

Thanks.

  • i've added this line:
    .ram_std_isr : { isr_standard.obj(.text) } load=PFLASH, run=RAM, table(BINIT)

    to cyclone_128.cmd, after compiling, it seems the run address of my isr function could be placed in the RAM area.

    So what is the next step?

    Duplicate the following code in load_UCD3138_128.asm to move contents specified in binit table?

    Any example code?
     
    tbl_addr .set r0
    var_addr .set r1
    tmp .set r2
    length: .set r3
    data: .set r4
    three: .set r5

    MOV three, #3 ;
    B rec_chk ;

    ;*------------------------------------------------------
    ;* PROCESS AN INITIALIZATION RECORD
    ;*------------------------------------------------------
    record: LDR var_addr, [tbl_addr, #4] ;
    ADD tbl_addr, #8 ;

    ;*------------------------------------------------------
    ;* COPY THE INITIALIZATION DATA
    ;*------------------------------------------------------
    MOV tmp, var_addr ; DETERMINE ALIGNMENT
    AND tmp, three ; AND COPY BYTE BY BYTE
    BNE _bcopy ; IF NOT WORD ALIGNED

    MOV tmp, length ; FOR WORD COPY, STRIP
    AND tmp, three ; OUT THE NONWORD PART
    BIC length, three ; OF THE LENGTH
    BEQ _wcont ;

    _wcopy: LDR data, [tbl_addr] ;
    ADD tbl_addr, #4 ;
    STR data, [var_addr] ; COPY A WORD OF DATA
    ADD var_addr, #4 ;
    SUB length, #4 ;
    BNE _wcopy ;
    _wcont: MOV length, tmp ;
    BEQ _cont ;

    _bcopy: LDRB data, [tbl_addr] ;
    ADD tbl_addr, #1 ;
    STRB data, [var_addr] ; COPY A BYTE OF DATA
    ADD var_addr, #1 ;
    SUB length, #1 ;
    BNE _bcopy ;

    _cont: MOV tmp, tbl_addr ;
    AND tmp, three ; MAKE SURE THE ADDRESS
    BEQ rec_chk ; IS WORD ALIGNED
    BIC tbl_addr, three ;
    ADD tbl_addr, #0x4 ;

    rec_chk:LDR length, [tbl_addr] ; PROCESS NEXT
    CMP length, #0 ; RECORD IF LENGTH IS
    BNE record ; NONZERO

  • I'm not sure if your code will work. You can execute from RAM, but on the UCD it doesn't run any faster.

    The only use we make of RAM execution is for modifying the program flash. While a program flash 32K block is being written or erased, it returns all FFs to all reads. So we copy code to RAM at that point.
  • There are some ways to make the code run faster. Especially if you are used to DSPs and Harvard architecture machines in general.

    On the ARM7, and many ARM cores, there is no immediate absolute addressing, but there is good relative addressing. So it's a good idea to put all the RAM variables used in a high speed code section into a single structure. That way the code will load the address of the structure into a register once, and then address the structure elements with offsets. This saves 3 instruction cycles per variable accessed, because that's how long it takes to load a 32 bit constant into a register. If you define the variables individually, you get the extra 3 cycles each time you access a variable.

    Also, the ARM7 doesn't have a single cycle read modify write, including bit set and bit clear. Every bit operation requires reading the data from memory or peripheral into a processor register, anding and/or oring it, and writing it back out. So for example for peripherals, if you can just write to the .all instead of the bit structure, you will save a little time.

    And, of course, use ARM mode, instead of Thumb mode for high speed code.

    Also use the high speed settings for the compiler.

    If you're not afraid of assembly code, the fast interrupt has some dedicated general purpose registers. You can preload them with pointers, so they don't have to be loaded during the fast interrupt execution. The C compiler doesn't support this. It does use those registers so it doesn't have to push as many register onto the stack.

    Otherwise, the standard speed up tactics work:

    1. Figure out only the things that absolutely must be in the fast loop - pre-calculate everything you can
    2. Avoid divides, pre-calculate a reciprocal and multiply if you can
    3. Unwrap loops
    4. Use inline for all functions called by the high speed loop. For inline to work, the function and the calling function must be in the same file.
    and so on.