22.08.2013 Views

Statiska moduler och buffrar

Statiska moduler och buffrar

Statiska moduler och buffrar

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Institutionen för data- <strong>och</strong> elektroteknik<br />

2004-02-22<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Inledning<br />

En statisk modul bevaras i programminnet mellan bootsidor genom att länkaren ser till att<br />

den hamnar i en del av programminnet som inte skrivs över då vi bootar in en ny bootsida.<br />

Modulen kan alltså anropas från flera bootsidor. Kom dock ihåg att den statiska modulen<br />

läses in tillsammans med den bootsida där den är deklarerad, innan dess finns inte modulen<br />

i minnet <strong>och</strong> kan alltså inte anropas. Det betyder att vill vi från bootsida 2 anropa en statisk<br />

modul som finns deklarerad på bootsida 3 så måste bootsida tre ha varit inbootad (inläst)<br />

innan bootsida 2 bootas in om vi skall kunna anropa den statiska modulen från bootsida 2.<br />

Dock kan bootsida 2 vara inbootad före bootsida 3 om vi ser till att inte anropa den statiska<br />

modulen förrän bootsida 3 har varit inläst.<br />

På samma sätt bevaras en statisk buffer mellan bootsidor <strong>och</strong> gör att variabler <strong>och</strong> data kan<br />

överföras mellan bootsidor. Länkaren ser alltså till att denna buffer inte skrivs över då en<br />

ny bootsida laddas in. Skall en statisk buffer från början vara initierad med värden så måste<br />

den bootsida där allokering <strong>och</strong> initiering sker läsas in innan bufferten kan användas på<br />

andra bootsidor.<br />

Vi skall bekanta oss med statiska <strong>moduler</strong> <strong>och</strong> variabler samtidigt som vi ser på hur vi kan<br />

hantera flera bootsidor genom att studera ett förenklat exempel som inte har annan funktion<br />

än att illustrera hanterandet av flera bootsidor <strong>och</strong> statiska <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong>, den<br />

programkod som finns i olika <strong>moduler</strong> saknar alltså direkt funktion <strong>och</strong> är närmast utfyllnad.<br />

Vi ser dock till att <strong>moduler</strong>na har lite olika längd för att se hur länkaren hanterar<br />

detta.. Vi ser också på skillnader i allokering mellan linjära (raka) <strong>och</strong> cirkulära <strong>buffrar</strong>. På<br />

samma gång tar vi tillfället i akt att studera vilken information en minnesallokeringsfil, en<br />

MAP-fil, ger.<br />

CHALMERS LINDHOLMEN Sida 1<br />

Institutionen för data- <strong>och</strong> elektroteknik<br />

Sven Knutsson<br />

Box 8873<br />

402 72 Göteborg<br />

Besöksdress: Hörselgången 4<br />

Telefon: 31-772 57 27<br />

Fax: 31-772 57 31<br />

E-mail: svenk@chl.chalmers.se<br />

Web: www.chl.chalmers.se/∼svenk


Exempel<br />

Förutsättningar<br />

Vi antar att vi har ett system som skall bestå av tre bootsidor, bootsida 0, 1 <strong>och</strong> 2.<br />

På bootida 0 har vi en submodul (subrutin) kallad sub_0_0 som är deklarerad som<br />

statisk. Denna modul anropas även från bootsida 2. Vi har dessutom på bootsida 0 en<br />

lokal submodul sub_0_1 som bara anropas från det egna huvudprogrammet.<br />

På bootsida 1 har vi en statisk modul, sub_1, som även den anropas från bootsida 2.<br />

På bootsida 0 har vi ett antal <strong>buffrar</strong> enligt nedan<br />

Buffertnamn Längd Cirkulär Statisk Minnestyp<br />

dm_x 10 ja ja DM<br />

dm_0_0 30 ja nej DM<br />

dm_0 15 nej nej DM<br />

dm_y 8 nej ja DM<br />

dm_0_1 6 nej nej DM<br />

pm_x 22 nej ja PM<br />

Bootsida 1 har <strong>buffrar</strong>na<br />

Buffertnamn Längd Cirkulär Statisk Minnestyp<br />

dm_1_0 7 ja nej DM<br />

dm_x 10 ja nej DM<br />

dm_z 19 ja ja DM<br />

dm_0 15 nej nej DM<br />

dm_1_1 14 nej nej DM<br />

pm_1_0 12 nej nej PM<br />

Även bootsida 2 har ett antal <strong>buffrar</strong><br />

Buffertnamn Längd Cirkulär Statisk Minnestyp<br />

dm_2_0 13 nej nej DM<br />

dm_2_1 27 ja nej DM<br />

dm_x 10 ja ja DM (från bootsida 0)<br />

dm_y 8 nej ja DM (från bootsida 0)<br />

dm_z 19 ja ja DM (från bootsida 1)<br />

Lägg märke till att vi i dataminnet har tre <strong>buffrar</strong> som är statiska. Av dessa skall två vara<br />

synliga på bootsida 0 <strong>och</strong> 2 (dm_x <strong>och</strong> dm_y) <strong>och</strong> en (dm_z) som skall vara synlig på<br />

bootsida 1 <strong>och</strong> 2.<br />

I programminnet finns en statiskt deklarerad buffer, denna skall bara vara synlig på bootsida<br />

0. Att denna buffer är statisk betyder här då inte att vi vill nå den från flera bootsidor<br />

utan att den skall behålla sina värden mellan de gånger då vi bootar in bootsida 0.<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 2


Observera också att det även på bootsida 1 finns en buffer med namnet dm_x i dataminne<br />

men denna är inte deklarerad som statisk <strong>och</strong> den är inte synlig från andra bootsidor<br />

<strong>och</strong> då gör det inget att den har samma namn som en buffert på bootsida 0.<br />

Lägg dessutom märke till att på både bootsida 0 <strong>och</strong> 1 har vi deklarerat en buffer i dataminnet<br />

med namnet dm_0 men ingen av dessa <strong>buffrar</strong> är deklarerad som statisk <strong>och</strong><br />

var <strong>och</strong> en av de två <strong>buffrar</strong>na är då en separat buffer som är lokal för sin bootsida.<br />

Övriga <strong>buffrar</strong> är helt skilda, även vad gäller namn, mellan de tre bootsidorna.<br />

För att undersöka hur länkaren hanterar minnet så är <strong>buffrar</strong>na medvetet lagda i en ordning<br />

som blandar olika typer av <strong>buffrar</strong>. Eftersom minnesallokeringen sker på olika sätt<br />

i program- <strong>och</strong> dataminne så finns en buffer deklarerad i programminne. Det som skiljer<br />

mellan minnestyperna är buffertarnas placering i minne. Vad som sägs om synlighet etc<br />

gäller båda minnestyperna.<br />

För att illustrera förloppet så lägger vi upp en arkitekturfil samt en enkel huvudmodul<br />

<strong>och</strong> några sub<strong>moduler</strong> för respektive bootsida. Vi länkar resultatet <strong>och</strong> låter länkaren<br />

generera en MAP-fil där vi kan se minnestilldelningen.<br />

Arkitekturfil<br />

Vi skriver en enkel arkitekturfil för ett system som bara har internt data- <strong>och</strong> programminne.<br />

Filen måste deklarera tre bootminnesareor, en per bootsida. Dessa areor måste<br />

ha olika namn. Vi får<br />

{ADSP2105-system med bara internt minne}<br />

.SYSTEM minimalt_2105_system; {system name}<br />

.ADSP2105; {2105 system}<br />

.MMAP0; {boot load enable}<br />

.SEG/ROM/BOOT=0 boot_mem0[1024]; {boot page 0}<br />

.SEG/ROM/BOOT=1 boot_mem1[1024]; {boot page 1}<br />

.SEG/ROM/BOOT=2 boot_mem2[1024]; {boot page 2}<br />

.SEG/PM/RAM/ABS=0/CODE/DATA int_pm[1024]; {internal program memory}<br />

.SEG/DM/RAM/ABS=14336/DATA int_dm[512]; {internal data memory}<br />

.ENDSYS;<br />

Observera alltså att minnesareorna för de tre bootsidorna måste ges olika namn.<br />

Assemblerfiler<br />

Bootsida 0<br />

Vi gör ett enkelt program som bara deklarerar ett antal <strong>buffrar</strong> anropar ett par sub<strong>moduler</strong><br />

<strong>och</strong> sedan lägger sig i IDLE-läge.<br />

{ADSP-2105 Huvudprogram för test av statiska}<br />

{cirkulära variabler <strong>och</strong> <strong>moduler</strong> }<br />

{bootsida 0}<br />

.MODULE/RAM/BOOT=0/ABS=0 mainmodul_0;<br />

.VAR/DM/RAM/STATIC/CIRC dm_x[10]; {statisk cirkulär buffer}<br />

{synlig på bootsida }<br />

{0 <strong>och</strong> 2 }<br />

.VAR/DM/RAM/CIRC dm_0_0[30]; {lokal cirkulär buffer}<br />

.VAR/DM/RAM dm_0[15]; {lokal buffer}<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 3


.VAR/DM/RAM/STATIC dm_y[8]; {statisk buffer synlig}<br />

{på bootsida 0 <strong>och</strong> 2 }<br />

.VAR/DM/RAM dm_0_1[6]; {lokal buffer}<br />

.VAR/PM/RAM/STATIC pm_x[22]; {statisk buffer synlig}<br />

{på bootsida 0 }<br />

.GLOBAL dm_x,dm_y; {dm_x <strong>och</strong> dm_y synliga}<br />

{på andra bootsidor }<br />

.EXTERNAL sub_0_0,sub_0_1; {sub<strong>moduler</strong>}<br />

JUMP start; nop; nop; nop; {restart interrupt}<br />

RTI; nop; nop; nop; {sampling interrupt IRQ2}<br />

RTI; nop; nop; nop; {SPORT0 transmit}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT0 receive}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT1 transmit}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT1 receive}<br />

{interrupt }<br />

RTI; nop; nop; nop; {TIMER interrupt}<br />

start: CALL sub_0_0; {anropa statisk submodul}<br />

CALL sub_0_1; {anropa submodul}<br />

wait: IDLE; {wait for interrupt}<br />

JUMP wait;<br />

.ENDMOD;<br />

Lägg märke till att de <strong>buffrar</strong> som skall vara synliga på andra bootsidor måste deklareras<br />

som globala via direktivet .GLOBAL.<br />

Eftersom vi inte vill nå den statiska bufferten pm_x i programminnet från andra <strong>moduler</strong><br />

så är denna inte deklarerad som GLOBAL. Bufferten är deklarerad som statisk<br />

för att variabelvärdena i denna buffer skall ligga kvar om vi efter att vi har låtit programmet<br />

boota in en annan bootsida åter vill läsa in bootsida 0 via en ny mjukvarustyrd<br />

bootning.<br />

Programmet anropar de två sub<strong>moduler</strong>na sub_0_0 <strong>och</strong> sub_0_1, där den första<br />

är statisk medan den andra är dynamisk.<br />

Submodul 0_0<br />

På bootsida 0 har vi en statisk submodul som anropas med labeln sub_0_0. Modulen<br />

har programkoden<br />

{ADSP-2105 Submodul för test av statiska}<br />

{icke-cirkulära variabler <strong>och</strong> <strong>moduler</strong> }<br />

{bootsida 0}<br />

.MODULE/RAM/BOOT=0/STATIC submodul_0_0;<br />

.EXTERNAL dm_y;<br />

.ENTRY sub_0_0;<br />

sub_0_0:AX0=DM(dm_y);<br />

AR=NOT AX0;<br />

DM(dm_y)=AR;<br />

RTS;<br />

.ENDMOD;<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 4


Submodul 0_1<br />

På bootsida 0 har vi också en submodul som inte är statisk utan dynamisk <strong>och</strong><br />

som anropas med labeln sub_0_1. Modulen har programkoden<br />

{ADSP-2105 Submodul för test av statiska}<br />

{cirkulära variabler <strong>och</strong> <strong>moduler</strong> }<br />

{bootsida 0}<br />

.MODULE/RAM/BOOT=0 submodul_0_1;<br />

.EXTERNAL dm_y;<br />

.ENTRY sub_0_1;<br />

sub_0_1:AX0=AY0;<br />

AY0=MX1;<br />

RTS;<br />

.ENDMOD;<br />

Bootsida 1<br />

Bootsida 1 får i princip samma enkla program som bootsida 0, men med sina variabler<br />

<strong>och</strong> sub<strong>moduler</strong> naturligtvis.<br />

{ADSP-2105 Huvudprogram för test av statiska}<br />

{cirkulära variabler <strong>och</strong> <strong>moduler</strong> }<br />

{bootsida 1}<br />

.MODULE/RAM/BOOT=1/ABS=0 mainmodul_1;<br />

.VAR/DM/RAM/CIRC dm_1_0[7]; {lokal cirkulär buffer}<br />

.VAR/DM/RAM/CIRC dm_x[10]; {lokal cirkulär buffer}<br />

.VAR/DM/RAM/STATIC/CIRC dm_z[19]; {statisk cirkulär buffer}<br />

{synlig på bootsida }<br />

{1 <strong>och</strong> 2 }<br />

.VAR/DM/RAM dm_0[15]; {lokal buffer}<br />

.VAR/DM/RAM dm_1_1[14]; {lokal buffer}<br />

.VAR/PM/RAM pm_1_0[12]; {lokal buffer}<br />

.GLOBAL dm_z; {dm_z synlig på andra}<br />

{bootsidor }<br />

.EXTERNAL sub_1; {anropa statisk submodul}<br />

start:<br />

JUMP start; nop; nop; nop; {restart interrupt}<br />

RTI; nop; nop; nop; {sampling interrupt IRQ2}<br />

RTI; nop; nop; nop; {SPORT0 transmit}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT0 receive}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT1 transmit}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT1 receive}<br />

{interrupt }<br />

RTI; nop; nop; nop; {TIMER interrupt}<br />

wait: IDLE; {wait for interrupt}<br />

JUMP wait;<br />

.ENDMOD;<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 5


Eftersom vi inte behöver se de statiska <strong>buffrar</strong>na som deklarerats på bootsida 0 på<br />

denna sida så finns inga .EXTERNAL-direktiv, däremot deklareras den nya statiska<br />

bufferten (dm_z) som global via direktivet .GLOBAL för att denna skall kunna nås<br />

från andra bootsidor, närmare bestämt från bootsida 2.<br />

Denna sida saknar egentlig programkod men den fyller ändå sin funktion vad gäller<br />

att illustrera delningen av <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong> mellan bootsidor.<br />

Submodul 1<br />

Även här har vi en statisk submodul. Den anropas med labeln sub_1 <strong>och</strong> kommer<br />

att anropas från bootsida 2. Modulen har programkoden<br />

{ADSP-2105 Submodul för test av statiska}<br />

{cirkulära variabler <strong>och</strong> <strong>moduler</strong> }<br />

{bootsida 1}<br />

.MODULE/RAM/BOOT=0/STATIC submodul_1;<br />

.EXTERNAL dm_y;<br />

.ENTRY sub_1;<br />

sub_1: SR=ASHIFT SI BY 2 (LO);<br />

RTS;<br />

.ENDMOD;<br />

Bootsida 2<br />

Även här gör vi ett mycket enkelt program men lägger in lite kod som hanterar de<br />

statiska <strong>buffrar</strong> som finns deklarerade på bootsida 0 för att se vad som händer. Eftersom<br />

de statiska <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong> som vi vill nå från denna bootsida är deklarerade<br />

på andra bootsidor så skall de inte deklareras på denna bootsida. Vi måste däremot<br />

använda .EXTERNAL-direktivet för att kunna se dessa statiska <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

även på denna bootsida.<br />

{ADSP-2105 Huvudprogram för test av statiska}<br />

{cirkulära variabler <strong>och</strong> <strong>moduler</strong> }<br />

{bootsida 2}<br />

.MODULE/RAM/BOOT=2/ABS=0 mainmodul_2;<br />

.VAR/DM/RAM dm_2_0[13]; {lokal buffer}<br />

.VAR/DM/RAM/CIRC dm_2_1[27]; {lokal cirkulär buffer}<br />

.EXTERNAL dm_x,dm_y,dm_z; {buffertar från }<br />

{andra bootsidor}<br />

.EXTERNAL sub_0_0,sub_1; {sub<strong>moduler</strong> på }<br />

{bootsida 0 <strong>och</strong> 1}<br />

JUMP start; nop; nop; nop; {restart interrupt}<br />

RTI; nop; nop; nop; {sampling interrupt IRQ2}<br />

RTI; nop; nop; nop; {SPORT0 transmit}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT0 receive}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT1 transmit}<br />

{interrupt }<br />

RTI; nop; nop; nop; {SPORT1 receive}<br />

{interrupt }<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 6


RTI; nop; nop; nop; {TIMER interrupt}<br />

start: CALL sub_0_0; {anropa submodul på}<br />

{bootsida 0 }<br />

CALL sub_1; {anropa submodul på}<br />

{bootsida 1 }<br />

AX0=DM(dm_x);<br />

AY0=1;<br />

AR=AX0+AY0;<br />

DM(dm_y)=AR;<br />

AR=AR+AY0;<br />

DM(dm_z)=ar;<br />

wait: IDLE; {wait for interrupt}<br />

JUMP wait;<br />

.ENDMOD;<br />

Länkning<br />

De tre bootsidorna måste länkas samman till samma EXE-fil. Detta för att länkaren skall<br />

klara av tilldelningen av minnesareor (<strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong>). Detta hade varit nödvändigt<br />

även om vi hade haft en enda bootsida <strong>och</strong> om statiska <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong> hade<br />

saknats. Länkning måste ske om så vårt program består av en enda modul.<br />

För att se minnestilldelningen så låter vi länkaren generera en MAP-fil.<br />

Minnestilldelning<br />

Vi ser minnesallokeringen genom nedanstående MAP-fil som länkaren har genererat vid<br />

länkningen. Filen är något redigerad för att eliminera oönskade radbrytningar.<br />

ADSP-2100 Family Development Tools, Release 6.0.1<br />

Analog Devices, Inc. : ADSP-2100 Family Linker<br />

Version 3.1<br />

Copyright © 1997<br />

static (static.exe) mapped according to MINIMALT_2105_SYSTEM<br />

(static.ach)<br />

xref for module: MAINMODUL_0 boot memory page(s) 0,<br />

MAINMODUL_0 pm 0:0000 [0020] module(global)<br />

DM_X dm 0:3800 [000A] variable(global)<br />

DM_0_0 dm 0:3840 [001E] variable<br />

DM_0 dm 0:385E [000F] variable<br />

DM_Y dm 0:380A [0008] variable(global)<br />

DM_0_1 dm 0:3812 [0006] variable<br />

PM_X pm 0:0030 [0016] variable<br />

START pm 0:001C label<br />

WAIT pm 0:001E label<br />

SUB_0_0 0:03FC [0000] extern(SUBMODUL_0_0)<br />

SUB_0_1 0:0020 [0000] extern(SUBMODUL_0_1)<br />

xref for module: MAINMODUL_1 boot memory page(s) 1,<br />

MAINMODUL_1 pm 1:0000 [001E] module(global)<br />

DM_1_0 dm 1:3818 [0007] variable<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 7


DM_X dm 1:3840 [000A] variable<br />

DM_Z dm 1:3820 [0013] variable(global)<br />

DM_0 dm 1:384A [000F] variable<br />

DM_1_1 dm 1:3859 [000E] variable<br />

PM_1_0 pm 1:001E [000C] variable<br />

START pm 1:001C label<br />

WAIT pm 1:001C label<br />

SUB_1 1:03FA [0000] extern(SUBMODUL_1)<br />

xref for module: MAINMODUL_2 boot memory page(s) 2,<br />

MAINMODUL_2 pm 2:0000 [0026] module(global)<br />

DM_2_0 dm 2:3812 [000D] variable<br />

DM_2_1 dm 2:3840 [001B] variable<br />

START pm 2:001C label<br />

WAIT pm 2:0024 label<br />

SUB_0_0 2:03FC [0000] extern(SUBMODUL_0_0)<br />

DM_X 2:3800 [000A] extern(MAINMODUL_0)<br />

DM_Y 2:380A [0008] extern(MAINMODUL_0)<br />

DM_Z 2:3820 [0013] extern(MAINMODUL_1)<br />

SUB_1 2:03FA [0000] extern(SUBMODUL_1)<br />

xref for module: SUBMODUL_0_0 boot memory page(s) 0,<br />

SUBMODUL_0_0 pm 0:03FC [0004] module(global)<br />

SUB_0_0 pm 0:03FC label(global)<br />

DM_Y 0:380A [0008] extern(MAINMODUL_0)<br />

xref for module: SUBMODUL_0_1 boot memory page(s) 0,<br />

SUBMODUL_0_1 pm 0:0020 [0003] module(global)<br />

SUB_0_1 pm 0:0020 label(global)<br />

DM_Y 0:380A [0008] extern(MAINMODUL_0)<br />

xref for module: SUBMODUL_1 boot memory page(s) 0,<br />

SUBMODUL_1 pm 0:03FA [0002] module(global)<br />

SUB_1 pm 0:03FA label<br />

DM_Y 0:380A [0008] extern(MAINMODUL_0)<br />

210x memory per MINIMALT_2105_SYSTEM (static.ach)<br />

internal 2105 pm ram mapped to 0000 - 07ff (auto booted at reset)<br />

internal 2105 dm ram mapped to 3800 - 3BFF<br />

0000 - 03FF [ 1024.] external bm rom code BOOT_MEM0<br />

0800 - 0BFF [ 1024.] external bm rom code BOOT_MEM1<br />

1000 - 13FF [ 1024.] external bm rom code BOOT_MEM2<br />

0000 - 03FF [ 1024.] internal pm ram data/code INT_PM<br />

3800 - 39FF [ 512.] internal dm ram data INT_DM<br />

boot memory and bootable run time program memory map:<br />

boot page 0 (auto boot)<br />

bm: 0000 - 001F (x8rom: 0000 - 007F) 0000 - 001F [32.] ram module<br />

MAINMODUL_0<br />

bm: 0020 - 0022 (x8rom: 0080 - 008B) 0020 - 0022 [ 3.] ram module<br />

SUBMODUL_0_1<br />

boot page 1<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 8


m: 0800 - 081D (x8rom: 2000 - 2077) 0000 - 001D [30.] ram module<br />

AINMODUL_1<br />

bm: 081E - 0829 (x8rom: 2078 - 20A7) 001E - 0029 [12.] ram variable<br />

PM_1_0 of MAINMODUL_1<br />

boot page 2<br />

bm: 1000 - 1025 (x8rom: 4000 - 4097) 0000 - 0025 [38.] ram module<br />

MAINMODUL_2<br />

24k of boot memory rom space required for this bootable run time map.<br />

Most convenient boot memory rom size is 24k bytes (192k bits).<br />

fixed program memory map:<br />

0030 - 0045 [ 22.] pm ram static variable PM_X of MAINMODUL_0<br />

03FA - 03FB [ 2.] pm ram page(s) 0,static module SUBMODUL_1<br />

03FC - 03FF [ 4.] pm ram page(s) 0,static module SUBMODUL_0_0<br />

fixed program memory rom: 0.<br />

fixed program memory ram: 28.<br />

dynamic data memory map:<br />

boot page 0<br />

3812 - 3817 [ 6.] ram variable DM_0_1 of MAINMODUL_0<br />

3840 - 385D [ 30.] ram circ variable DM_0_0 of MAINMODUL_0<br />

385E - 386C [ 15.] ram variable DM_0 of MAINMODUL_0<br />

dynamic data memory rom page 0: 0<br />

dynamic data memory ram page 0: 51<br />

boot page 1<br />

3818 - 381E [ 7.] ram circ variable DM_1_0 of MAINMODUL_1<br />

3840 - 3849 [ 10.] ram circ variable DM_X of MAINMODUL_1<br />

384A - 3858 [ 15.] ram variable DM_0 of MAINMODUL_1<br />

3859 - 3866 [ 14.] ram variable DM_1_1 of MAINMODUL_1<br />

dynamic data memory rom page 1: 0<br />

dynamic data memory ram page 1: 46<br />

boot page 2<br />

3812 - 381E [ 13.] ram variable DM_2_0 of MAINMODUL_2<br />

3840 - 385A [ 27.] ram circ variable DM_2_1 of MAINMODUL_2<br />

dynamic data memory rom page 2: 0<br />

dynamic data memory ram page 2: 40<br />

fixed data memory map:<br />

3800 - 3809 [ 10.] dm ram circ variable static DM_X of MAINMODUL_0<br />

380A - 3811 [ 8.] dm ram variable static DM_Y of MAINMODUL_0<br />

3820 - 3832 [ 19.] dm ram circ variable static DM_Z of MAINMODUL_1<br />

fixed data memory rom: 0.<br />

fixed data memory ram: 37.<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 9


Vad visar MAP-filen<br />

MAP-filen inleds med en beskrivning av hur olika minnesareor utnyttjas på de tre bootsidorna.<br />

Här kan vi se att programkoden hamnar från adress noll (0) i programminnet<br />

för att börja köras vid inläsning av respektive bootsida. Vi ser också programkodens<br />

längd.<br />

Vi ser därefter hur variablerna är placerade i minnet. Vi ser att statiska variabler är<br />

angivna som variable(global) medan övriga variabler bara anges som variable.<br />

Vi återkommer till variabelallokeringen. Vi hittar här också namn <strong>och</strong> adress<br />

för de lablar som används på olika bootsidor samt de namn på allokerade minnesareor<br />

som används. De modullablar <strong>och</strong> namn på minnesareor som ligger i en annan<br />

modul anges som extern, där vi också kan se namnet på den modul där labeln eller<br />

minnesdeklarationen finns.<br />

De tre sub<strong>moduler</strong>na är beskrivna var för sig på samma sätt som ovan.<br />

Efter detta följer en del som sammanfattar adresser <strong>och</strong> namn på alla tillgängliga<br />

minnesareor. Lägg märke till att de tre bootminnesareorna ligger i adressintervallen 0<br />

– 1k, 2k – 3k respektive 4k – 5k i bootminne. Areorna är alltså 1k långa med en<br />

lucka på 1k mellan respektive area. Denna lucka beror på kompabiliteten med processorn<br />

ADSP-2101 som har 2k stora bootareor. Med outnyttjade minnesareor blir<br />

bootminnet då 6k stort men eftersom varje intruktion upptar fyra positioner i ett 8<br />

bitars minne (tre positioner med 8 bitar av instruktionen plus en tom position) så anger<br />

MAP-filen att vi behöver ett 24k stort minne.<br />

MAP-filen avslutas med ytterligare en beskrivning av minnesallokeringen för variablerna<br />

på de olika bootsidorna. Här anges variabelnamn, minnestyp samt vilka adresser<br />

som variabeln upptar. Variabler som skall användas på flera bootsidor <strong>och</strong> därför<br />

är statiska anges som låsta (fixed memory map) medan variabler som kan skrivas<br />

över då en ny bootsida läses in anges som dynamiska (dynamic memory<br />

map).<br />

Buffrar i programminne<br />

Eftersom vi har deklarerat dessa <strong>buffrar</strong> i programminne så kommer naturligtvis<br />

minne att allokeras i detta minne. Vi har bara internt programminne <strong>och</strong> detta startar<br />

på adress 0x0000. Även om vi hade haft externt programminne så skulle länkaren<br />

ha börjat med att fylla internt programminne om vi inte via segment- eller absolutdirektiv<br />

(SEG respektive ABS) hade angivit att vissa <strong>buffrar</strong> skulle ligga i externt<br />

minne.<br />

Det interna programminnet ligger alltså i adressintervallet 0x0000-0x03FF <strong>och</strong><br />

program <strong>och</strong> programminnes<strong>buffrar</strong> måste placeras i detta intervall.<br />

Ur MAP-filen får vi följande karta över programminnet<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 10


.<br />

Figur 1 Karta över programminnet<br />

För att avbrottstabellen skall komma på rätt adresser så skall huvudprogrammet placeras<br />

från adress 0x0000 på varje bootsida. Vi har säkerställt detta genom att ange<br />

direktivet ABS=0 i huvudmodulens inledningsrad.<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 11


Vi ser att den dynamiska submodulen sub_0_1 på bootsida 0 placeras direkt efter<br />

huvudprogrammet <strong>och</strong> att både huvudprogram <strong>och</strong> submodul kommer att skrivas<br />

över då en ny bootsida laddas in.<br />

De två statiska sub<strong>moduler</strong>na, sub_0_0 <strong>och</strong> sub_1, däremot placeras sist i det interna<br />

programminnet för att undvika att de skrivs över vid byte av bootsida.<br />

Om vi övergår till <strong>buffrar</strong>na så ser vi att den statiska bufferten pm_x placeras så högt<br />

i programminnet att ingen dynamisk programudul eller buffer kommer att skriva över<br />

den vid byte av bootsida. Den dynamiska bufferten pm_1_0 på bootsida 1 placeras<br />

däremot direkt efter programkoden eftersom vi tillåter att den skrivs över vid byte av<br />

bootsida.<br />

Buffrar i dataminne<br />

På samma sätt ger MAP-filen följande bild av dataminnet.<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 12


Figur 2 Dataminnskarta med cirkulära <strong>buffrar</strong><br />

Minneskartan kan synas rörig <strong>och</strong> onödigt splittrad i smådelar men det finns en logik<br />

i röran.<br />

I normala fall skulle länkaren tilldela minne i den ordning som <strong>buffrar</strong>na dyker upp i<br />

assemblerfilen <strong>och</strong> därmed lägga dom i denna ordning efter varandra i minnet. Nu<br />

när vi har statiska <strong>buffrar</strong> så ser vi att länkaren i stället inleder med att allokera minne<br />

för dessa. Detta verkar ju logiskt eftersom de statiska <strong>buffrar</strong>na då kommer i minnesareans<br />

början <strong>och</strong> inte låser upp areor någonstans mitt i det interna dataminnet.<br />

Varken dessa eller de dynamiska <strong>buffrar</strong>na ligger dock i en följd på efterföljande<br />

adresser. Detta beror på att vissa av <strong>buffrar</strong>na är cirkulära <strong>och</strong> skall adresseringen av<br />

dessa fungera så måste buffertens basadress vara en heltalsmultipel av det tal vi får<br />

om vi avrundar den aktuella bufferlängden till nästa tvåpotens. En 9 positioner lång<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 13


4<br />

buffer måste alltså ha basadressen på en heltalsmultipel av 2 = 1610<br />

= 1016.Detta<br />

leder<br />

till exempel till att den cirkulära (<strong>och</strong> statiska) bufferten dm_z hamnar på adress<br />

0x3820 <strong>och</strong> inte på den tomma adressen 0x381F som finns direkt efter bufferten<br />

dm_1_0.<br />

Lägg märke till att den minnesarea som innehåller de tre statiska <strong>buffrar</strong>na inte täcks<br />

av nya <strong>buffrar</strong> då en ny bootsida läses in utan bufferternas innehåll finns kvar i minnet.<br />

Observera dock att de statiska <strong>buffrar</strong>na bara är tillgängliga från den bootsida där<br />

de är deklarerade (bootsida 0 respektive bootsida 1) <strong>och</strong> den bootsida (eller de bootsidor)<br />

där de är deklarerade som EXTERNAL (bootsida 2). På bootsida 1 kan vi inte<br />

nå <strong>buffrar</strong>na dm_x <strong>och</strong> dm_y <strong>och</strong> på bootsida 0 kan vi inte nå bufferten dm_z.<br />

Lägg dessutom märke till att de <strong>buffrar</strong> som har deklarerats med samma namn <strong>och</strong><br />

längd på bootsida 0 <strong>och</strong> 1 (dm_0), men som inte är statiska, inte ligger på samma<br />

adresser <strong>och</strong> då en ny bootsida läses in kommer dessa areor att upptas av andra variabler.<br />

Dessa två <strong>buffrar</strong> är alltså inte samma buffer på de två bootsidorna utan två<br />

skilda <strong>buffrar</strong>.<br />

På bootsida 1 finns dessutom bufferten dm_x deklarerad. Bufferten har alltså samma<br />

namn <strong>och</strong> även samma storlek som den statiska bufferten dm_x som är synlig på bootsida<br />

0 <strong>och</strong> 2, men eftersom bootsida 1 saknar något EXTERNAL-direktiv för bufferten<br />

dm_x så är bufferten med detta namn på bootsida 1 en annan buffer än den<br />

statiska globala bufferten med namnet dm_x <strong>och</strong> den ligger därför på en annan<br />

adress. Skulle vi ha försökt att göra den statiska bufferten synlig på bootsida 1 så<br />

skulle vi ha fått ett assembleringsfel. Vi kan inte ha två <strong>buffrar</strong> med samma namn<br />

synliga samtidigt.<br />

Hade vi inte använt cirkulära <strong>buffrar</strong> så hade vi inte fått luckorna i ovanstående minneskarta<br />

utan vi hade fått nedanstående bild där alla minnes<strong>buffrar</strong> ligger på efterföljande<br />

adresser.<br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 14


Figur 3 Dataminneskarta utan cirkulära <strong>buffrar</strong><br />

Tillämpad digital signalbehandling<br />

Signalprocessorn<br />

<strong>Statiska</strong> <strong>moduler</strong> <strong>och</strong> <strong>buffrar</strong><br />

Sida 15

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!