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++
12747 Discussions

Using the section attribute

Altera_Forum
Honored Contributor II
3,254 Views

Hello, 

 

I have trouble using the section attribute. 

My Nios processor runs from flash and I would like to have one function (called ReadFlash) in the FPGA internal memory (called FPGARAM1).  

 

The software developer's handbook tells me to do the following: 

int ReadFlash (FILE* fp) __attribute__ ((section (".FPGARAM1.txt"))); 

 

This builds without errors and I can download it to flash. When I run the program it boots correctly but the program stops when I call the ReadFlash function. 

I have a strong impression that my program jumps to the FPGARAM1 memory but that the program stops because the FPGARAM1 memory is empty... 

 

Can somebody tell me how I can solve this? 

 

thanks, 

Dolphin
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
1,636 Views

Hi DOLPHIN, 

 

You probably didn't use the boot-copier program -- which should relocate your elf sections as needed. 

Take a look at the flash programmer guide. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Use objdump to check that the section attribute worked correctly.  

 

Why do you need a function to read from flash? If it's a CFI flash you can read from it like memory if you're in read array mode.
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Hello smcnutt, 

 

The boot copier is used when all program memory must be copied from flash to RAM. In my program this is not the case, I only have one function that should be executed in FPGA internal RAM. Can you explain me how to use the boot copier in that case? 

 

Hi RugbyBloke, 

 

I am a beginner to Nios, can you tell me how to use&start objdump? 

 

Thanks, 

Dolphin
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Hello, 

 

I just made the objdump. It contains the following info: 

 

 

Sections: 

Idx Name Size VMA LMA File off Algn 

0 .entry 00000020 00000000 00000000 000000d4 2**5 

CONTENTS, ALLOC, LOAD, READONLY, CODE 

1 .exceptions 00000128 00000020 00000020 000000f4 2**2 

CONTENTS, ALLOC, LOAD, READONLY, CODE 

2 .text 0000a9b4 00000148 00000148 0000021c 2**2 

CONTENTS, ALLOC, LOAD, READONLY, CODE 

3 .rodata 00000610 01000000 0000aafc 0000abd0 2**2 

CONTENTS, ALLOC, LOAD, READONLY, DATA 

4 .rwdata 00000b70 01000610 0000b10c 0000b1e0 2**2 

CONTENTS, ALLOC, LOAD, DATA, SMALL_DATA 

5 .bss 00000218 01001180 01001180 0000be84 2**2 

ALLOC, SMALL_DATA 

6 .Flash 00000000 0000bc7c 0000bc7c 0000be84 2**0 

CONTENTS 

7 .FPGARAM1 00000134 01001398 0000bc7c 0000bd50 2**2 

CONTENTS, ALLOC, LOAD, READONLY, CODE 

8 .FPGARAM2 00000000 01008000 01008000 0000be84 2**0 

CONTENTS 

9 .comment 0000114d 00000000 00000000 0000be84 2**0 

CONTENTS, READONLY 

10 .debug_aranges 00000cc0 00000000 00000000 0000cfd8 2**3 

CONTENTS, READONLY, DEBUGGING 

11 .debug_pubnames 00001186 00000000 00000000 0000dc98 2**0 

CONTENTS, READONLY, DEBUGGING 

12 .debug_info 000234c4 00000000 00000000 0000ee1e 2**0 

CONTENTS, READONLY, DEBUGGING 

13 .debug_abbrev 00007cd5 00000000 00000000 000322e2 2**0 

CONTENTS, READONLY, DEBUGGING 

14 .debug_line 000140b3 00000000 00000000 00039fb7 2**0 

CONTENTS, READONLY, DEBUGGING 

15 .debug_frame 00001494 00000000 00000000 0004e06c 2**2 

CONTENTS, READONLY, DEBUGGING 

16 .debug_str 00003076 00000000 00000000 0004f500 2**0 

CONTENTS, READONLY, DEBUGGING 

17 .debug_alt_sim_info 00000020 00000000 00000000 00052578 2**2 

CONTENTS, READONLY, DEBUGGING 

18 .debug_ranges 000005a8 00000020 00000020 00052598 2**0 

CONTENTS, READONLY, DEBUGGING 

 

The FPGARAM1 and FPGARAM2 are in there as a section. My function is declared in the following way: 

 

int ReadFlash (FILE* fp) __attribute__ ((section (".FPGARAM1.txt"))); 

 

I think that this is OK. 

Is there anything else that I have to verify? 

 

thanks, 

Dolphin
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Dolphin, 

 

For your information the use of objdump is not Nios specific, it's a standard Gnu software tool. 

 

If you type nios2-elf-objdump --help you will find all the options. 

 

For your question I would type nios2-elf-objdump -D name_of_your_elf.elf > another_file 

 

It should be fairly obvious looking at another file if your function is in the correct section 

 

e.g. in a simple executable you will find 

 

Disassembly of section .exceptions: 

 

01000020 <alt_exception>: 

 

This shows that the function alt_exceptions is in the .exceptions section, just look for something else for your function/section
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Hi DOLPHIN, 

 

> The boot copier is used when all program memory must be copied from flash to RAM. 

 

Correct. 

 

> In my program this is not the case, I only have one function that should be executed 

> in FPGA internal RAM 

 

Ok ... but your code won&#39;t magically copy itself ... you&#39;ll need to do it yourself in your 

application. This is normally done with a custom linker script that will set the output section&#39;s 

LMA to a location in flash (normally adjacent to your &#39;standard&#39; stuff) and defines a few 

symbols so you can deterime the source/destination address and length. 

 

There are also a few hacks you can play with prior to a custom linker script. E.g. set the LMA to 

be adjacent to .bss (via objcopy) and use _end as the source address of your copy. The destination 

address and length can be hardcoded to match your on-chip ram. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

 

--- Quote Start ---  

originally posted by dolphin@Aug 30 2005, 08:39 AM 

in my program this is not the case, i only have one function that should be executed in fpga internal ram. 

--- Quote End ---  

 

Have you tried using FPGA internal ROM instead? 

 

When you build code or data to be stored in FPGA internal memory, the Nios II IDE will generate ".hex" files with the contents of those internal memories. Then you have to recompile the FPGA to link those memory contents to the FPGA bit image. Unfortunately, some FPGA internal memories (MRAM blocks come to mind) can&#39;t be initialized from the FPGA bit pattern this way (FYI, M512 and M4K blocks can be initialized from the bit pattern). 

 

If you set your Quartus project to "Smart Recompile", and you recompile the chip with new .hex files without changing the actual logic of the design, it will skip synthesis and fitting and just relink the .hex file data. This can save you a bunch of time. 

 

I&#39;ve got a project which uses a Nios II/e with 2K internal ROM and 512 bytes internal RAM on a EP1C3. It works fine; the CPU boots and runs from the ROM and uses the RAM for stack and globals. Granted, I had to use all the footprint-reducing tricks in the book, and there&#39;s still some dead code (_mulsi3) in there.
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Hi DOLPHIN, 

 

Forget what I said about a custom linker file ... you don&#39;t need it (it&#39;s been a while since I played 

with the hal) ... the generated linker script conveniently provides the necessary symbols. 

The script contains an output section for each memory "partition" you define, along with the symbols: 

 

_alt_partition_xxx_start 

_alt_partition_xxx_end 

_alt_partition_xxx_load_addr 

 

where xxx is the partition name. For example, with an on-chip memory named "ocm" you would have: 

 

_alt_partition_ocm_start 

_alt_partition_ocm_end 

_alt_partition_ocm_load_addr 

 

For details, you can look through your system_description/generated.x file. 

 

Anyway, to move your code from its load address (LMA) to its virtual adderss (VMA), you can use 

these symbols with something like:extern unsigned _alt_partition_ocm_start; extern unsigned _alt_partition_ocm_end; extern unsigned _alt_partition_ocm_load_addr; ... unsigned *dst = _alt_partition_ocm_start; unsigned *end = _alt_partition_ocm_end; unsigned *src = _alt_partition_ocm_load_addr; while (dst < end) *dst++ = *src++; 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
1,636 Views

Hello, 

 

I also explained my problem to the altera support and they came up with the following solution: 

# include <stdio.h># include "altera_avalon_pio_regs.h"# include "system.h"# include "sys/alt_load.h" 

 

extern void hello (void) __attribute__ ((section (".onchip_ram_64_kbytes"))); 

 

void hello() 

printf("hello from Nios II!\n"); 

 

int main() 

IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0x11); 

printf("hi\n"); 

ALT_LOAD_SECTION_BY_NAME(onchip_ram_64_kbytes); 

hello(); 

 

return 0; 

 

I&#39;ve tried it and it works fine. By doing this I don&#39;t need to study the linker script. 

 

thanks for your help, 

Dolphin
0 Kudos
Reply