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++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Software size is too big

Altera_Forum
Honored Contributor II
2,510 Views

Hello guys, i've tried small C lib, reduced device drivers and everything else but nothing works.. 

 

I am using Quartus V10.0SP1 and NIOSEDS V10.0SP1, A hello word simple program with a printf takes 4k of onchip mem... that's impossible right? I must be doing something wrong.  

 

It's the hello word example when creating a new project 

 

# include <stdio.h> int main() { printf(" Hello world!"); return 0; } 

 

It always overlap the sections .rwdata, heap and others.. Even if my onchipmemory is 10K Bytes.
0 Kudos
17 Replies
Altera_Forum
Honored Contributor II
1,250 Views

 

--- Quote Start ---  

A hello word simple program with a printf takes 4k of onchip mem... that's impossible right?  

--- Quote End ---  

 

That could be quite normal: a complete printf implementation requires a lot of code. You must also account for the driver code which redirects the printf output string to the stdout device (i.e. jtag uart). 

Did you try the compiler directive -Os? This should optimise code size. 

Anyway, if your 4k code doesn't fit in a 10k memory, this is probably due to stack/heap or any data memory required by the stdio library and driver.
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Well in another project i have a code with plenty of printfs and other stuffs, the code is 400 lines wide and the code size is 8k.

0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Find the elf program file for your working and non-working projects and look at the symbols (nm file, or objdump -n file) and program sections (objdump -p file). That might help to identify the bloat. 

The altera printf() pulls in a lot of code! 

 

I suspect it maps to fprintf(stdout, ...) so requires large tracts of stdio rather that being implemented as a console write - as a unix kernel's printf() is usually implemented. 

 

After all, the likelyhood of wanting an actual stdio implementation on a real fpga embedded application is minimal.
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Maybe it is because you have included <stdio.h>. This is a lot of code which should be compiled even if you are not using all of it.

0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

dsl, how can i use the unix printf then? 

I made the following changes and the code size went down from 28k to 13kbytes (A NORMAL PRINTF) 

 

template BSP/syslib: 

- uncheck Support C++ em properties->C/C++ Build do BSP Template  

- check Lightweight device driver no BSP Editor 

- check Reduced device drivers no BSP Editor 

- uncheck enable_clean_exit no BSP Editor 

- uncheck enable_exit no BSP Editor 

- configure optimize level to Size on properties->C/C++ Build do BSP Template  

- configure Debug level to none on properties->C/C++ Build do BSP Template 

 

 

 

Software: 

- configure optimize level to Size em properties->C/C++ Build do BSP Template  

- configure Debug level to none em properties->C/C++ Build do BSP Template 

 

 

IF I CHANGE the code to this  

#include "sys/alt_stdio.h" //#include <stdio.h> int main() { //printf("Hello from Nios II!\n"); alt_putstr("Hello from Nios II!\n"); return 0; }  

 

the size goes to 600bytes
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Other question is, how to read from the keyboard? I want nios to be a calculator and ask from jtag (nios-terminal) two numbers to sum. 

 

How can i do that? Scanf is too large..
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Try getc and elaborate yourself the keystrokes sequence

0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

gets(bitrate); // alt_putchar(c); //} alt_putstr(bitrate);  

 

This works fine. But why it is initiatilized with some random values? If i type 101 it apears as a101 or sometimes b101 or sometimes ffef101
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

something like (untested): 

void put_uint(unsigned int x) { char b, *p = b + 9; unsigned int n; b = 0; do { n = x / 10; *--p = '0' + (x - n * 10); } while ((x = n) != 0); alt_putstr(p); }will output an unsigned value to the terminal in decimal. 

The above will pull in the libc function to do divide (unless you added the hardware instruction and told gcc to use it). 

The 'divide by constant' can be replaced by a multiply and shift, but that requires the 64bit result from the multiply - which altera don't have support for on the older fpgas (needs the DSP based multiply) and might need a 64bit shift. Splitting the value into two 16bit values does make this possible (I've done that to avoid needing 64bit divide when converting 'long long'.) 

 

Writing printf() is just a SMOP (simple matter of programming).
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Thanks for the code dsl, i am going to use. Can you look at my older post please? I"ve edited it

0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

 

--- Quote Start ---  

And when i start the program sometimes getchar() get some random numbers.. 

--- Quote End ---  

 

Use getchar() at the beginning of your code to make the char buffer empty. 

while (getchar() != EOF) 

/* wait */;
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Oh, you really don't want to be using gets() - it will write past the end of your buffer at some point! 

The normal recommendation is to use fgets(), but that may not be appropraite here - your own loop calling getchar() is probably better.
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

 

--- Quote Start ---  

Use getchar() at the beginning of your code to make the char buffer empty. 

while (getchar() != EOF) 

/* wait */; 

--- Quote End ---  

 

it seems like i never get end of file.. the program never comes back.
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

Mmm... I do the same and works fine. 

Maybe you have some device which continously puts data on stdin? 

Have you considered if the received chars show you some hint? Or are they completely random?
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

They are completly random. I have some optimization configuration in my project.. the ones i posted in the 1st page, maybe it has something to do with it? 

 

 

Here 

 

template BSP/syslib: - uncheck Support C++ em properties->C/C++ Build do BSP Template - check Lightweight device driver no BSP Editor - check Reduced device drivers no BSP Editor - uncheck enable_clean_exit no BSP Editor - uncheck enable_exit no BSP Editor - configure optimize level to Size on properties->C/C++ Build do BSP Template - configure Debug level to none on properties->C/C++ Build do BSP Template Software: - configure optimize level to Size em properties->C/C++ Build do BSP Template - configure Debug level to none em properties->C/C++ Build do BSP Template
0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

# include "sys/alt_stdio.h" # include <stdio.h> void put_uint(unsigned int x); int main() { unsigned int c; c=0; alt_putstr("Informe o bitrate e digite enter!\n"); while (c!=10){ c = getchar(); put_uint(c); //alt_putchar(c); } return 0; } void put_uint(unsigned int x) { char b, *p = b + 9; unsigned int n; b = 0; do { n = x / 10; *--p = '0' + (x - n * 10); } while ((x = n) != 0); alt_putstr(p); }  

Is this how am i suposed to use your function? It shows a number for each keyboard key i touch but not the actual number that the key represents =p 

 

Sorry for this stupid questions but i am really new to the "low level" C.. 

 

 

 

--- Quote Start ---  

something like (untested): 

void put_uint(unsigned int x) { char b, *p = b + 9; unsigned int n; b = 0; do { n = x / 10; *--p = '0' + (x - n * 10); } while ((x = n) != 0); alt_putstr(p); }will output an unsigned value to the terminal in decimal. 

The above will pull in the libc function to do divide (unless you added the hardware instruction and told gcc to use it). 

The 'divide by constant' can be replaced by a multiply and shift, but that requires the 64bit result from the multiply - which altera don't have support for on the older fpgas (needs the DSP based multiply) and might need a 64bit shift. Splitting the value into two 16bit values does make this possible (I've done that to avoid needing 64bit divide when converting 'long long'.) 

 

Writing printf() is just a SMOP (simple matter of programming). 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
1,250 Views

NVM, Found the problem..

0 Kudos
Reply