Icall()

Icall() Ist eine Funktion zum indirekten Aufruf von Methoden über Funktionspointer.

Syntax

  • Icall( Adresse[, Parameterdefinition( Parameter1, Parameter2, .. )] )

Die Parameterdefinition wird genutzt, wenn Parameter der Methode übergeben werden sollen. Adresse ist die Adresse der Methode im Programmspeicher (Flash).

Wichtige Hinweise

  • Für indirekte Aufrufe von Luna-Methoden im Programm, wird #odecl erwartet.
  • Bei Controllern mit mehr als 128k Flash wird das Bank-Register „RAMPZ“ und der Assemblerbefehl „eicall“ verwendet. „RAMPZ“ speichert auf dem Avr die oberen Bits (16-24) einer Flashadresse. D.h. verwendet die aufgerufene Methode „von Hand“ erstellte Assembler-Funktionen/Befehle zum Flashzugriff oder kann durch solche Funktionen unterbrochen werden (ISR mit solchen Funktionen), muss am Beginn der aufgerufenen Methode das Register „RAMPZ“ auf Null zurückgesetzt werden. Nach Rückkehr vom Aufruf wird das Register „RAMPZ“ jedoch automatisch zurückgesetzt.

Siehe auch: #cdecl, #odecl, #idecl

Beispiel

' --------------------------------------------
' ICALL Example
' Beispiel zur Nutzung von Funktionspointern
' --------------------------------------------
' System Settings
' --------------------------------------------
const F_CPU  = 20000000
avr.device	= atmega328p
avr.clock	= F_CPU
avr.stack	= 48
 
uart.baud = 19200
uart.Recv.Enable
uart.send.enable
 
#define LED1	as portd.5
#define LED2	as portd.6
#define LED3	as portd.7
 
'Funktions prototyp
'Deklariert wieviele und welche Art Parameter einer Parameterübergabe aussehen
'Dabei bedeutet:
' #cdecl = Alle Parameter werden über den Stack übergeben.
' #odecl = 1. Parameter wird über Registerblock A übergeben,
'          Nachfolgende über den Stack.
' #idecl = 1. und 2. Parameter werden über Registerblock A und B übergeben,
'          Nachfolgende über den Stack. Jedoch darf der erste Parameter hierbei KEIN
'          Ausdruck sein, sondern nur eine einzelne Variable, Adresse, Konstante o.Ä.
' Syntax: #cdecl <datatype/void> Bezeichner( [<byRef/byVal>] <datatype>, .. )
 
#odecl byte func_p(byte)
#odecl void proc_p(byRef byte,word)
'        |     |     |     |    |
'        |     |     |     |    +Datentyp 2.Parameter
'        |     |     |     +Datentyp 1.Parameter
'        |     |     +Übergabetyp (optional), Referenz oder Wert(Vorgabe)
'        |     +Bezeichner der Parameterdeklaration
'        +Rückgabetyp, bei Proceduren "void"
'
LED1.mode = output
LED2.mode = output
LED3.mode = output
 
dim a,b as byte
dim ptr1,ptr2,ptr3 as word
 
print 12;
 
'Funktionspointer der Methoden erstellen
ptr1=test().Addr
ptr2=myproc.Addr
ptr3=myfunc.addr
 
print "ptr1 = 0x";hex(ptr1)
print "ptr2 = 0x";hex(ptr2)
print "ptr3 = 0x";hex(ptr3)
 
do
  icall(ptr1)
  icall(ptr2,proc_p(a,b))
  b=icall(ptr3,func_p(b))
  print 13;
loop
 
procedure test()
  LED1.toggle
  print " | test()";
  waitms 300
endproc
 
function myfunc(a as byte) as byte
  LED3.toggle
  incr a
  print " | myfunc(): a=0x";hex(a);
  waitms 300
  return a
endfunc
 
procedure myproc(byRef a as byte,b as word)
  LED2.toggle
  incr a
  print " | myproc(): a=0x";hex(a);", b=0x";hex(b);
  waitms 300
endproc