Hallo,
C++
Man kann doch eine Funktionen entweder erst deklarieren und später
definieren oder gleich definieren und damit auch deklarieren. Ich hätte
gern gewusst, wie der Syntax für eine Funktionsdefinition lauten muss
mit diesen Optionen um sie gleich zu definieren? Ohne vorher deklarieren
zu müssen.
man erhält
" an asm-specification is not allowed on a function-definition"
Der Hintergrund ist, ich möchte gern etwas Header only programmieren,
ohne .cpp.
Hallo,
Target wäre AVR ATmega 8Bit und der Compiler avr-gcc 9.3.0. Aktuell
Atmega2560 und 328P. Mit getrennter Deklaration und Definition in .h.
und .cpp funktioniert es. Ich hätte es gern, falls möglich, Header only.
Der Ursprung ist von hier:
https://www.mikrocontroller.net/articles/AVR_Interrupt_Routinen_mit_C%2B%2B
Veit D. schrieb:> Der Ursprung ist von hier:
Da wird nur erklärt, wie das Macro ISR intern arbeitet. Im Usercode
haben die Internas nichts verloren. Es sein denn, man will den
Unleserlichkeits-Kontest gewinnen.
ISRs werden auch nicht von extern aufgerufen, sondern von der
Interruptlogik. Daher gehören sie nicht in ein h-File.
Peter D. schrieb:> Daher gehören sie nicht in ein h-File.
Mein reden seit 1840 ...
Eine ISR darf nur einmal definiert werden, darum hat sie in einer *.h
nichts zu suchen.
Denn:
Eine *.h welche nur einmal eingebunden werden darf, ist Sinnverzerrt.
Hallo,
jetzt dämmerts, habs kapiert. Danke euch.
Der Hintergrund ist folgender warum ich meine Lib auf Header only
umbauen wollte.
Ich möchte eine vorhandene Template Klasse/Lib einbinden.
Das funktioniert aber nur wenn meine Lib Header only ist.
Weil ein Template in einer .cpp nicht gebaut werden kann.
Damit sitze ich in der Falle.
Entweder verzichte ich auf die vorhandene "Template Lib" oder ich muss
mir Gedanken machen wie ich das mit der ISR anderweitig gelöst bekomme.
Peter D. schrieb:> Veit D. schrieb:>> Der Ursprung ist von hier:>> Da wird nur erklärt, wie das Macro ISR intern arbeitet. Im Usercode> haben die Internas nichts verloren. Es sein denn, man will den> Unleserlichkeits-Kontest gewinnen.
Der Code wird nicht weniger leserlich dadurch, dass er im Header steht.
Und wenn ich als Anwender wissen will, wie ich die Funktionen benutze,
schaue ich in die Doku, nicht in den Header.
> ISRs werden auch nicht von extern aufgerufen, sondern von der> Interruptlogik. Daher gehören sie nicht in ein h-File.
Das wiederum sehe ich auch so.
Veit D. schrieb:> Entweder verzichte ich auf die vorhandene "Template Lib" oder ich muss> mir Gedanken machen wie ich das mit der ISR anderweitig gelöst bekomme.
Mir ist das Problem nicht klar. Deine ISR soll ein Template sein? Das
ergibt irgendwie keinen Sinn. Und wenn sie kein Template ist, warum muss
sie dann im Header stehen?
Hallo,
Missverständnis. Die ISR ist kein Template. Geht ja nicht.
Meine SPI Lib ist auch keine Template Klasse.
Alles funktioniert so wie gewollt.
Jetzt möchte ich zum Pin schalten die PinLib von Arduino Fanboy
einbinden. Seine Lib ist eine Template Klasse.
Kann ich so nicht einbinden, eben weil Templates.
Darum muss meine SPI Lib auch eine Template Klasse sein - Header only.
Ich habe dazu auch schon eine neue Idee die ich im Moment umsetze.
Es geht allgemein darum wie man eine einzige ISR für mehrere Objekte
einer Klasse verwendet. Zeige ich sobald das fertig. Wenn das nicht
klappt, dann hat sich mein Problem hier sowieso erledigt. :-) Dann
bleibt alles wie es derzeit ist.
Sorry für das Durcheinander. Konnte anfangs nicht erahnen wie verzwickt
das wird. :-)
Hallo,
habe es am laufen. :-)
Ich habe jedoch noch einen Schönheitsfehler drin.
Und zwar muss die ISR den CS Pin wieder auf High setzen wenn alle Daten
aus dem Buffer sind.
Derzeit setze ich von allen Instanzen den Pin auf High.
Ich würde auch hier gern über den Zeiger auf den Pin vom aktuellen
Objekt zugreifen.
Mache ich das in einer Trockenübung klappt das. Es blinkt.
1
#include<CombiePin.h>
2
usingnamespaceCombie::Pin;
3
OutputPin<13>pin;
4
5
voidsetInit(void)
6
{
7
pin.init();
8
}
9
10
voidsetPinHigh(void)
11
{
12
pin.setHigh();
13
}
14
15
voidsetPinLow(void)
16
{
17
pin.setLow();
18
}
19
20
void(*ptrFunction)()=nullptr;
21
22
voidsetup(void)
23
{
24
ptrFunction=setInit;
25
(*ptrFunction)();
26
}
27
28
voidloop(void)
29
{
30
ptrFunction=setPinHigh;
31
(*ptrFunction)();
32
delay(500);
33
34
ptrFunction=setPinLow;
35
(*ptrFunction)();
36
delay(500);
37
}
Mach ich das im Headerfile, kann ich dem Zeiger keinen Funktionnamen
zuweisen. Auch ein verpacken in eine extra Funktion hilft nicht.
1
void(*ptrFunction)()=nullptr;// function pointer
2
ptrFunction=slaveSelectHigh;
Was ist dabei anders? Ist das möglich? Wenn ja wie?
Fehlermeldung ist:
1
TwoDevices.ino:13:
2
DevilSpi.h: In instantiation of 'void SpiSlave<csPin, divider>::init() [with unsigned char csPin = 11; unsigned char divider = 32]':
3
TwoDevices.ino:38:16: required from here
4
DevilSpi.h:94:19: error: cannot convert 'SpiSlave<11, 32>::slaveSelectHigh' from type 'void (SpiSlave<11, 32>::)()' to type 'void (*)()'
5
94 | ptrFunction = slaveSelectHigh;
6
| ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
7
DevilSpi.h: In instantiation of 'void SpiSlave<csPin, divider>::init() [with unsigned char csPin = 12; unsigned char divider = 8]':
8
TwoDevices.ino:39:16: required from here
9
DevilSpi.h:94:19: error: cannot convert 'SpiSlave<12, 8>::slaveSelectHigh' from type 'void (SpiSlave<12, 8>::)()' to type 'void (*)()'
PS: Die messPin Objekte sind nur für den Datalogger/Oszi drin.