hi ihr MI - Asse :-)
kann mir jemand von euch diesen assembler code erklären und oder auch
kommtentieren zeile für zeile :-) ?
danke :-)
mfg nfs2k
.global SWIHandler
.text
SWIHandler:
ldr sp, STACK
stmfd sp!, {lr}
ldr ip,[r14, #-4]
bic ip, ip, #0xff000000
mov ip, ip, lsl #2
ldr lr, =SWIJumpTable ablegen
ldr ip, [lr, ip]
mov lr, pc
mov pc, ip
ldmfd sp!, {pc}^
STACK:
.word 0x78c
SWIJumpTable:
.word init_ser @SWI0
.word putchar @SWI1
.word getchar @SWI2
.end
Ja, nö. Is ja auch so popeleinfach, irgendnen Code voll ausm Kontext gerissen zu erklären. Du weißt bestimmt deutlich mehr, wozu der Code gehört und was er machen soll und überhaupt, welcher CPU-Core, als Du hier verraten willst. Peter
hab zwar keine Ahnung von Assembler, aber das pdf file kann das glaub ich ;) http://www.jegerlehner.ch/intel/index_de.html grüße
nfs2k schrieb:
> mehr ist leider in dieser File nicht an code drinnen !?
Nicht mehr Code, sondern grundsätzliche Projektinformationen.
Dann ist eben nicht mehr Antwort drin, die Kristallkugeln sind nämlich
grade alle zur Reparatur.
Peter
SWI #0 => Aufruf von init_ser SWI #1 => Aufruf von putchar SWI #2 => Aufruf von getchar SWI sonst => undefiniert, lies: Handler ist Schrott. Zeile für Zeile erklärt dir ein ARM Handbuch.
Oberfläche :Ubuntu
Tools:
Snavigator
(terminalersatz)
In der Aufgabe soll ein SWI Handler genutzt werden, um eine Trennung des
Low Level
IOs vom Anwendungsprogramm zu erreichen. Dazu sind die Funktionen die
den SWInterrupt
aufrufen in Assembler zu implementieren und mit dem Debugger ist die
Funktionsweise des
Interrupthandlers zu untersuchen.
Es sollen die Funktion puts (siehe ser_io.S) in Assembler so ergänzen,
dass auch der
String auf die serielle Schnittstelle ausgegeben wird. Die IO-Funktionen
putchar und
getchar (siehe seriell.S) werden dabei über einen SWI (siehe swi.S)
aufgerufen.
void puts(char *) Ausgabe eines nullterminierten Strings und Ersetzung
von Newline
durch Carriage Return (0x0d) und Linefeed (0x0a).
Nun ist der Code des SWI-Handlers zu erklären ?????? :-))) (siehe
swi.S).
3 dateien sind beinhaltet : oben genannte swi.s
+ 2 folgende
hoffe es hilft ein bischen weiter
___________
@-----------------------------------------------------------------------
-----
@ File Name : ser_io.S
@ Object : Ein- Ausgabe-Funktionen der seriellen
Schnittstelle
@-----------------------------------------------------------------------
-----
@ Debuginformationen
.file "ser_io.S"
@ Funktion
.text
.align 2
.global inits
.type inits,function
inits:
stmfd sp!,{lr} @ Retten der Register
swi 0
ldmfd sp!,{pc} @ Rücksprung
@ Funktion
.text
.align 2
.global puts
.type puts,function
puts:
stmfd sp!,{lr} @ Retten der Register
// Hier muß Ihr Code eingefügt werden.
mov r1,r0
puts_start:
ldrb r0,[r1],#1
cmp r0,#0
beq puts_end
// /n /r
cmp r0,#0x0a
moveq r0,#0x0d
swieq 1
moveq r0,#0x0a
bl putchar
b puts_start
puts_end:
ldmfd sp!,{pc} @ Rücksprung
@ Funktion
.text
.align 2
.global gets
.type gets,function
gets:
stmfd sp!,{lr} @ Retten der Register
// Hier könnte Ihr Code eingefügt werden!
ldmfd sp!,{pc} @ Rücksprung
.end
-----------------
@-----------------------------------------------------------------------
-----
@ File Name : seriell.S
@ Object : Grundfunktionen der seriellen Schnittstelle
@-----------------------------------------------------------------------
-----
.file "seriell.S"
#include "../h/pmc.inc"
#include "../h/pio.inc"
#include "../h/usart.inc"
DEFAULT_BAUD = 38400
CLOCK_SPEED = 25000000
US_BAUD = 0x29 @ CLOCK_SPEED / (16*(DEFAULT_BAUD))
@ Funktion
.text
.align 2
.global init_ser
.type init_ser,function
init_ser:
stmfd sp!, {r0-r3, lr} @ Register retten
adr r0,L1
adr r1,L1_end
init_ser_loop:
ldmia r0!, {r2-r3}
cmp r0, r1
str r3, [r2]
bne init_ser_loop
ldmfd sp!, {r0-r3, pc} @ Rücksprung
L1:
.word PMC_BASE+PMC_PCER, 0x4
.word PIOA_BASE+PIO_PDR, 0x18000
.word USART0_BASE+US_CR, 0xa0
.word USART0_BASE+US_MR, 0x8c0
.word USART0_BASE+US_BRGR, US_BAUD
.word USART0_BASE+US_CR, 0x50
L1_end:
@ Funktion
.text
.align 2
.global putchar
.type putchar,function
putchar:
stmfd sp!, {r0-r2, lr} @ Register retten
ldr r2, =USART0_BASE
1:
ldr r1, [r2, #US_CSR]
tst r1, #US_TXRDY @ ist Transmitter frei
beq 1b
str r0, [r2,#US_THR]
ldmfd sp!, {r0-r2, pc} @ Rücksprung
@ Funktion
.text
.align 2
.global getchar
.type getchar,function
getchar:
stmfd sp!, {r1, r2, lr} @ Register retten
ldr r2, =USART0_BASE
1:
ldr r1, [r2, #US_CSR]
ands r1, r1, #US_RXRDY
beq 1b
ldr r0, [r2, #US_RHR]
ldmfd sp!, {r1, r2, pc} @ Rücksprung
.end
Moin, also SWIs sind 'ne Möglichkeit anderen Programmen Funktionen von
dem Code der die Interrupts verwaltet zugänglich zu machen. Ich hab'
z.B. 'n Bootloader geschrieben der gleichzeitig auch eine Interrupt
getriebene serielle USB Schnitstelle bereitstellt. Damit dann das
Programm, das hochgeladen wird nicht den ganzen Interrupt code und den
für USB CDC/ACM nochmal beinhalten muss mache ich dann die putc, getc,
... via SWIs sichtbar.
ldr sp, STACK <- setzt den Stack Pointer auf Adresse
STACK
stmfd sp!, {lr} <- wirft die ReturnAddr. auf den Stack
ldr ip,[r14, #-4] <- holt den auslösenden SWI opcode
bic ip, ip, #0xff000000 <- extrahiert SWI Nummer
mov ip, ip, lsl #2
ldr lr, =SWIJumpTable ablegen
ldr ip, [lr, ip] <- lädt SWI-Fkt. Adresse
mov lr, pc
mov pc, ip <- ruft SWI-Fkt auf
ldmfd sp!, {pc}^ <- return;
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.