Forum: Mikrocontroller und Digitale Elektronik PIC18 C18 Interrupt in Assembler schreiben


von Thomas W. (thomas0906)


Lesenswert?

Hallo

Aus Geschwindigkeitsgründen möchte ich eine Interruptroutine in 
Assembler schreiben.

1. Möglichkeit
Inline Assembler.
Ich habe aber nicht herausgefunden, wie ich dort C Variablen nutzen 
kann.
Gibt es da ein Beispiel?
Oder ganz einfach File Register sharen?

2. Möglichkeit
.asm File mit dem Linker dazulinken.
Wie muß dann aber der Code im .asm File aussehen, so daß er vom C File 
aufgerufen werden kann? Gibt es auch dafür ein Beispiel?
Hier das gleiche Problem mit den Variablen.

Danke für Tips
Thomas

von Purzel H. (hacky)


Lesenswert?

Ja. sicher geht das. Sowas muesst im Manual zum Compiler erklaert sein. 
Worum geht es denn ? Welchen Compiler ?

von Thomas W. (thomas0906)


Lesenswert?

Hi

Steht in der Überschrift:

C18 und MPLAB.

Leider ist das sehr sehr sehr schlecht bis garnicht erklärt in der
Compileranleitung. Daher suche ich auch ein Beispiel.

Gruß
Thomas

von Thomas W. (thomas0906)


Lesenswert?

Schade, scheint wohl niemand zu machen :-/

von Max (Gast)


Lesenswert?

Seite 18 hier kennst du aber, oder?

http://gputils.sourceforge.net/51288a.pdf

von Thomas W. (thomas0906)


Lesenswert?

For example:
_asm
  /* User assembly code */
  MOVLW 10       // Move decimal 10 to count
  MOVWF count, 0
  /* Loop until count is 0 */
  start:
    DECFSZ count, 1, 0
    GOTO done
    BRA start
  done:
_endasm
Was z.B. ist count?

Und hier die Super Anleitung zum Datenaustausch und DazuLINKEN:
It is generally recommended to limit the use of inline assembly to a 
minimum. Any
functions containing inline assembly will not be optimized by the 
compiler. To write large
fragments of assembly code, use the MPASM assembler and link the modules 
to the C
modules using the MPLINK linker.

Mehr steht zu dem Thema in der ganzen Anleitung nicht!

Da steht, daß man das machen kann, was ich machen will.
Da steht aber nicht, WIE ich das machen kann und wie die 
Schnittstellenvariablen und Funktionsaufrufe auszusehen haben, um 
zwischen C und Assembler Variablen Daten auszutauschen.



Gruß
Thomas

von Wilhelm F. (Gast)


Lesenswert?

Thomas W. schrieb:

> Da steht, daß man das machen kann, was ich machen will.
> Da steht aber nicht, WIE ich das machen kann und wie die
> Schnittstellenvariablen und Funktionsaufrufe auszusehen haben, um
> zwischen C und Assembler Variablen Daten auszutauschen.

Hast du einen Compiler in Vollversion, oder eine Demo bzw. Freeware, 
Light-Version?

Beim PIC ist das sehr schräg, machte mit einem HiTech-Light-Compiler 
(für 12F675) auch keine gute Erfahrung. Verschiedene Besonderheiten 
findet man in der Doku einfach nicht.

von holger (Gast)


Lesenswert?

>Da steht, daß man das machen kann, was ich machen will.
>Da steht aber nicht, WIE

Geh mal in das Verzeichnis deiner C18 Installation.
Dort gibt es ein src Verzeichnis. Da gibt es jede Menge
Quellcode für die stdclib in ASM. Schau dir da halt was ab.

von ich (Gast)


Lesenswert?

zu 1.):

Du könntest das vielleicht auf 2 Weisen machen.

1.) Falls das geht (ich nehme mikroC und da geht das), du guckst in der 
Übersicht oder Statistik nach, welche Speicheradresse er für welche 
Variable reserviert. Ich kann beim mikroC z.B. gucken, welche Variable 
welche Adresse im RAM hat oder welche "Unter-Funktion" welche Adresse im 
Programmspeicher hat. Dann könntest du da nachgucken, und in Assembler 
dann diese Adresse benutzen.

2.) Falls dein Compiler das ausgibt, lass dir die ASM-Datei ausgeben. 
Als interrupt machst du einfach dein ASM und als Adressen nimmst du 
erstmal irgendeinen Namen oder irgendeine (Eindeutige) Adresse. Danach 
suchst du das in der erzeugten ASM-Datei und suchst dir die richtige 
Adresse raus. Zugegebener weise eher eine unsaubere Lösung, aber gehen 
sollte es.

3.) Eventuell kannst du bei der Variablen-Dekleration in C schon eine 
feste Adresse bestimmen, die diese Variable haben soll. Dann ist das ja 
kein Problem.

von Loonix (Gast)


Lesenswert?

Die Tipps von "ich" würde ich ganz schnell wieder vergessen weil 
unbrauchbar und unprofessionell. Da sieht man mal wieder dass in diesem 
Forum kaum jemand seine Werkzeuge anständig beherrscht. Die MPLAB-Doku 
sagt zum Thema ASM und C mischen alles, was man dazu wissen muss. Aus 
irgend einem Grund geht man bei Microchip wohl davon aus, dass man wohl 
zumindest den MPASM ein wenig kennt...

Also, im Datenblatt eines jeden PIC steht genau wo sich dessen Reset- 
und Interruptvektor(en) befinden. Man nimmt jetzt ein neues ASM-File und 
schreibt:
1
#define RESET_VECTOR_ADDR   0x0000
2
#define HI_INT_VECTOR_ADDR  0x0008
3
#define LOW_INT_VECTOR_ADDR 0x0018
4
5
        code HI_INT_VECTOR_ADDR
6
HiIntVect
7
    goto HiISR
8
9
10
        code
11
HiISR
12
/* hier den code der ISR platzieren,
13
   Kontext speichern und Interrupt-Flag
14
   löschen nicht vergessen */
15
        retfie

Jetzt ist dafür gesorgt dass der PIC beim Eintritt in den 
Interruptvektor einen Sprung zur Interruptroutine ausführt.

von ich (Gast)


Lesenswert?

Es geht doch aber hier nicht um dir Routine selbst, sondern , wie man in 
dieser Routine mit einem Inline-ASM die Variablen "von" dem C-Programm 
benutzen kann. Bei meinen ersten beiden Punken gebe ich dir recht, dass 
es eine recht unsaubere Lösung ist (wie ich ja auch geschrieben habe). 
Aber wenn man im C-Programm die Variable schon einer festen Adresse 
zuweisen kann, sodass man im Inline-ASM genau weiß, welche Variable, 
welche Adresse hat, weiß ich nicht, was daran schlecht sein soll. Aber 
ich lerne auch immer gerne dazu.

von Loonix (Gast)


Lesenswert?

ich schrieb:
> Es geht doch aber hier nicht um dir Routine selbst, sondern , wie man in
> dieser Routine mit einem Inline-ASM die Variablen "von" dem C-Programm
> benutzen kann.

Und genau das ist in der MPLAB-Hilfe erklärt. Einfach mal lesen.

ich schrieb:
> Aber wenn man im C-Programm die Variable schon einer festen Adresse
> zuweisen kann, sodass man im Inline-ASM genau weiß, welche Variable,
> welche Adresse hat, weiß ich nicht, was daran schlecht sein soll.

Weil der Name einer Variable, den du im Programm verwendest ein 
Platzhalter für die Adresse ist. Es wird eindeutig beschrieben wie mit 
den Keywords "global" und "extern" unter MPASM umzugehen ist. Dadurch 
reicht es, die passenden Variablennamen zu verwenden. Was ist jetzt 
einfacher und eindeutiger? Ein- und derselbe Name für den Zugriff auf 
dieselbe Variable oder ein Name und eine Zahl, die im Zweifelsfall immer 
beide überprüft werden müssen?

von Thomas W. (thomas0906)


Lesenswert?

Hi

Tja, da ich zu blöd bin, um das in der Doku zu finden, werde ich mal 
folgendes probieren:

Im C Code eine VAR als global definieren.
Im ASM Code VAR als extern definieren und dann
den ASM Code compilieren uns später dazulinken.

Dazu die Prozedur im ASM Code als global definieren und im C Programm 
als extern definieren.

mal sehen, ob es klappt, dort im ASM Code eine Wert reinzuschreiben,
um ihn dann im C Code weiterzuverwenden.

Wie gesagt, im Zweifel schreibe ich in die File Register, die haben ja 
feste Adressen.



Gruß
Thomas

von Loonix (Gast)


Lesenswert?

Thomas W. schrieb:
> Tja, da ich zu blöd bin, um das in der Doku zu finden, werde ich mal
> folgendes probieren:

So wars nicht gemeint, daher:

MPLAB->Help->Topics->C18 Users Guide->Index

und

"mixing C and assembly" in der Suchzeile eingeben

von Lehrmann M. (ubimbo)


Lesenswert?

Thomas W. schrieb:
> Aus Geschwindigkeitsgründen möchte ich eine Interruptroutine in
> Assembler schreiben.

Ich möchte an dieser Stelle bemerken, dass es für die Geschwindigkeit 
kaum irgendwas bringt, wenn man selbst in Assembler seinen Code 
verfasst. Im Normalfall (und das sei betont) ist der Compiler mit seinen 
Optimierungen gleicht gut, bei Anfängern mit Sicherheit sogar besser. 
Wenn man wirklich besser (hier schneller) sein will als der Compiler, 
dann muss man verdammt gut Assembler können und vor allem viel viel 
Erfahrung in dieser Hinsicht mitbringen, soweit der Code überhaupts 
optimierungen zulässt. Sei mir nicht böse, aber ich glaube nicht, dass 
du diese Erfahrung besitzt (deinen Postings nach zu urteilen).
Ein Einsatzgebiet wo ich sagen würde, da ist es legitim Asm zu benutzen 
ist, wenn es zeitkritisch wird (ich muss genau wissen wieviele Fosc/4 
meine ISR braucht, ...).

Ansonsten wirst du deinen Code nur aufblähen. Ich glaube nicht, dass dir 
das Assembler-Programmieren an dieser Stelle irgendwas bringt. Ich habe 
eher die Vermutung, dass dein Code größer und zeitintensiver wird, als 
wenn du constant mit C durchgehst.

Als alternative kannst du ja alles in C machen und dir dann vom Compiler 
das *.asm File anschauen und da dann noch optimieren, soweit dir das 
möglich ist. Kommt genau auf's gleiche raus. Die ISR zu finden sollte ja 
nicht zu schwer sein.

von Thomas W. (thomas0906)


Lesenswert?

Hi

Mein Fall ist ein anderer.
Ich habe schon ein komplettes Assembleprogramm.
Das mlchte ich auf C umstellen, weil ich noch einiges erweitern möchte.
Tja und einige Programmteile sind so optimiert und funktionieren 
perfekt, so daß ich diese behalten möchte. Auch eine Interruptroutine.

Gruß
Thomas

von Lehrmann M. (ubimbo)


Lesenswert?

Thomas W. schrieb:
> Mein Fall ist ein anderer.
> Ich habe schon ein komplettes Assembleprogramm.
> Das mlchte ich auf C umstellen, weil ich noch einiges erweitern möchte.
> Tja und einige Programmteile sind so optimiert und funktionieren
> perfekt, so daß ich diese behalten möchte. Auch eine Interruptroutine.

Das ändert aber nichts daran, dass Inlineassembler nicht das Optimum 
ist, da da der Compiler nicht seine vollen Optimierungskünste zur 
Geltung bringen kann.

Wie gesagt, Assembler bringt nur was bei zeitkritisch, nicht bei 
geschwindigkeitskritisch. Von daher ist diese Diskussion ohnehin 
hinfällig - hättest du uns gleich gesagt, was du vor hast, wären wir 
nicht abgeschweift.

Wünsche noch viel Erfolg bei der Portierung und im Ernstfall mal die 
kompilierte *.asm anschauen ...

von Loonix (Gast)


Lesenswert?

Lehrmann Michael schrieb:
> Das ändert aber nichts daran, dass Inlineassembler nicht das Optimum
> ist, da da der Compiler nicht seine vollen Optimierungskünste zur
> Geltung bringen kann.

Das ist nunmal so bei Assembler, egal ob Inline oder nicht.

Lehrmann Michael schrieb:
> Wie gesagt, Assembler bringt nur was bei zeitkritisch, nicht bei
> geschwindigkeitskritisch. Von daher ist diese Diskussion ohnehin
> hinfällig - hättest du uns gleich gesagt, was du vor hast, wären wir
> nicht abgeschweift.

Abgesehen davon, dass diese zwei Welten oft nah beieinander liegen 
wüsste ich nicht wo das einen Einfluss auf die Lösung gehabt hätte. 
Besagte Lösung erschliesst sich einem allerdings erst wenn man die von 
mir zitierten Schritte in MPLAB durchgeht und die Compiler-Doku liest. 
Dadurch ist der von dir befürchtete Missbrauch durch unbedarfte Anfänger 
schon fast nicht mehr möglich, da man sich nach dem Studium des 
Compiler-Handbuchs schon als Edel-Anfänger betrachten darf der zum 
experimentieren mit ASM/C-Mixturen berechtigt ist. ;)

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.