星期一, 3月 14, 2005

Memory Sections

Memory Sections

The .text Section

.text section內含所有instruction部分,這個section被區分為initN和finiN等幾個部分

Note:
avr -size並不會把.data 部分initialize data也加入flash size的計算,若是要之知道實際使用的flah大小,要自己將.text和.data兩個section的size加起來(.bss就不用加)。
sram的使用量則是.data和.bss的總合

The .data Section

這個section包含所有static,有初值的data。例如

char err_str[]="Your program has died a horrible death!";
struct point pt = { 1, 1};

如果要指定.data section的起始位置,可以在compile加上-Wl,-Tdata,addr 這個option,addr就是設定的data sector起始位置。要注意的是addr必須要加上0x800000的offset,這樣linker才知道.data是在RAM space。
說明
因為AVR是harvard架構,所以linker script將RAM的位址(virtual memory address)指定在0x800000-?,所以屬於RAM的資料都要加上0x800000的offset。
所以沒有加上0x800000的話,linker會把.data的.noinit部分放在flash (.text)區域,會產生錯誤。

The .bss Section

沒有初始化的變數

The .eeprom Section

安排eeprom的空間

The .noinit Section

是.bss section的一部分,和一般.bss內的變數不一樣的是,一般宣告,沒有初始化的變數在main執行前都會被初始為0。
但是宣告
int foo __attribut__((section(".noinit")));
的變數foo,會被放在.noinit,不會被初始為0。
所以這樣宣告
int bar __attirbut__((section(".noinit")))=10;
會產生link error。
一樣,可以用-Wl,--section-start=.noinit=0x802000指定這個section的起始位置。

The .initN Section

在main之前,各階段的init code。

.init0:
Weakly bound to _init(),如果user自己定義_init(),reset後到_init()執行
.init1:
未使用,user可以自己決定
.init2:
C program時,initialize stack
.init3:
未使用,user可以自己決定
.init4:
將.data section的初值由flash copy到ram,avr-gcc將出值放在.text之後,.init的function會作copy動作。
.init5:
未使用
.init6:
C+ +使用
.init7:
未使用
.init8:
未使用
.init9:
Jump into main()

The .finiN Section

類似.initN,不過是在main呼叫exit()後依次執行的部分。
由9開始執行

.find9:
未使用
.fini8:
未使用
.fini7:
未使用
.fini6:
C+ +的destuctors
.fini5:
未使用
.fini4:
未使用
.fini3:
未使用
.fini2:
未使用
.fini1:
未使用
.fini0:
infinit loop

Using Sections in Assembly Code

#include <avrio.h>

.section .init1,"ax",@progbits
ldi   rd0,0xff
out   _SFR_IO_ADDR(PORTB),r0
out   _SFR_IO_ADDR(EERB) ,r0

Note:
"ax"的a代表allocable, x是executable,@progbits代表有reference@progbits中的data.


Using Sections in C Code

#include <avrio.h.

void my_init_portb(void) __attribut__((naked)) \
     __attribut__((section(".init1")));

void my_init_portb(void)
{
    outb(PORTB,0xff);
    outb(DDRB ,0xff);
}
這個 function (my_init_portb)因為在.init1 section,所以在main()之前就會被執行。

沒有留言:

網誌存檔