Sida 4 av 5
Re: Jag står inför ett teknikskifte...
Postat: 11 februari 2011, 16:26:41
av BJ
Jag tycker om att veta vilken bank jag är i.

Då slipper jag byta bank så fort jag ska göra nånting
med ett register.
När det gäller att veta var i en bank som variablerna hamnar
så har jag en buffert i bank 1 (i just den här filen), och
processorn tar emot tecken från uarten och lägger dom i bufferten.
Sen har jag en avbrottshanterare som håller reda på start-adress,
slut-adress och adressen till rätt ställe i bufferten.
Jag använder FSR som pekare och skriver tecknet med registret INDF.
Som det är nu så har jag konstanter för adresserna.
Men det kanske finns andra sätt?
Kan man låta assemblatorn räkna ut adresserna och sen använda
dom som konstanter i programmet?
Eller länkaren blir det kanske?
Re: Jag står inför ett teknikskifte...
Postat: 11 februari 2011, 16:36:56
av sodjan
Jo, men det spelar ingen som helst roll *var* i bank1 som bufferten ligger.
(Och igentligen inte heller vilken bank den ligger i.)
> Som det är nu så har jag konstanter för olika adress-gränser.
> Men det kanske finns andra sätt?
Ja.
> Kan man låta assemblatorn räkna ut adresserna och sen använda
> dom som konstanter i programmet?
Ja, eller igentligen är det MPLINK som gör det när den har
bestämt var i minnet den aktuella variablen/bufferten ska ligga.
Du laddar FSR med adressen från symbolen som pekar på bufferten.
Den sätts korrekt vid varje "build" beroende på var bufferten hamnar varje gång.
Det finns ett litet exempel vid "bankisel" i MPASM manualen.
Du behöver alltå inte hålla reda på eller veta en enda adress.
Du jobbar helt och hållet "symboliskt", så att säga.
Re: Jag står inför ett teknikskifte...
Postat: 11 februari 2011, 17:55:55
av BJ
Inte riktigt kanske... Exemplet verkar använda
start-adressen (0x20). Inte symbolen group_1_var_1...
Kod: Markera allt
group1 udata 0x20 ;group1 data stored at locations
;starting at 0x20 (IRP bit 0).
group1_var1 res 1 ;group1_var1 located at 0x20.
...
movlw 0x20 ;This part of the code addresses
movwf FSR ;variables group1_var1...
Så kanske man kan göra i stället.
Re: Jag står inför ett teknikskifte...
Postat: 11 februari 2011, 18:18:43
av BJ
Eller vänta lite nu...
Symbolen är ju en pekare. Det är ju bara att ladda den
som en konstant.
Re: Jag står inför ett teknikskifte...
Postat: 11 februari 2011, 19:23:02
av sodjan
Exakt !
Otestat, men det borde bli något i stil med :
Kod: Markera allt
myvar_1 udata ; Start new user-data section at section "myvar_1".
buf_1 res 10 ; Create 10 byte long buffer in section "myvar_1"
; with start address in "buf_1".
...
movlw buf_1 ; Load start address of buf_1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf_1 ; Set bank bits för indexed access according to buf_1.
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 09:56:49
av BJ
Ja, så borde det bli. Tack.
Finns det nåt smart sätt att räkna ut slutadressen?
Jag provade med nåt sånt här:
#define buf_1_slut = buf_1 + 9
Det assembleras, men jag vet inte vad det blir.
Jag tittade i map-filen, men det är inte med där.
Eller man kan göra så här:
Men då måste man veta att dom kommer i rätt ordning.
Annars får man räkna ut det själv. Antingen varje gång.
Då blir programmet lite svårare att läsa (och så tar det
en extra instruktion, men det gör inte så mycket).
Eller också räknar man ut det en gång i början, och låter
en variabel hålla reda på värdet. Då tar det ett extra
register i minnet. Eller 2, om man tar både början och slutet.
Så... Går det att göra med define eller nån liknande instruktion
eller direktiv?
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 11:23:27
av TomasL
PHermansson skrev:Egentligen kan man väl säga som så här: Vill du programmera i C väljer du AVR.
Hur resonerar du då?
Det är väl inga som helst problem att skriva C-kod för PIC.
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 11:29:50
av sodjan
Notera att du kan göra mycket i MPASM som itne har ett smack
med slutresultatet att göra. T.ex de flesta #-direktiv. En #define
sätter en assembly-time variabel som kan användas senare under
samma "build" i #IF o.s.v, men den existerar enbart under
körningen av MPASM.
Om du vill veta vilket värde din "buf_1_slut" fick så kan du använda
"error" eller "messg" för att få ut dom från MPLAB.
Se ock så "set" för att hantera variabler under assembleringen.
Otestat... :
Kod: Markera allt
buf1_len set 10
myvar1 udata ; Start new user-data section at section "myvar1".
buf1 res buf1_len ; Create 10 byte long buffer in section "myvar1"
; with start address in "buf1".
...
set buf1_end buf_1 + buf1_len ; Calculate end address of buf1...
...
...
movlw buf1 ; Load start address of buf1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf1 ; Set bank bits för indexed access according to buf1.
...
movlw buf1_end ; Load end address of buf1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf1_end ; Set bank bits för indexed access according to buf1_end.
Nu kan du ändra längden på ett ställe och det slår ingenom io hela koden.
Inget är hårdkodat förrutom längden.
(Du kanske ska använda "buf1_len - 1" i "set..." ovan för att inte hamna
på första positionen efter buf1...)
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 12:44:32
av BJ
Tack för att ni hjälper till så mycket.
Det var ett bra tips, men tyvärr så verkar det som att man inte
kan använda en "res" i ett "set"-uttryck.
Jag får "Missing symbol" där.
Det hade varit väldigt bra om det hade fungerat.
Jag kanske är tvungen att ha min variabel i alla fall...
(Eller räkna ut det varje gång.)
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 13:00:34
av sodjan
EDIT: Rättat/justerat lite i koden...
OK, jaha, där ser man...
Det är ju ganska självklart varför det inte fungerar om man
tänker till lite...

Eftersom vi kör "relocatable" så är det MPLINK som
slutligen sätter de aktuella adresserna. D.v.s att adressen till bufferten
är inte känd av MPASM (den hanterar det bara symboliskt genom hela
assembleringen) och därför kan den inte räkna ut "buf1 + buf_len".
Om man gör så här så går det i alla fall igenom en build :
Kod: Markera allt
radix dec
buf1_len set 15
myvar1 udata ; Start new user-data section at section "myvar1".
buf1 res buf1_len ; Create 15 (dec) byte long buffer in section "myvar1"
; with start address in "buf1".
...
;;;;set buf1_end buf1 + buf1_len ; Fungerar inte eftersom "buf1" inte är känt av MPASM !!
...
...
movlw buf1 ; Load start address of buf1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf1 ; Set bank bits för indexed access according to buf1.
...
movlw buf1 + buf_len ; Load end address of buf1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf1 + buf_len ; Set bank bits för indexed access according to buf1_end.
Enligt MAP filen skapas "buf1" på adress 0x20, och "movlw buf1 + buf_len" blir
"MOVLW 0x2F", vilket ju är 0x20 + 15...
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 16:13:58
av BJ
Du hade ju delvis rätt nu kan man säga... men det fungerar inte
om jag ska räkna ut slut-adressen.
Det här fungerar:
movlw buf1 + buf_len
Och det här fungerar inte:
movlw buf1 + buf_len - 1
Operand contains unresolvable labels or is too complex
Kanske dags att jag ger upp snart.

Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 17:35:48
av sodjan
Ha, yes...
Jag skrev texten i inlägget samtidigt som jag labbade i MPLAB...

De stämmer inte överens mot varandra helt och hållet.
Jag noterade exakt samma sak som du. Uppenbarligen är det OK att skicka
med "buf1 + buf_len" från MPASM till MPLINK (det är ju först i MPLINK som
det kan räknas ut slutgiltigt), men inte om man har med en konstant
i uttrycket...
Finns absolut ingen anledning att ge upp. Och att ge upp vadå ?
Mitt senaste kodexempel fungerar ju faktiskt.
Hela poängen med det hela är att jag vill visa att man *själv* inte
behöver hålla redan på en enda adress, man kan låta MPASM och
MPLINK hantera deet helt och hållet. Och man behöver inte heller
tvinga bufferten till en viss minnes-bank, min kod fungerar som den
är oavsett var bufferten hamnar.
Re: Jag står inför ett teknikskifte...
Postat: 12 februari 2011, 20:21:27
av BJ
Ja visst, det du visar är jättebra.

Och om man använder bankisel så kommer man ju åt bufferten
var den än hamnar.
Jag menade att ge upp med att få Mpasm och Mplink att räkna ut
alla adresserna åt mig. Jag tycker att den borde klara att
räkna ut uttryck med tal i också, men så är det tydligen inte.
Om jag räknar så så hamnar ju slutadressen efter bufferten,
inte på sista adressen i den. Och den adressen har man ju inte
så stor användning för. Då får man i alla fall räkna ett steg
tillbaka för att få den rätta, och då kan man lika gärna räkna
rätt första gången själv.

Om det inte finns nåt annat sätt som jag har missat.
Re: Jag står inför ett teknikskifte...
Postat: 14 februari 2011, 12:32:47
av BJ
Så här kan man göra.
Kod: Markera allt
radix dec
buf1_len set 15 ; Längd, för allokering.
buf1_len_minus_1 set 14 ; Längd - 1, för att räkna ut slutadressen.
myvar1 udata ; Start new user-data section at section "myvar1".
buf1 res buf1_len ; Create 15 (dec) byte long buffer in section "myvar1"
; with start address in "buf1".
...
movlw buf1 ; Load start address of buf1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf1 ; Set bank bits för indexed access according to buf1.
...
movlw buf1 + buf_len_minus_1 ; Load end address of buf1 into W...
movwf FSR ; ...and store in index register FSR.
bankisel buf1 + buf_len_minus_1 ; Set bank bits för indexed access according to buf1_end.
Vad movlw-instruktionen blir när allt är färdigt kunde jag inte se,
men man får väl anta att den räknar rätt.
Egentligen skulle det väl räcka med "bankisel buf1" vid den andra läsningen
eller skrivningen. Det som vi har nu verkar vara gjort för en buffert som kan vara
i flera minnes-banker. Men så blir det väl aldrig. Och FSR skulle väl inte klara det.
Re: Jag står inför ett teknikskifte...
Postat: 14 februari 2011, 12:41:15
av sodjan
> Vad movlw-instruktionen blir när allt är färdigt kunde jag inte se,
Du kan göra en "View" -> "Progam Memory" så borde du se det.
> Egentligen skulle det väl räcka med "bankisel buf1" vid den andra läsningen
> eller skrivningen.
Absolut. Hela bufferten ligger alltid i samma bank. Och som du säger så klarar
den aktuella arkitekturen inte av det annars. De nya "Enhanced Mid-Range",
d.v.s PIC16F1xxx serien, har inte denna begränsning. Där kan en buffert vara
linjär över valfri del av minnet. Och indexregistren kan själva räkna direkt
linjärt över hela adresserymden.