Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

Nios2 stack size?

Altera_Forum
Honored Contributor II
1,892 Views

Hi all! 

I know this topic has been discussed more than once in this forum, but i did not find a sufficient answer. So please show mercy. 

Question: 

How do i find out how much memory is resevered for the nios2 stack by the compiler? (I am using Nios2 IDE 9.1 SP2) 

I mean the stack where temporary variables, function-call-return-addresses, etc are stored. I do not mean any kind of TCPIP stack. 

And if somebody could tell me how to change the size of this stack, you would make me very happy. 

Regards 

 

Btw: Sorry to all the guys that wrote answers to my last thread about EPCS memory. I could not reply to your posts because for some strange reason the thread does not accept any new posts by me.
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
984 Views

The compiler doesn't 'reserve' stack - just uses it! 

The amount of memory allocated to the stack will be defined by a combination of the linker script, defined memory areas and the system startup code. 

If you have a single memory area it is likely (I don't use the defaults [1]) that it will be filled with code/rodata, data, bss, heap, stack in that order. 

So if things go awry the stack crashes down into the heap (can be very difficult to diagnose, since minor code changes break unrelated things). 

 

The information in the memory map output file from the linker probably contains useful info. 

 

[1] The only stack references I have are where the function prologue (of a function that doesn't ever return) saves registers on entry! The relatively small code (fits in 8k of tightly coupled instruction memory) is compiled as a single unit with all functions inlined and no on-stack locals (or other register spills).
0 Kudos
Altera_Forum
Honored Contributor II
984 Views

Hi dsl! 

Ok, perhaps it is not the compiler who reserves the memory area for the stack, perhaps it is the linker. 

But i still want to tell this "thing" that reserves this memory: 

"Please use 1024 bytes for the stack. 

And please do not use any memory for the heap. 

I don't have any dynamic memory allocation." 

How do i do this? 

Regards
0 Kudos
Altera_Forum
Honored Contributor II
984 Views

If you are being that careful/concerned about memory allocation then you'll almost certainly need to write your own startup code (rather than using the code that Altera's build system includes). This isn't that difficult as you only need to set the %gp and %sp (and maybe %et) registers from code at the cpu's reset entry point before jumping to the first C function. 

 

This can be done from a .S file, but given the small number of instructions I hand assembled them and put them directly into the linker script. This gives something like (edited for inclusion here). 

 

MEMORY { code_memory (x) : ORIGIN = 0x8000, LENGTH = 8k data_memory (rw) : ORIGIN = 0x14000, LENGTH = 48k } /* Memory from 0x14000 to 0x24000 is accessible from %gp */ _gp = 128k - 16k; STACK_SIZE = 1024; /* Constants for building instructions by hand */ RA_SHIFT = 32 - 5; RB_SHIFT = RA_SHIFT - 5; RC_SHIFT = RB_SHIFT - 5; OP_SHIFT = RC_SHIFT - 6; IMM16_SHIFT = 6; SECTIONS { /* code - at reset vector */ code : { /* Instuctions to set %gp */ LONG(0 << RA_SHIFT | 26 << RB_SHIFT | ((_gp + 32768) >> 16) << IMM16_SHIFT | 0x34) LONG(26 << RA_SHIFT | 26 << RB_SHIFT | (_gp & 0xffff) << IMM16_SHIFT | 0x4) /* Set %sp by adding affset from %gp */ LONG(26 << RA_SHIFT | 27 << RB_SHIFT | 0x4 | ((stack_top - _gp) & 0xffff) << IMM16_SHIFT) LONG(main << 4 | 1) /* jmpi main() */ . = 0x20; /* Add exception (aka interrupt) code here */ .... *(.text) /* add other sections */ } >code_memory data : { stack_limit = .; . = . + STACK_SIZE; stack_top = .; *(.sdata*) *(.rodata) /* add other sections */ } >data_memory }
0 Kudos
Altera_Forum
Honored Contributor II
984 Views

Hi dsl! 

> If you are being that careful/concerned about memory allocation 

Unfortunately i have to. I am using a cyclone2 (EP2C20Q240C8N) without any external memory except an EPCS device. Because of this i don't have that much OnChipRam/Rom. 

But isn't it possible to just modify the startup code that Altera's build system includes to change stack size? 

If this is possible, i would still need a hint where to look for the Altera startup code (which file)... 

I feel a little reluctant towards writing my own startup code, because of my lack of information about this topic. 

Regards
0 Kudos
Altera_Forum
Honored Contributor II
984 Views

I'd expect the stack to start at the highest address of the data memory area, so the amount of memory available for the stack is defined by the size of the rest of the system! 

 

If you are squeezing code into a small space, you probably need to be careful not to include much (if any) of libc - so check the namelist of your elf image in case anything has got added. You probably want to stop malloc() and friends being included, which may constrain which altera libs you specify. I'm not sure that their small libs don't still call malloc() during initialisation. 

 

If you've managed to exclude malloc from your build (I don't know if altera's low level jtag uart code needs malloc - but you can write functions for tracing strings and integers that don't) then the only initialisation you need is setting %sp and %gp (and zero .bss - which can be done from C). 

 

If you only have on-chip memory, then it is probably worth using tightly coupled I & D memory (you'll need a minimal I-cache to use the jtag or epcs loader). When I started doing that I had to use a non-standard linker script to get the program headers to load the data to the required target addresses - rather than adding code to copy initialised data from the end of the code to the target address. 

 

You can also reduce the code size by making all data memory and IO be within 64k and marking everything as .sdata or .sbss so that the compiler generates %gp relative addesses. You might need to rebuild the compiler (with my patches from the wiki) in order to get %gp relative addressing for structure members.
0 Kudos
Reply