(原創) 如何將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 II EDS,我們只能做以下的設定,看要使用哪一種記憶體:
並無法單純的用設定的方式可以指定array或變數單獨建立在哪一塊記憶體上,但我們知道onchip memory與SSRAM速度最快,若將常用的變數或陣列單獨建立在onchip memory或者SSRAM上,對於Nios II整體速度將有幫助,但要如何將array建立在SSRAM上呢?答案是使用GCC所提供的attribute。
Solution
hello_world.c / C
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行
利用__attribue__將array ia[]宣告再SSRAM上。
看到這裡,你一定會問,一定要宣告在main()外面嗎?在Altera原廠的Nios II Software Developers's Handbook p.6-42 Assigning Code and Data to Memory Partitions這一節中有以下敘述:
也就是一定要放在main()之前的function prototype區才可以,不能放在function內。
當然不只能用於array而以,變數,function都可以利用attribute放在指定的記憶體內。
另外一個問題,就是我怎麼知道有哪些記憶體section可以放?有以下兩個方法
Method 1:
查看Nios II EDS
以上列的,就是記憶體可用的section name。
Method 2:
查看linker script
\DE2_70_NIOS_10_attribute\software\hello_world_0_syslib\Debug\system_description\generated.x
generated.x很長,我只節錄與section相關部分
{
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,我們卻可以靈活的使用記憶體,增加程式整體的效率。