Forum: Compiler & IDEs Library für alle AVRs erstellen


von N. G. (newgeneration) Benutzerseite


Lesenswert?

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.

von hääää (Gast)


Lesenswert?

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
von N. G. (newgeneration) Benutzerseite


Lesenswert?

d.h. alle heutigen Prozessoren sind binärkompatilbel? Eher nicht

von Karl H. (kbuchegg)


Lesenswert?

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
von N. G. (newgeneration) Benutzerseite


Lesenswert?

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...

von hääää (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
von N. G. (newgeneration) Benutzerseite


Lesenswert?

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 ;)

von Carl D. (jcw2)


Lesenswert?

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
von Stephan (Gast)


Lesenswert?

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.

von Alex W. (a20q90)


Lesenswert?

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.

von häää (Gast)


Lesenswert?

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.
*

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
von F. F. (foldi)


Lesenswert?

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"

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von F. F. (foldi)


Lesenswert?

Und wenn der TO dann so weit ist, dann ... hat er Arduino. :-)

von N. G. (newgeneration) Benutzerseite


Angehängte Dateien:

Lesenswert?

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