What is the usage of ISTACK, USTACK and CSA?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User17612
Level 4
Level 4
First like received
Hi all,

could you please help me with the following questions: What is the difference of ISTACK, USTACK and CSA? How are they allocated in RAM?

Thanks in advance and BR
L.


#8042000 12618
1 Reply
User17740
Level 4
Level 4
First solution authored First like received
Hi Lucas,


ISTACK, USTACK and CSA are three different regions in DSPR.

ISTACK is used to store local variables before the code is interrupted by ISR, the local variables are pushed into ISTACK when entering interrupt and popped out when exiting interrupt.
USTACK is used to store local variables when calling sub function in a function, the local variables are pushed into USTACK when entering the sub function and popped out when exiting sub function.
It depends on PSW.IS bit whether the ISTACK and USTACK are independent or shared. When PSW.IS is set to 0, the interrupt routine will use ISTACK as stack and the stack point register will load from ISP at the beginning of interrupt. When PSW.IS is set to 1, the interrupt routine will also use user stack.
CSA is used to store context, the so-call context consists of upper context and lower context as shown in --> image_1, attached.


Generally speaking, upper context registers are stored and restored automatically, and the store and restore of lower context depends on some instructions, like BISR, SVLCX, STLCX.
BISR (Begin Interrupt Service Routine): this instruction may be used to store lower context register at the beginning of ISR, when the ISR is simple which don’t use lower context registers, this instruction will not be used, when the ISR is complex which use lower context registers, this instruction will be used.
SVLCX (Store Lower Context): this instruction may be used to store lower context register at the beginning of a function, when the function is simple which don’t use lower context registers, this instruction will not be used, when the function is complex which use lower context registers, this instruction will be used.
STLCX (Restore Lower Context): this instruction is used to restore lower context registers from CSA which may be used when exiting an ISR or function.
In DSPR, CSA with 16 word alignment is constructed by list, there are 2 lists, one indicates free CSA and the other indicates used CSA, FCX register stores the address of first free block in CSA, LCX register stores the address of last free block in CSA, PCX register stores the address of first used block in CSA.
--> See image_2


Every time a function is called, FCX will decrease and PCX will increase. For example, before calling IfxCpuSyncDemo_init(), FCX is 0x00070670,PCXI is 0。
--> See image_3


After entering IfxCpuSyncDemo_init(), FCX changes to 0x00070671 and PCXI changes to 0x00x70670
--> See image_4

After calling IfxCpuSyncDemo_init(), FCX and PCXI recover.
Each core of Aurix has its own DSPR, in the default setting in LSL file, CSA, ISTACK USTACK, HEAP are placed in own DSPR of each CPU, but DATA and BSS of all CPUs are placed in one of DSPR. For example, in LSL file, if the definition is shown as below, DATA and BSS are placed in DSPR0.

REGION_ALIAS( default_ram , dsram0)
/REGION_ALIAS( default_ram , dsram1)/
/REGION_ALIAS( default_ram , dsram2)/



CSA, ISTACK, USTACK and HEAP are allocated each DSPR as below, in startup file, after calling IfxCpu_initCSA(), FCX and LCX registers are initialized, afterward, ISTACK and USTACK pointer are initialized.
--> See image_5


The memory map of CSA, ISTACK, USTACK and HEAP are defined in LSL file as below, while DATA and BSS are allocated only in one of DPSR.

LCF_CSA2_OFFSET = (LCF_DSPR2_SIZE - 1k - LCF_CSA2_SIZE);
LCF_ISTACK2_OFFSET = (LCF_CSA2_OFFSET - 256 - LCF_ISTACK2_SIZE);
LCF_USTACK2_OFFSET = (LCF_ISTACK2_OFFSET - 256 - LCF_USTACK2_SIZE);

LCF_CSA1_OFFSET = (LCF_DSPR1_SIZE - 1k - LCF_CSA1_SIZE);
LCF_ISTACK1_OFFSET = (LCF_CSA1_OFFSET - 256 - LCF_ISTACK1_SIZE);
LCF_USTACK1_OFFSET = (LCF_ISTACK1_OFFSET - 256 - LCF_USTACK1_SIZE);

LCF_CSA0_OFFSET = (LCF_DSPR0_SIZE - 1k - LCF_CSA0_SIZE);
LCF_ISTACK0_OFFSET = (LCF_CSA0_OFFSET - 256 - LCF_ISTACK0_SIZE);
LCF_USTACK0_OFFSET = (LCF_ISTACK0_OFFSET - 256 - LCF_USTACK0_SIZE);

LCF_HEAP0_OFFSET = (LCF_USTACK0_OFFSET - LCF_HEAP_SIZE);
LCF_HEAP1_OFFSET = (LCF_USTACK1_OFFSET - LCF_HEAP_SIZE);
LCF_HEAP2_OFFSET = (LCF_USTACK2_OFFSET - LCF_HEAP_SIZE);

3745.attach3746.attach3747.attach3748.attach3749.attach


Hope this helps you,

BR,
Bernie