(原創) 如何將array宣告在SSRAM上? (SOC) (Nios II)

Abstract
DE2/DE2-70上有很多記憶體,有onchip memory、SSRAM、SDRAM、Flash,各有各的優缺點,如何將變數或array放在特定的記憶體上呢?

Introduction
使用環境:Quartus II 8.0 + Nios II EDS 8.0 + DE2-70 (Cyclone II EP2C70F896C6N)

DE2 Dev網上論壇中,網友Mithril問了以下問題

在建立nios的時候,放進了SSRAM、SDRAM、FLASH,在nios ide中設定程式跟資料都放在SDRAM上,這樣要如何宣告告一個陣列放在SSRAM上面呢?


在Nios II EDS,我們只能做以下的設定,看要使用哪一種記憶體:

nios_ssram00

並無法單純的用設定的方式可以指定array或變數單獨建立在哪一塊記憶體上,但我們知道onchip memory與SSRAM速度最快,若將常用的變數或陣列單獨建立在onchip memory或者SSRAM上,對於Nios II整體速度將有幫助,但要如何將array建立在SSRAM上呢?答案是使用GCC所提供的attribute

Solution

hello_world.c / C

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : hello_world.c
5 Compiler    : Nios II EDS 8.0 / ANSI C
6 Description : Demo how to declare array in SSRAM
7 Release     : 11/11/2008 1.0
8 */
9 
10 #include <stdio.h>
11 
12 // declare array in SSRAM
13 int ia[3] __attribute__ ((section(".ssram")));
14 
15 int main() {
16   int i;
17  
18   // write to array
19   for(i = 0; i < 3; ++i)
20     ia[i] = i;
21  
22   // read from array 
23   for(i = 0; i < 3; ++i)
24     printf("%d\n", ia[i]);
25  
26   return 0;
27 }
28 


13行

int ia[3] __attribute__ ((section(".ssram")));


利用__attribue__將array ia[]宣告再SSRAM上。

看到這裡,你一定會問,一定要宣告在main()外面嗎?在Altera原廠的Nios II Software Developers's Handbook p.6-42 Assigning Code and Data to Memory Partitions這一節中有以下敘述:

Within your program source code, you can specify a target memory section for each piece of code. In C or C++, you can use the section attribute. This attribute must be place in a function prototype, you cannot place it in the function declaration itself.


也就是一定要放在main()之前的function prototype區才可以,不能放在function內。

當然不只能用於array而以,變數,function都可以利用attribute放在指定的記憶體內。

另外一個問題,就是我怎麼知道有哪些記憶體section可以放?有以下兩個方法

Method 1:
查看Nios II EDS

nios_ssram01

以上列的,就是記憶體可用的section name。

Method 2:
查看linker script

\DE2_70_NIOS_10_attribute\software\hello_world_0_syslib\Debug\system_description\generated.x

generated.x很長,我只節錄與section相關部分

.onchip_mem :
    {
        PROVIDE (_alt_partition_onchip_mem_start
= ABSOLUTE(.));
        *(.onchip_mem .onchip_mem.*)
        .
= ALIGN(32 / 8);
        PROVIDE (_alt_partition_onchip_mem_end = ABSOLUTE(.));
    } > onchip_mem

    PROVIDE (_alt_partition_onchip_mem_load_addr
= LOADADDR(.onchip_mem));

    .sdram_u1 :
    {
        PROVIDE (_alt_partition_sdram_u1_start
= ABSOLUTE(.));
        *(.sdram_u1 .sdram_u1.*)
        .
= ALIGN(32 / 8);
        PROVIDE (_alt_partition_sdram_u1_end = ABSOLUTE(.));
        _end = ABSOLUTE(.);
        end = ABSOLUTE(.);
        __alt_stack_base = ABSOLUTE(.);
    } > sdram_u1

    PROVIDE (_alt_partition_sdram_u1_load_addr
= LOADADDR(.sdram_u1));

    .sdram_u2 :
    {
        PROVIDE (_alt_partition_sdram_u2_start
= ABSOLUTE(.));
        *(.sdram_u2 .sdram_u2.*)
        .
= ALIGN(32 / 8);
        PROVIDE (_alt_partition_sdram_u2_end = ABSOLUTE(.));
    } > sdram_u2

    PROVIDE (_alt_partition_sdram_u2_load_addr
= LOADADDR(.sdram_u2));

    .ssram :
    {
        PROVIDE (_alt_partition_ssram_start
= ABSOLUTE(.));
        *(.ssram .ssram.*)
        .
= ALIGN(32 / 8);
        PROVIDE (_alt_partition_ssram_end = ABSOLUTE(.));
    } > ssram

    PROVIDE (_alt_partition_ssram_load_addr
= LOADADDR(.ssram));

    .cfi_flash :
    {
        PROVIDE (_alt_partition_cfi_flash_start
= ABSOLUTE(.));
        *(.cfi_flash .cfi_flash.*)
        .
= ALIGN(32 / 8);
        PROVIDE (_alt_partition_cfi_flash_end = ABSOLUTE(.));
    } > cfi_flash


以上顯示出可使用記憶體的section name,其實Nios II EDS所顯示的section name也是根據linker script而來。

完整程式下載
DE2_70_NIOS_10_attribute.7z

Conclusion
以前在寫PC的程式時,我們根本無法指定array、變數或者function放在哪塊記憶體上,但在DE2/DE2-70,我們卻可以靈活的使用記憶體,增加程式整體的效率。

posted on 2008-11-12 00:25  真 OO无双  阅读(3811)  评论(2编辑  收藏  举报

导航