Forum: Mikrocontroller und Digitale Elektronik SWI Handler erklärung?


von nfs2k (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von nfs2k (Gast)


Lesenswert?

mehr ist leider in dieser File nicht an code drinnen !?

von Alexander M. (Firma: FAMOS) (famos)


Lesenswert?

hab zwar keine Ahnung von Assembler, aber das pdf file kann das glaub 
ich ;)

http://www.jegerlehner.ch/intel/index_de.html

grüße

von Peter D. (peda)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von nfs2k (Gast)


Lesenswert?

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

von Joghurt3k (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.