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