Hallo Forum, ich überlege gerade mir eine Library für SPI zu bauen. Library im echten Sinne, also libspi-avr.a + spi.h . So weit die "Aufgabenstellung" Nur wenn ich bei eclipse AVR cross target static Library auswähle muss ich immer einen spezifischen AVR angeben und nur für diesen passt die lib dann. Bei allen anderen überspringt der Linker die unpassende lib und findet dann natürlich keine mehr. Möglicherweise liegt es am "static" im Namen. Was hat es damit auf sich? Ich meine mich zu erinnern, dass es auch noch "shared Libs" gibt, bin mir aber nicht mehr sicher. Dass der Linker meckert ist ja auch klar, so wie ich das sehe wir ganz normal der asm-Code generiert und gelinkt und dann in eine Library gepackt, damit man diese verwenden kann ohne dass der Compiler im Ziel-Projekt noch einmal drüber muss. So kann es aber ja sein, dass unpassender Code generiert wurde, etwa mit Op-Codes die der Ziel-AVR gar nicht hat. Aber beim PC ist es doch auch so, dass es nur eine Lib gibt, für verschiedene Architekturen, oder irre ich mich da? Also meine frage ob ich mit dem AVR-GCC solch eine "multi-avr-lib" zusammenbasteln kann. Von Hand zig mal die selbe lib zu erstellen ist mir zu aufwändig... Ein paar Schlüsselwörter zum googlen wären auch nicht schlecht, weil ich weiß ja nicht mal wie ich mein Problem genau beschreiben soll... mfG, N.G.
N. G. schrieb: > ber beim PC ist es doch auch so, dass es nur eine Lib gibt, für > verschiedene Architekturen, oder irre ich mich da? > nein, ja!
:
Wiederhergestellt durch Moderator
d.h. alle heutigen Prozessoren sind binärkompatilbel? Eher nicht
N. G. schrieb: > Aber beim PC ist es doch auch so, dass es nur eine Lib gibt, für > verschiedene Architekturen, oder irre ich mich da? Pssst. Das was landläufig unter PC verstanden wird, ist immer ein und dieselbe Prozessor Architektur - Intels So Dinge wie unterschiedliche Hardware als CPU-Erweiterungen sind entweder kompatibel oder werden über herstellerspezifische Treiber eingebunden. Tatsächlich unterschiedliche Prozessor Architekturen findet man Meinstream heute gar nicht mehr so oft. Und wenn, dann läuft da meistens ein Linux drauf und Programme werden als Source Code zum selber compilieren ausgegeben. Aber wenn wo Windows drauf steht, dann ist da ein Intel-Prozessor (oder kompatibler) drinnen. Und wenn nicht, wie zb beim RasPi auf dem Windows 10 läuft, dann brauchst du eigens dafür compilierte Programme (wenn es native laufen soll, was immer mehr aus der Mode kommt)
:
Bearbeitet durch User
D.h ich kann das wirklich nur so lösen, dass ich entweder den Sourcecode jedes mal kompiliere oder einmal für jedes meiner Devices eine lib erstelle? Gibt es da nicht evtl ein Format zum austausch oder eine ganz andere Lösung? (Sorry für die vllt dummen Fragen, aber irgendwie finde ich es komisch, dass es so was nicht gibt.) PS: Das mit den PC-CPU wusste ich zwar, aber es will immer noch nicht in meinen Schädel...
N. G. schrieb: > Gibt es da nicht evtl ein Format zum austausch oder eine ganz andere > Lösung? > z.B. Bytecode und die entsprechende VM dazu
N. G. schrieb: > D.h ich kann das wirklich nur so lösen, dass ich entweder den Sourcecode > jedes mal kompiliere Wo liegt das Problem? Typische AVR Programme kompilieren sich doch in diesen Bereichen in ein paar Millisekunden. Zude braucht man das pro Projekt nur ein einziges mal. Dann ist der Code ja compiliert und wird in weiteren Entwicklungszyklen nur mehr gelinkt. > Gibt es da nicht evtl ein Format zum austausch oder eine ganz andere > Lösung? Mir kommt vor, du siehst ein Problem wo es in der Praxis gar keines gibt. > PS: Das mit den PC-CPU wusste ich zwar, aber es will immer noch nicht in > meinen Schädel... Sei froh, dass es heutzutage so ist. Das war nicht immer so und oft war es schwierig, genau das Programm von dem man so viel gehört hatte und das man gerne haben wollte, genau für seine Maschine zu bekommen. Wie glücklich war ich, als ich endlich mal meine Finger an einen TCP/IP Stack für eine VAX (unter VMS) kriegte und damit aus Decnet ausbrechen konnte. Einen make Ersatz hab ich mir selber programmiert, weil ich in den diversen Gopher oder FTP Tummelplätzen einfach keinen finden konnte. War allerdings kein Vergleich mit dem make, das auf den Apollo Workstations nebenan lief.
:
Bearbeitet durch User
hääää schrieb: > N. G. schrieb: >> Gibt es da nicht evtl ein Format zum austausch oder eine ganz andere >> Lösung? >> > z.B. Bytecode und die entsprechende VM dazu Naja, wäre dann doch ein bisschen Overkill, meinst du nicht auch ;) Karl H. schrieb: > N. G. schrieb: >> D.h ich kann das wirklich nur so lösen, dass ich entweder den Sourcecode >> jedes mal kompiliere > > Wo liegt das Problem? > Typische AVR Programme kompilieren sich doch in diesen Bereichen in ein > paar Millisekunden. Zude braucht man das pro Projekt nur ein einziges > mal. Dann ist der Code ja compiliert und wird in weiteren > Entwicklungszyklen nur mehr gelinkt. Das stimmt natürlich, es geht mir auch nicht wirklich um Zeitersparnis, vielmehr wollte ich (meinem Spieltrieb gefolgt) einfach mehrere "Treiber" für die AVRs schreiben. Karl H. schrieb: >> Gibt es da nicht evtl ein Format zum austausch oder eine ganz andere >> Lösung? > > Mir kommt vor, du siehst ein Problem wo es in der Praxis gar keines > gibt. Mag schon sein. Wie schon gesagt, Spieltrieb... Karl H. schrieb: >> PS: Das mit den PC-CPU wusste ich zwar, aber es will immer noch nicht in >> meinen Schädel... > > Sei froh, dass es heutzutage so ist. Das war nicht immer so und oft war > es schwierig, genau das Programm von dem man so viel gehört hatte und > das man gerne haben wollte, genau für seine Maschine zu bekommen. Man merkt halt dass ich noch die Schulbank drücke ;) Wobei mich eigentlich vor allem die alte Technik interessiert, aber ich hatte noch nicht so viel Zugang zu alten Maschinen, dass mir das nennenswert aufgefallen wäre. Karl H. schrieb: > Wie > glücklich war ich, als ich endlich mal meine Finger an einen TCP/IP > Stack für eine VAX kriegte und damit aus Decnet ausbrechen konnte. Einen > make Ersatz hab ich mir selber programmiert, weil ich in den diversen > Gopher oder FTP Tummelplätzen einfach keinen finden konnte. Tja, bei mir war nur das Problem, dass ich nicht ins Internet konnte, wenn jemand telefonierte. Das konnt ich damals nicht durch programmieren lösen, und könnte es heute immernoch nicht ;)
Wer wirklich wissen will, welcher Aufwand dahinter steckt, solche "Binär-Biblioteken" zu bauen -> die AVRlibc gibt's komplett mit alle Build-Scripts als Source. Kein Vergleich zu einer SPI-Source, die per #ifdef mal schnell die ein oder andere Eigenheit bereinigt. Manches hängt ja garnicht vom Chip ab, sondern davon, daß ein USART-Register manchmal durchnummeriert ist, oder auch nicht. Die 100ms Compiletime wurden schon erwähnt.
:
Bearbeitet durch User
Hallo NG das was mit Hardware zu tun hat muss 'immer' MC bindend programmiert werden! Da es MCs gibt die 1 oder mehrere SPIs haben. Auch können einige mit 5 Bit bis 16 Bit im Datenregister umgehen. Das was du suchst, die Gemeinsamkeit, folgt danach! API. Alles was mit SPI zu tun hat, wie Speicher, Ethernet, LCD usw. sollte eine 'gemeinsame' API nutzen können. Selbst das ist nicht so einfach. Sieh dir mal den Code zu Arduino, die haben es versucht, viele MCs mit Hilfe einer API zu verbinden, aber es bleibt da viel auf der Strecke.
Man kann doch einen Präprozessor verwenden! Also in der Lib erstmal eine z.b. Funktion die speziell auf die Hardware abgestimmt ist (z.b. AES beim XMega). wenn jetzt ein AVR ohne internen AES verwendet werden möchte (z.b. ein normaler AVR) so wird jetzt die AES-Routine aktiv. Ist zwar langsamer als die XMega-AES-Hardwareintern, aber der Programmierer muss sioch nicht groß umstellen. Er wird sich nur über die arschlahmen Verarbeitungsgeschwindigkeit wundern.
N. G. schrieb: > hääää schrieb: >> N. G. schrieb: >>> Gibt es da nicht evtl ein Format zum austausch oder eine ganz andere >>> Lösung? >>> >> z.B. Bytecode und die entsprechende VM dazu > > Naja, wäre dann doch ein bisschen Overkill, meinst du nicht auch ;) > du scheinst nicht zu verstehen, um was es hier geht! Du möchtest einen (übersetzten) Code für alle AVRs schreiben, oder? Jeder dieser MCU hat aber unterschiedliche Hardware, Maschinenbefehle und Register. Wenn du einen plattformunabhängigen und vorübersetzten Code schreiben möchtest, kein Problem, aber du benötigst etwas, was diesen universellen Code mit den Spezifika der jeweiligen Plattform abarbeitet. Das ist wäre dann halt eine Art Interpreter oder VM, welche für jede MCU angepasst ist. Z.B. das allseits bekannte Java arbeitet genau so... Damit hast du aber plötzlich mehrere Baustellen: * den plattformspezifischen Interpreter/VM, der erst mal geschrieben werden muss * den Bytecode-Übersetzer, der den universellen Code für den plattformunabhängigen Interpreter/VM bereitstellt, auch der muss geschrieben werden * plus noch ein paar Kleinigkeiten, wie z.B. man den Bytecode durch die VM auf der MCU durchjagt etc. Fazit: es ist also wahrscheinlich doch einfacher mit diversen Makros, Defines etc. die plattformspezifischen Dinge im Quellcode abzuhandeln und dann jedes mal zu übesetzen. *
Hier mal eine Idee, die ich ein einem Soft-I2C umgesetzt hab: Das C-Modul ist allgemein gehalten und unabhängig von der Hardware. Read from und Write to SPI haben dann folgende Abhängigkeiten von der Hardware: 1) Ports, die für SDA und SCL zu verwenden sind 2) Geschwindigkeit, mit der der Soft-SPI arbeiten soll 3) Befehle zum Erreichen der atomarität und Nebenläufigkeit einzelner Aktionen. Zunächst zu 2): Die Geschwindigkeit ergibt sich durch die Aufrufrate, mit der der SPI-Treiber verwendet wird. Der I2C-Treiber ist eine State-Machine und führt alle N Aufrufe maximal 1 Port-Operation aus. Aufruf erfolgt aus einer "allgemeinen" Timer-ISR, die nicht zum I2C gehört. 3) Geschieht wie gesagt dadurch, dass der Treiber auf Interruptebene operiert. Er verwendet 2 FIFOs, die von einem externen FIFO-Modul gehandhabt werden. Am interessantesten ist 1) gelöst: Im Header gibt es die Deklaration einer externen Routine, welche die I2C-Portoperationen auszuführen hat: == i2c-soft.h ==
1 | #include "fifo.h" |
2 | ...
|
3 | |
4 | typedef struct |
5 | {
|
6 | fifo_t *fifo, *fifo_in; |
7 | ...
|
8 | } i2c_soft_t; |
9 | |
10 | enum
|
11 | {
|
12 | // SDA setzen
|
13 | I2CS_sda, |
14 | // SDA lesen
|
15 | I2CS_sda_get, |
16 | // SCL setzen
|
17 | I2CS_scl
|
18 | };
|
19 | |
20 | extern uint8_t i2cs_port (i2c_soft_t*, uint8_t port, uint8_t val); |
21 | extern void i2cs_init (i2c_soft_t*, fifo_t*, fifo_t*); |
22 | extern void job_i2c_soft (i2c_soft_t*); |
23 | ...
|
Die Implementierung von i2cs_port() erfolgt in der Applikation, z.B. == main.c ==
1 | #include <avr/io.h> |
2 | |
3 | #include "ports.h" |
4 | #include "i2c-soft.h" |
5 | |
6 | static i2c_soft_t i2c; |
7 | |
8 | ISR (TIMER2_COMPA_vect) |
9 | {
|
10 | ...
|
11 | job_i2c_soft (&i2c); |
12 | }
|
13 | |
14 | |
15 | inline __attribute__((always_inline)) |
16 | uint8_t i2cs_port (i2c_soft_t *ic, uint8_t port, uint8_t val) |
17 | {
|
18 | (void) ic; |
19 | |
20 | if (port == I2CS_sda) |
21 | {
|
22 | if (val) |
23 | CLR (PORT_SDA); |
24 | else
|
25 | SET (PORT_SDA); |
26 | }
|
27 | |
28 | if (port == I2CS_sda_get) |
29 | {
|
30 | val = 0; |
31 | if (IS_SET (PORT_SDA_IN)) |
32 | val = 1; |
33 | }
|
34 | |
35 | if (port == I2CS_scl) |
36 | {
|
37 | if (val) |
38 | CLR (PORT_SCL); |
39 | else
|
40 | SET (PORT_SCL); |
41 | }
|
42 | |
43 | return val; |
44 | }
|
Im Modul i2c-soft.c wird i2cs_port dann verwendet, um mit SDA und SCL zu spielen. Zur Bequemlichkeit gibt's da zunächst ein paar Abkürzungen: == i2c-soft.c ==
1 | #include "fifo.h" |
2 | #include "i2c-soft.h" |
3 | |
4 | #define INLINE inline __attribute__((__always_inline__))
|
5 | |
6 | static INLINE void |
7 | sda (i2c_soft_t *is, uint8_t val) |
8 | {
|
9 | i2cs_port (is, I2CS_sda, val); |
10 | }
|
11 | |
12 | static INLINE uint8_t |
13 | sda_get (i2c_soft_t *is) |
14 | {
|
15 | uint8_t val; |
16 | val = i2cs_port (is, I2CS_sda_get, 0 /* unused */); |
17 | return val; |
18 | }
|
19 | |
20 | static INLINE void |
21 | scl (i2c_soft_t *is, uint8_t val) |
22 | {
|
23 | i2cs_port (is, I2CS_scl, val); |
24 | }
|
25 | |
26 | ...
|
27 | |
28 | #define I2CS_DELAY 0
|
29 | |
30 | void job_i2c_soft (i2c_soft_t *is) |
31 | {
|
32 | if (I2CS_DELAY |
33 | && is->job.delay) |
34 | {
|
35 | is->job.delay--; |
36 | return; |
37 | }
|
38 | |
39 | uint8_t state = is->job.state; |
40 | |
41 | switch (state) |
42 | {
|
43 | case JOB_idle: |
44 | {
|
45 | int val = fifo_get (is->fifo); |
46 | if (-1 == val) |
47 | return; |
48 | |
49 | state = val; |
50 | }
|
51 | break; |
52 | |
53 | case JOB_start_sda0: |
54 | sda (is, 0); |
55 | state++; |
56 | break; |
57 | |
58 | case JOB_start_scl0: |
59 | scl (is, 0); |
60 | state = JOB_idle; |
61 | break; |
62 | |
63 | ...
|
64 | }
|
65 | |
66 | is->job.state = state; |
67 | |
68 | if (I2CS_DELAY) |
69 | is->job.delay = I2CS_DELAY; |
70 | }
|
Wie sieht nun der erzeugte Code aus? o job_i2c_soft aus i2s-soft.c ist geinlinet in die main.c ISR. o gleiches gilt für die Implementierung von i2cs_port von main, die also durch die Hintertür wieder in main landet. Die cases für JOB_start_sda0 und JOB_start_scl0, jetze in der ISR, sehen so aus:
1 | .L120: |
2 | sbi 0x5,1 ; 238 *sbi [length = 1] |
3 | ldi r24,lo8(2) ; 13 movqi_insn/2 [length = 1] |
4 | rjmp .L117 ; 704 jump [length = 1] |
5 | .L121: |
6 | sbi 0xb,7 ; 247 *sbi [length = 1] |
7 | ldi r24,0 ; 658 movqi_insn/1 [length = 1] |
8 | rjmp .L117 ; 702 jump [length = 1] |
Der case für JOB_idle:
1 | .L118: |
2 | ;; Z = i2c_soft->fifo |
3 | ld r30,Y ; 213 *movhi/3 [length = 2] |
4 | ldd r31,Y+1 |
5 | ;; Z = fifo->count |
6 | ;; if (0 == fifo->count) |
7 | ;; return -1; --> führt zu "break" in JOB_idle. |
8 | ld r24,Z ; 214 movqi_insn/4 [length = 1] |
9 | tst r24 ; 215 *cmpqi/1 [length = 1] |
10 | brne .+2 ; 216 branch [length = 2] |
11 | rjmp .L100 |
12 | ;; Die FIFO enthält mindestens ein Byte, gib dieses zurück |
13 | ;; else ... |
14 | movw r24,r30 ; 222 *movhi/1 [length = 1] |
15 | call fifo_get.part.2 ; 223 call_value_insn/2 [length = 2] |
16 | ;; Dieser Vergleich ist überflüssig, und zudem ginge er |
17 | ;; in 1 Instruktion weniger. |
18 | cpi r24,-1 ; 226 *cmphi/7 [length = 3] |
19 | ldi r18,-1 |
20 | cpc r25,r18 |
21 | breq .+2 ; 227 branch [length = 2] |
22 | rjmp .L117 |
23 | rjmp .L100 ; 707 jump [length = 1] |
24 | |
25 | ... |
26 | |
27 | .L117: |
28 | std Y+6,r24 ; 412 movqi_insn/3 [length = 1] |
29 | .L100: |
30 | /* epilogue start */ |
31 | pop r31 ; 551 popqi [length = 1] |
32 | pop r30 ; 552 popqi [length = 1] |
33 | ... |
Von fifo_get() wurde also nur ein Teil geinlint, nämlich der, der überprüft, ob die FIFO ein neues Kommando enthält (in dem Falle gibt sie 0...255 zurück, ansonsten -1). Obwohl der Code nicht optimal ist, ist der Overhead sehr klein, z.B. sind die Aufrufe i2cs_port() von und Verleiche auf Port-IDs in main.c komplett weggefallen. Im Projekt ist das i2c-soft.c nur ein C-Modul, aber das ginge genauso in einer Bibliothek, indem diese mit -flto -Os erzeugt wird und mit -flto -Os -fuse-linker-plugin gegen diese gelinkt wird. Verwendet hab ich avr-gcc-5.2. Wichtig ist bei diesem Ansatz der Verzicht auf Callbacks.
:
Bearbeitet durch User
Ich glaube anfangs denkt jeder darüber nach, aber dann stellt man fest, das man seinen oder seine (paar wenige) µC's gefunden hat und da ist es einfacher den Code möglichst unabhängig zu schreiben, um nur noch die Deklaration ändern zu müssen (vornehmlich die Pin Zuordnung). Ein paar Sachen wiederverwendbar auszulagern macht da mehr Sinn, wie im diesem Beispiel: Beitrag "Re: Library für alle AVRs erstellen"
Karl H. schrieb: > Das was landläufig unter PC verstanden wird, ist immer ein und dieselbe > Prozessor Architektur - Intels Naja, mittlerweile sind es zwei, Intels und AMDs (die offiziell leise weinend in "x86_64" umbenannt worden ist, nachdem Intel sie schnell noch adoptiert hat), und entsprechend gibt es nunmehr selbst in der heilen Windowswelt oft zwei Binärversionen von einem Programm, die dann "32 bit" und "64 bit" tituliert werden. Beim AVR kommt's drauf an. Wenn man sich die Architektur-Klassen in der avr-libc bzw. die Multilib-Optionen im AVR-GCC ansieht, bekommt man ein Gefühl dafür, was man da binär in einen Topf werfen kann und tatsächlich in einer Bibliothek implementieren könnte. Was dann allerdings noch bliebe ist, dass nicht in jedem AVR der SPI-Modul auf der gleichen Adresse liegt. Man könnte die Adressen über das API übergeben, dann verzichtet man jedoch auf die Möglichkeit, dass der Compiler IN/OUT-Befehle für den Zugriff benutzt, und muss immer über MMIO gehen. (Bei IN/OUT ist die Registeradresse Bestandteil des Opcodes und muss daher zur Compilezeit bekannt sein. Bei MMIO kann man über Zeigerregister die Bindung auf die Laufzeit verschieben.) Alternativ kann man natürlich abseits der Multilib-Optionen noch eine Unterteilung vornehmen in die AVRs, die SPI auf 0x2C … 0x2E haben (alle neueren) und die, die es auf 0x0D … 0x0F haben: ATmega128A ATmega128 ATmega162 ATmega16A ATmega16 ATmega32A ATmega32 ATmega64A ATmega64 ATmega8515 ATmega8535 ATmega8A ATmega8 Das ist jetzt nur auf ATmegas bezogen, Tinys, Xmegas (sind aber einfacher) oder ganz alte AVRs habe ich nicht nachgesehen.
Carl D. schrieb: > Wer wirklich wissen will, welcher Aufwand dahinter steckt, solche > "Binär-Biblioteken" zu bauen -> die AVRlibc gibt's komplett mit alle > Build-Scripts als Source. Und ich hatte schon Probleme einfach nur einen Compiler mit dieser libc zu bauen (main/trunk, etc)... Stephan schrieb: > das was mit Hardware zu tun hat muss 'immer' MC bindend programmiert > werden! > Da es MCs gibt die 1 oder mehrere SPIs haben. Auch können einige mit 5 > Bit bis 16 Bit im Datenregister umgehen. Ich würde mich ja in diesem Fall auf die Schnittmenge beschränken. (Und naiv wie ich bin dachte ich die SPI-Hardware ist bei jedem AVR gleich, einschließlich Registeradresse) Stephan schrieb: > Sieh dir mal den Code zu Arduino, die haben es versucht, viele MCs mit > Hilfe einer API zu verbinden, aber es bleibt da viel auf der Strecke. Also DAS (Arduino) kommt bei meinem "Problem" raus? Ein bisschen mehr Benutzerfreundlichkeit und dafür den µC um einen hohen Faktor verlangsamen oder beschneiden? Dann is mir schnelle HW lieber ;) Alex W. schrieb: > Man kann doch einen Präprozessor verwenden! > > ... Wird sowieso viel Präprozessor-magie drin sein. Alleine schon um an die Register vom ATmega324PA immer ne 0 anzuhängen (warum auch immer?). häää schrieb: > ... > Fazit: es ist also wahrscheinlich doch einfacher mit diversen Makros, > Defines etc. die plattformspezifischen Dinge im Quellcode abzuhandeln > und dann jedes mal zu übesetzen. Ja da hast du recht. Hätte ich auch selbst drauf kommen können... @Johann L. Interessanter Beitrag, geht schon mal in die Richtung. Wieder was gelernt. Johann L. schrieb: > Wichtig ist bei diesem Ansatz der Verzicht auf Callbacks. Was meinst du mit Callbacks (Sagt mir in C jetzt nichts)? Möglicherweise nicht zur Compilezeit feststehende Funktionsaufrufe? F. F. schrieb: > Ich glaube anfangs denkt jeder darüber nach, aber dann stellt man fest, > das man seinen oder seine (paar wenige) µC's gefunden hat und da ist es > einfacher den Code möglichst unabhängig zu schreiben, um nur noch die > Deklaration ändern zu müssen (vornehmlich die Pin Zuordnung). Wenn ich wenigstens nicht der einige bin ... ;) Die paar wenigen µCs beschränken sich (bei den megaAVRs) auf 30 Stück, wobei viele kompatibel zueinander sind (nur mehr Speicher). Bisher löse ich das immer so: (für den ADC, siehe Anhang, wobei mir noch nicht gefällt dass im Header-File schon etwas AVR-abhäniges stehen muss, mir wären da nur die Deklarationen lieber, aber wie schon mehrfach erwähnt hat nicht jeder AVR die selbe HW). Jörg W. schrieb: > Beim AVR kommt's drauf an. Wenn man sich die Architektur-Klassen in > der avr-libc bzw. die Multilib-Optionen im AVR-GCC ansieht, bekommt > man ein Gefühl dafür, was man da binär in einen Topf werfen kann und > tatsächlich in einer Bibliothek implementieren könnte. So wie ich das beim Kompilieren der avr-libc gesehen habe sind das aber auch mdst 10 Architekturen (ohne jetzt nachgeschaut zu haben), also immearnoch eine Menge. Die Autoren der libc haben definitiv meinen Respekt! Jörg W. schrieb: > Was dann allerdings noch bliebe ist, dass nicht in jedem AVR der > SPI-Modul auf der gleichen Adresse liegt. Man könnte die Adressen > über das API übergeben, dann verzichtet man jedoch auf die Möglichkeit, > dass der Compiler IN/OUT-Befehle für den Zugriff benutzt, und muss > immer über MMIO gehen. (Bei IN/OUT ist die Registeradresse Bestandteil > des Opcodes und muss daher zur Compilezeit bekannt sein. Bei MMIO > kann man über Zeigerregister die Bindung auf die Laufzeit verschieben.) > ... Naja, eigentlich bin ich ein Verfechter davon, alles was möglich ist zur Compilezeit zu erledigen. Aber dein Beitrag ist auch hilfreich, gerade das mit der multilib wusste ich noch nicht. F. F. schrieb: > Und wenn der TO dann so weit ist, dann ... hat er Arduino. :-) Ich fürchte auch... Ich spiel aber noch ein bisschen damit rum, habe ja außer Zeit nichts zu verlieren (und grad Ferien :P also genug Zeit)
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.