Ik ben nu heel druk aan het programmeren (ik ben nu bezig met de command-line interface via een VT100 terminal), en ik kom wat vreemde zaken tegen bij het schrijven van assembler voor de AT90S8515 met de assembler van Atmel.
Het meest vreemde (waar ik ook langer dan een uur op heb zitten zoeken) is het volgende:
CommandTable: ;List of all commands
;first byte is ID, last byte should be 0
.db 1, "CLS", 0
.db 2, "RESET", 0
.db 3, "SYSTEM", 0, 0
.db 5, "READF", 0
.db 4, "READ", 0, 0
.db 6, "HELP", 0, 0
CommandTableEnd: .db 0, 0, 0, 0, 0
Als ik bij de woorden met een even aantal letters de laatste 0 weghaal (zodat de entry een EVEN aantal bytes is), dan start de controller helemaal niet op. Na een reset gebeurt er dan helemaal niets meer.
Dat vind ik dus wel heel erg vreemd. Ik zou me nog kunnen voorstellen dat iedere entry een even aantal bytes moet zijn, omdat het programmageheugen bestaat uit 16-bits woorden. Maar dat ze oneven moeten zijn, dat slaat alles. En waarom start de controller dan niet op?
Wie weet er hoe dit in elkaar zit?
Bastiaan
Bachelor of Engineering -- Microcontrollers AVR, PIC (asm, C), PC applicaties (C, C++), Webpages (HTML, CSS, PHP, SQL), Rail-infra engineer
Ik kan wel zo het een en ander bedenken wat ten grondslag ligt aan jouw probleem.
Ook durf ik zo wel te zeggen dat jouw conclusie betreffende het zogenaamde oneven aantal benodigde bytes niet juist is.
Maar.... ik heb meer info nodig over je programma dan je tot nu toe heb gegeven. Want HOE gebruik je die CommandTable? Want enkel een "verkeerde" tabel weerhoudt in eerste instantie een controller niet om op te starten.
Dus gelieve de code waarin je de tabel aaroept cq gebruikt ook even te plaatsen.
Dit is alle data in Flash:
.cseg
.org $0
rjmp InitAll
rjmp EXT_INT0 ;IRQ 0
rjmp EXT_INT1 ;IRQ 1
rjmp TIM1_CAPT ;Timer 1 capture
rjmp TIM1_COMPA ;Timer 1 compare A
rjmp TIM1_COMPB ;Timer 1 compare B
rjmp TIM1_OVF ;Timer 1 overflow
rjmp TIM0_OVF ;Timer 0 overflow
rjmp SPI_Handler ;Serial transfer complete
rjmp UART_RXC ;Uart RX complete
rjmp UART_DRE ;Uart data register empty
rjmp UART_TXC ;Uart TX complete
rjmp ANA_COMP ;Analog comparator
; **** GENERAL DATA
CRLFMsg: .db CR, LF, 0
InitMsg: .db "AVR test, (c) 2004 by Digital Guru", CR, LF, 0
RamTopMsg: .db "Top of internal Ram: $", 0
ExRamTopMsg: .db "Top of external Ram: $", 0
StackMsg: .db "End of stack: $", 0
StackSizeMsg: .db "Max size of stack: $", 0
HeapMsg: .db "Start of heap: $", 0
TXStartMsg: .db "Start of TX buffer: $", 0
TXSizeMsg: .db "Size of TX buffer: $", 0
RXStartMsg: .db "Start of RX buffer: $", 0
RXSizeMsg: .db "Size of RX buffer: $", 0
HeapFreeMsg: .db "Start of free space: $", 0
MemFreeMsg: .db "Free memory: $", 0
GetHelpMsg: .db "HELP for a list of commands.", CR, LF, 0
HelpMsg: .db "All numbers are in HEX, ex: $FF, $FFFF and $FFFF:FF.", CR, LF, 0
ReadyMsg: .db "System ready.", CR, LF, 0
ErrorMsg: .db "Unrecognized command.", CR, LF, 0
RMErrorMsg: .db "Not a valid adress.", CR, LF, 0
CommandTable: ;List of all commands,
;first byte is ID, last byte should be 0
.db 1, "CLS", 0
.db 2, "RESET", 0
.db 3, "SYSTEM", 0, 0
.db 5, "READF", 0
.db 4, "READ", 0, 0
.db 6, "HELP", 0, 0
CommandTableEnd: .db 0, 0, 0, 0, 0
en dit is de functie:
;Returns ID of command that is in LineBuf in temp
FindCommand:
push i
in i, SREG
push i
push A
push ZL
push ZH
push YL
push YH
ldi ZL, low(CommandTable<<1)
ldi ZH, high(CommandTable<<1)
FindCommandThis:
lds YL, LineBuf
lds YH, LineBuf + 1
lpm
adiw ZH:ZL, 1
mov temp, A
tst temp
brne FindCommandCont ;ID = 0, no command found
FindCommandSkip:
lpm
adiw ZH:ZL, 1
mov temp, A
tst temp
breq FindCommandEnd ;ID = 0, no command found
FindCommandCont:
ld i, Y+ ;first char of line
lpm
adiw ZH:ZL, 1 ;first char of command
cp i, A
breq FindCommandNext ;first letter matches
FindCommandNextID:
lpm
adiw ZH:ZL, 1
tst A
brne FindCommandNextID
adiw ZH:ZL, 1
rjmp FindCommandThis
FindCommandNext:
ld i, Y+ ;next char of line
lpm
adiw ZH:ZL, 1 ;next char of command
tst A
breq FindCommandEnd ;found it
cp i, A
breq FindCommandNext ;next letter matches
rjmp FindCommandNextID
FindCommandEnd:
pop YH
pop YL
pop ZH
pop ZL
pop A
pop i
out SREG, i
pop i
ret
Maar als ik die nullen achter die entries weghaal, dan start de controller niet meer op. Ook niet als ik die routine weghaal. Hij komt daar niet meer. Hij komt dan zelfs niet meer bij de code waar hij bij een reset naartoe springt.
Hier staat de hele code.
Ik zou het geweldig vinden als je me zou kunnen uitleggen wat er fout gaat!
Bastiaan
Bachelor of Engineering -- Microcontrollers AVR, PIC (asm, C), PC applicaties (C, C++), Webpages (HTML, CSS, PHP, SQL), Rail-infra engineer
Ehm, hoe heb je bepaald dat je controller niet opstart?
Je bent vergeten dat er voor je strings ook nog een ID nummer staat, dat moet je wel meerekenen. Als je dus een even aantal karakters in je string hebt heb je een oneven aantal bytes in je entry want -> even karakt + ID = oneven bytes dus moet er een enkele afsluitnul bij om het even te maken, NU heb je juist met deze code dat je een "verkeerd" aantal bytes hebt gevult in zijn geheugen.
Welke assembler gebruik je om je code van asm naar hex te converteren? Want de meeste zetten er zelf een 0 achter als jij een ruimte niet juist hebt gevult met even bytes.
Als je kijkt naar een stukje van je listing:
.db 6, "HELP", 0
000100 4806
000101 4c45
000102 0050
Dan zie je dat het zo hoort. Op adres 000100 staat de 06 van je 6 als ID en de 48 van de H. Dan komt de 45 van je E, de 4c van je L en tot slot de 50 van je P (dat zijn de hex waardes van je ascii karakters). Om die plek "af te sluiten" was die ene nul dus nodig want anders blijft de plek voor die 50 op adres 000102 open, dus er wordt afgesloten met een enkele 0 die je ook ziet op adres 100102
[Bericht gewijzigd door Bastiaan op ]
Ja, dat is dus precies hetgene dat ik niet begrijp! Want als ID + string + afsluitnul een even aantal bytes is, gaat het fout. Is het oneven, dan plakt de assembler er nog een extra 0 achter (dus maximaal 3 ipv. 1) en dan gaat het dus wel goed.
Met 'niet opstarten' bedoel ik, dat zelfs als ik bij InitAll alles uitrem behalve het zetten van de stack op RAMEND en het initialiseren van de UART, buffers en interrupts, er geen text op de terminal verschijnt. En dan reageert hij nergens meer op. Ik heb niet geprobeerd een ledje te laten knipperen op een vrij pootje.
Je kunt het programma volgens mij ook op een controller draaien zonder extern SRAM als je de TXbufSize en RXbufSize klein zet (als je een string schrijft die niet past gaat het goed maar moet je wachten), als je ".org RAMEND + 1" wijzigt in ".org RAMFREE" en de SRAMloop uitremt.
Als je een ander kristal dan 6 Mhz gebruikt, moet je ook de waarde van baud96 aanpassen.
Ik kan eventueel ook zelf de aanpassingen maken en een versie posten die zonder aanpassingen werkt op een kale AT90S8515.
Ik gebruik trouwens de assembler van Atmel.
Edit: ik heb zelfs geprobeert alles in InitAll uit te remmen en rechtstreeks een char naar de UART te schrijven, met hetzelfde resultaat. Maar er zijn dan natuurlijk nog steeds een heleboel andere dingen die toch invloed kunnen hebben. Het is lastig de zaak te debuggen als de terminal niet werkt, ik heb nog niet kunnen ontdekken hoe ik in AVRstudio extern SRAM kan aanmelden als ik hem niet ook laat programmeren (ik gebruik de programmer van deze site met PonyProg).
[Bericht gewijzigd door DiGuru op ]
Ok. Ik heb de source aangepast. Het draait nu ook op een AT90S8515 zonder extern geheugen (en waarschijnlijk op de meeste andere AVR's met minimaal 256 bytes RAM), je moet nog wel de waarde van "baud96" aanpassen aan de waarde van je kristal: 25 voor 4Mhz of 51 voor 8Mhz.
[Bericht gewijzigd door DiGuru op ]
Vaag verhaal, DiGuru.. Of eigenlijk een duidelijk verhaal, maar een vaag gebeuren.
Ik heb op diverse controllers en uPs in assembly gewerkt en inderdaad, de assembler moet (indien nodig) extra 0-en toevoegen. Daar is het ding voor, anders kan ik net zo goed direct zelf m'n hexfiletje tikken...
Echter... Ik heb ook al meerdere compilers / assemblers gevonden waar fouten in zitten. Ik zou als ik jou was die zelfde code eens door een andere assembler heen trekken en eens kijken wat voor hex file je dan hebt. Heb hier ook nog wel ergens AVR studio, al is het ruim een jaar geleden dat ik er voor het laatst wat mee gedaan heb.
Groet
Marco
Ja, ik verwacht zelf ook dat het een bug is in de assembler. Ik kwam een mailinglist tegen waar nog wat meer foutjes naar voren werden gebracht, waarna een ontwikkelaar van de assembler reageerde dat er inderdaad wat slordigheidjes inzaten.
Nou ja, ik weet waar ik op moet letten.