Splitta asm kod till flera filer i AVRStudio
Splitta asm kod till flera filer i AVRStudio
Jag skulle vilja dela upp ett större asm projekt genom att dela koden i större block & lägga dom i varsin .asm fil.
Varje block skulle då få en subrutins label, som man ska kunna anropa ifrån huvud filen/ programmet.
I AVRStudio, så kan man ju lägga till flera filer under, Source Files trädet, men hur ska man kunna länka samma dessa?.
Eller går det överhuvud taget?.
Varje block skulle då få en subrutins label, som man ska kunna anropa ifrån huvud filen/ programmet.
I AVRStudio, så kan man ju lägga till flera filer under, Source Files trädet, men hur ska man kunna länka samma dessa?.
Eller går det överhuvud taget?.
Nu när jag har inkluderat filen, då gick det bra att assemblerna utan fel.
Det gjorde det inte innan eftersom jag skrev i huvudprogrammet (rcall testar).
& labeln (testar) låg i den nya asm filen.
Så länkningen åt det hållet fungerar.
Men jag får ändå inte detta att fungera riktigt, processorn bara buggar ur direkt vid start.
Sen om jag högerklickar på den nya asm filen & väljer Set As Entry File, & kör asembleringen där, då kan jag få massvis med fel.
Jag märkte att jag även var tvungen inkludera "m16def.inc" i den nya filen.
Annars fick jag fel vid asembleringen för att t.e.x namnet PORTA inte fanns eller kunde tolkas.
Så det känns inte som att båda filerna asembleras tillsammans?.
Hmm nu blev det nog kluddigt.
Det gjorde det inte innan eftersom jag skrev i huvudprogrammet (rcall testar).
& labeln (testar) låg i den nya asm filen.
Så länkningen åt det hållet fungerar.
Men jag får ändå inte detta att fungera riktigt, processorn bara buggar ur direkt vid start.
Sen om jag högerklickar på den nya asm filen & väljer Set As Entry File, & kör asembleringen där, då kan jag få massvis med fel.
Jag märkte att jag även var tvungen inkludera "m16def.inc" i den nya filen.
Annars fick jag fel vid asembleringen för att t.e.x namnet PORTA inte fanns eller kunde tolkas.
Så det känns inte som att båda filerna asembleras tillsammans?.
Hmm nu blev det nog kluddigt.
Ett litet praktiskt test.
I den gamla huvud filen så skriver jag
Rcall Testar
Efter att en knapp trycks ner.
Labeln Testar ligger i den nya filen, såhär
Testar:
Ret
Det är allt som står i den nya filen.
Så programmet borde bara hoppa dit & hoppa tillbaka igen utan att utföra några funktioner.
Men så fort jag gör såhär så buggar processorn ur 90% av startförsöken.
I den gamla huvud filen så skriver jag
Rcall Testar
Efter att en knapp trycks ner.
Labeln Testar ligger i den nya filen, såhär
Testar:
Ret
Det är allt som står i den nya filen.
Så programmet borde bara hoppa dit & hoppa tillbaka igen utan att utföra några funktioner.
Men så fort jag gör såhär så buggar processorn ur 90% av startförsöken.
När man kör med inkluderade filer så är det ibland viktigt i vilken ordning man inkluderar dom. I ditt fall t.ex. Inkluderingen av m16-filen måste vara före inkluderingen av den nya huvudfilen. Om man tänker att det enda inkluderingen egentligen gör är att textmässigt ersätta själva "include"-direktivet med texten i den inkluderade filen. Ligger då inkluderingarna i fel ordning så är ju inte PORTA definierad när den används första gången (i den nya huvudfilen) eftersom den inkluderas först EFTER huvudfilen.Fagge skrev:Jag märkte att jag även var tvungen inkludera "m16def.inc" i den nya filen.
Annars fick jag fel vid asembleringen för att t.e.x namnet PORTA inte fanns eller kunde tolkas.
Så det känns inte som att båda filerna asembleras tillsammans?.
Edit: Alternativet är att inkludera definitionsfilen i alla filer där den används, även i den andra inkluderingsfilen. Nackdelen är att man lätt får error p.g.a dubbeldefinitioner. Lösningen på det är som man ofta ser i C-kod att sätta en "ifdef" runt inkluderingen. Om filen redan är inkluderad så gör man det inte fler ggr.
Oki, Tackar.
Jag hade ju givetvis inkluderat den nya filen innan "m16def.inc
Så nu ser det lite ljusare ut.
Men jag har fortfarande ett konstigt problem kvar.
Om jag både har i spi kabeln instucken (AVRISP mkII) & den nya filen inkluderad .INCLUDE "test2.asm", då buggar processon ur vid nästan alla startförsök (spänningspåslag)
Men tar jag bort något av ovanstående, så går processorn som på räls.
Någon som kan se ett samband?.
Jag hade ju givetvis inkluderat den nya filen innan "m16def.inc
Så nu ser det lite ljusare ut.
Men jag har fortfarande ett konstigt problem kvar.
Om jag både har i spi kabeln instucken (AVRISP mkII) & den nya filen inkluderad .INCLUDE "test2.asm", då buggar processon ur vid nästan alla startförsök (spänningspåslag)
Men tar jag bort något av ovanstående, så går processorn som på räls.
Någon som kan se ett samband?.
Jag vet inte hur det fungerar med AVR, så detta bygger på PIC miljön...
Att bara dela upp ASM koden i flera filer och sedan "bara" lägga ihop dom igen
med "include", ger igentligtn inte mer än lite mindre filer att hantera.
Det ger inga alls av de fördelar man har med separatassemblering. T.ex
separata "name spaces" (samma namn på labels och variabler i olika filer
utan att det krockar).
Har AVR miljön en separat länkare som kan länka separat assemblerande
objektfiler ?
Att bara köra med "include" är i princip ingen skillnad mot att ha allt i
en stor fil, från assemblerns sida sett.
Att bara dela upp ASM koden i flera filer och sedan "bara" lägga ihop dom igen
med "include", ger igentligtn inte mer än lite mindre filer att hantera.
Det ger inga alls av de fördelar man har med separatassemblering. T.ex
separata "name spaces" (samma namn på labels och variabler i olika filer
utan att det krockar).
Har AVR miljön en separat länkare som kan länka separat assemblerande
objektfiler ?
Att bara köra med "include" är i princip ingen skillnad mot att ha allt i
en stor fil, från assemblerns sida sett.
Jag har väldigt dålig koll på det här med include filer men jag tror att det här ska fungera.
OBS! ATmega88.
Huvud fil
Include fil
OBS! ATmega88.
Huvud fil
Kod: Markera allt
.INCLUDE "m88def.inc"
//----------------------------------------------------------------------
.def tmp = r16
//--- Interrupt Vector -------------------------------------------------
.org 0x000
rjmp Reset ; Reset Handler
//--- Reset ------------------------------------------------------------
.org 0x01A
Reset:
ldi tmp, LOW(RAMEND) ; Set stackpointer to ram end
out SPL, tmp
ldi tmp, HIGH(RAMEND)
out SPH, tmp
sei ; set global interrupt enable
//--- Includes External--------------------------------------------------
.INCLUDE "MinFil.asm"
Main:
//--- Init --------------------------------------------------------------
ldi tmp, 0x01
out DDRB, tmp
//-----------------------------------------------------------------------
rcall Test
Loop:
rjmp Loop
Kod: Markera allt
rjmp Main
Test:
sbi PORTB, 0
ret
Senast redigerad av BEEP 9 september 2008, 21:53:57, redigerad totalt 1 gång.
Nu hajar jag .
Det verkar som att när processor går upp i från & ner & trampar på .INCLUDE "MinFil.asm"
Så tassar den in i den filen & fortsätter där, därav min hängningar.
Så därför måsta man tydligen skriva rjmp Main direkt i början i den nya filen, så att den hoppar tillbaka till huvudprogammet igen & fortsätter nästa steg neråt.
Vilken liten jävlel, där gick denna kvällen!.
Tack allihopa.
Det verkar som att när processor går upp i från & ner & trampar på .INCLUDE "MinFil.asm"
Så tassar den in i den filen & fortsätter där, därav min hängningar.
Så därför måsta man tydligen skriva rjmp Main direkt i början i den nya filen, så att den hoppar tillbaka till huvudprogammet igen & fortsätter nästa steg neråt.
Vilken liten jävlel, där gick denna kvällen!.

Tack allihopa.

Det är absolut ingen skillnad på att göra INCLUDE och att skriva det
som står i den inkluderande filen *direkt* i huvudfilen. Skulle det
bli fel med koden där direkt, så blir det det även med INCLUDE...
> Så tassar den in i den filen & fortsätter där,
Nej, ingentligen inte.
Den *läser in* den inkluderade filen som om det hade varit en del av
huvudfilen *innan* den börjar assemblera eller "tassa" någonstans alls.
I just det exemplet som BEEP postade så är det ju lite korkat
att lägga INCLUDE där det ligger, bättre hade varit sist, efter "rcall Test".
Det hade ju varit där den hade legat, om den hade legat i huvudfilen...
Och då behövs inte "rjmp Main" i den inkluderade filen, så klart.
Include fil:
Att include-filer *oftast* ligger tidigt i koden beror på att de *oftast*
innehåller t.ex symboldefinitioner som behövs vid assembleringen, t.ex
device filerna med definitionen av DDRB m.m. Den kan *inte* inkluderas
sist i koden...
I många fall där man delar koden så har man två include filer, en som innahåller
diverse definitioner som behövs i main-koden och den inkluderas tidigt, och en
som innehåller själva den inkluderade exekverbara koden, och den kan/ska/bör
inkluderas där den passar in, ofta mot slutet av main-koden.
Mycket av dessa problem försvinner helt om man har en miljö som stöder
separat-asemblerade filer, men jag vet som sagt inte om AVR verktygen stöder det...
som står i den inkluderande filen *direkt* i huvudfilen. Skulle det
bli fel med koden där direkt, så blir det det även med INCLUDE...
> Så tassar den in i den filen & fortsätter där,
Nej, ingentligen inte.
Den *läser in* den inkluderade filen som om det hade varit en del av
huvudfilen *innan* den börjar assemblera eller "tassa" någonstans alls.
I just det exemplet som BEEP postade så är det ju lite korkat
att lägga INCLUDE där det ligger, bättre hade varit sist, efter "rcall Test".
Det hade ju varit där den hade legat, om den hade legat i huvudfilen...
Och då behövs inte "rjmp Main" i den inkluderade filen, så klart.
Kod: Markera allt
...
...
Main:
//--- Init --------------------------------------------------------------
ldi tmp, 0x01
out DDRB, tmp
//-----------------------------------------------------------------------
rcall Test
Loop:
rjmp Loop
//--- Includes External--------------------------------------------------
.INCLUDE "MinFil.asm"
Kod: Markera allt
Test:
sbi PORTB, 0
ret
innehåller t.ex symboldefinitioner som behövs vid assembleringen, t.ex
device filerna med definitionen av DDRB m.m. Den kan *inte* inkluderas
sist i koden...
I många fall där man delar koden så har man två include filer, en som innahåller
diverse definitioner som behövs i main-koden och den inkluderas tidigt, och en
som innehåller själva den inkluderade exekverbara koden, och den kan/ska/bör
inkluderas där den passar in, ofta mot slutet av main-koden.
Mycket av dessa problem försvinner helt om man har en miljö som stöder
separat-asemblerade filer, men jag vet som sagt inte om AVR verktygen stöder det...
Jag har nog gjort fel för jag tror att .INCLUDE ska vara i slutet på huvudfilen.
Kod: Markera allt
.INCLUDE "m88def.inc"
//----------------------------------------------------------------------
.def tmp = r16
//--- Interrupt Vector -------------------------------------------------
.org 0x000
rjmp Reset ; Reset Handler
//--- Reset ------------------------------------------------------------
.org 0x01A
Reset:
ldi tmp, LOW(RAMEND) ; Set stackpointer to ram end
out SPL, tmp
ldi tmp, HIGH(RAMEND)
out SPH, tmp
sei ; set global interrupt enable
//--- Init --------------------------------------------------------------
ldi tmp, 0x01
out DDRB, tmp
//-----------------------------------------------------------------------
rcall Test
Loop:
rjmp Loop
//--- Includes External--------------------------------------------------
.INCLUDE "MinFil.asm"
Kod: Markera allt
Test:
sbi porta, 0
ret
Senast redigerad av BEEP 9 september 2008, 22:45:28, redigerad totalt 2 gånger.
> Error: Relative bransch out of reach
Byt "rcall" till något annat. rcall är inte optimalt för calls till inkluderade
filer. Det är allt för lätt att "target" glider iväg utom räckhåll för rcall.
> I vilket fall som helst så funkar det helt perfekt nu, när .include ligger i början!.
Du gör en helt onödig "rjmp". Det kallar jag inte "perfekt"...

Och dessutom är det i princip fel att göra så...
Byt "rcall" till något annat. rcall är inte optimalt för calls till inkluderade
filer. Det är allt för lätt att "target" glider iväg utom räckhåll för rcall.
> I vilket fall som helst så funkar det helt perfekt nu, när .include ligger i början!.
Du gör en helt onödig "rjmp". Det kallar jag inte "perfekt"...


Och dessutom är det i princip fel att göra så...