AVR Functionpointertabelle im Flash, Function aufrufen

OP #1395602
Hab etwa folgenden Code:
1
#define MEM_ROM_LOC(v)       v PROGMEM
2

3
typedef void (* funcPtr_t)(void);
4

5

6

7
static funcPtr_t MEM_ROM_LOC(s0_ts0[]) =
8
{
9
   f1,
10
   f2,
11
   NULL
12
};
13
...
14

15
static funcPtr_t MEM_ROM_LOC(s1_ts0[]) =
16
{
17
   f1,
18
   f2,
19
   NULL
20
};
21
...
22

23
static funcPtr_t MEM_ROM_LOC(*funcList[ABC][DEF]) =
24
{
25
  {
26
      (funcPtr_t *) s0_ts0
27
     ,(funcPtr_t *) s0_ts1
28
  },
29

30
  {
31
      (funcPtr_t *) s1_ts0
32
     ,(funcPtr_t *) s1_ts1
33
  }
34
}

Jetzt möchte ich alle Funktionen der funcList ausführen:
1
...
2
funcPtr_t *tsLocalFuncList;
3
tsLocalFuncList = rtosFuncList[i][j];
4

5

6
for(a = RESET; tsFuncList[a] != NULL; a++)
7
{
8
   /* execute current function */
9
   (tsLocalFuncList[a])();
10
}

Ich weiß dass man mittels pgm_read_byte() den ROM lesen kann, aber wie 
macht man das um an eine Funktionsadresse zu kommen?
OP #1395658
Danke für die Antwort,

es geht mir aber um die Zeile
1
tsLocalFuncList = funcList[i][j];

Ich habe folgendes gemacht
1
tsLocalFuncList = (funcPtr_t) pgm_read_word(&funcList[i][j]);



und bekomme die Warning:
1
warning: assignment from incompatible pointer type

Das Programm läuft auch leider nicht. Als ich die Tabellen im RAM hatte 
war alles i.O.
#1395667
So, wie du dir das vorstellst, geht das nicht. Du musst jeden einzelnen 
Funktionszeiger aus dem Flash lesen. Und das gilt im übrigen nicht nur 
für den eigentlichen Aufruf der Funktion, sondern natürlich auch für den 
Test des Pointers gegen Null in der for-Bedingung. Die von Jörg 
vorgeschlagene Zwischenvariable ist damit natürlich umso sinnvoller. ;-)
OP #1395675
Du hast absolut recht. Damit wird das ganze aber zu aufgebläht. In dem 
Fall lasse ich die Tabellen im RAM, außer Ihr kennt eine andere 
Alternative um das Problem zu lösen? Ich bin leider noch AVR Neuling, 
komme vom R8C (da machst du ein const und das Ding ist im ROM. Der 
Zugriff ist ebenso einfach)
#1395686
Bronko Pavel schrieb:
> Du hast absolut recht. Damit wird das ganze aber zu aufgebläht.

Glaub ich zwar nicht, aber was willst du eigentlich wirklich machen?

Das du hier Casts brauchst
1
static funcPtr_t MEM_ROM_LOC(*funcList[ABC][DEF]) =
2
{
3
  {
4
      (funcPtr_t *) s0_ts0
5
     ,(funcPtr_t *) s0_ts1
6
  },
macht mich stutzig, da sollte eigentlich keiner notwendig sein.
Auch deine Einführung des Makros MEM_ROM_LOC macht die Sache nicht 
unbedingt übersichtlicher.

Also: Was soll das Ganze eigentlich werden?
Moderator Persönliche Seite #1395983
Bronko Pavel schrieb:
> Du hast absolut recht. Damit wird das ganze aber zu aufgebläht.

Der Maschinencode dafür ist so oder so notwendig, der Unterschied
zwischen Flash-ROM und RAM ist nur, ob dort LDS- oder LPM-Befehle
an den entsprechenden Stellen stehen, wobei die LPM-Befehle im
Vergleich zu LDS jeweils einen Takt mehr brauchen.  Der Rest des
Codes (Zurechtlegen der notwendigen Adressregister) wird so oder
so benötigt, ist halt nur die Frage, dass man das beim AVR-GCC
und Flash-ROM-Zugriff nicht so schön einfach hinter zwei Paar
eckigen Klammern verstecken kann.
OP #1396822
Karl heinz Buchegger schrieb:
> Bronko Pavel schrieb:
>> Du hast absolut recht. Damit wird das ganze aber zu aufgebläht.
>
> Glaub ich zwar nicht, aber was willst du eigentlich wirklich machen?
>
> Das du hier Casts brauchst
>
1
> static funcPtr_t MEM_ROM_LOC(*funcList[ABC][DEF]) =
2
> {
3
>   {
4
>       (funcPtr_t *) s0_ts0
5
>      ,(funcPtr_t *) s0_ts1
6
>   },
7
>
> macht mich stutzig, da sollte eigentlich keiner notwendig sein.
> Auch deine Einführung des Makros MEM_ROM_LOC macht die Sache nicht
> unbedingt übersichtlicher.
>
> Also: Was soll das Ganze eigentlich werden?


Ja das ist mein kleines zeitscheibenbasierte "Betriebssystem". Du kannst 
dir das so vorstellen: Jede Zeitscheibe hat bis zu 10 Tasks 
(Funktionen). Jeder "State" Besteht aus bis zu 4 Zeitscheiben und dann 
gibt es noch 4 States. Das ganze ist über Präprozessorlogik so 
zusammengesetz, das nur Speicher für die tatsächliche Anzahl von 
Tasks/Timeslices/States kompiliert wird. Natürlich sind 
Tasks/Timeslices/States in Ihrer Anzahl variabel, aber o. g. Werte haben 
sich bewährt. Das ganze kommt bei mittelgroßen Projekten zum Einsatz. Da 
ich den AVR kennenlernen will habe ich damit angefangen es zu portieren 
und am Ende HW unabhängig zu machen, deshalb z.B. MEM_ROM_LOC() Macro 
usw.. Wenn du sagst das Performance "unnötigerweise" verloren geht, dann 
nehm ich halt einen größeren/schnelleren uC (ob ich 3€ oder 5€ zahl ist 
daheim Wurst)

... werd versuchen das nach Jörgs Aussage doch ins Flash zu packen...

Gruß
Bronko
OP #1396862
ich pack es irgendwie doch nicht.
1
tsLocalFuncList = (funcPtr_t) pgm_read_word(&funcList[i][j]);
führt zu
1
warning: assignment from incompatible pointer type


Wie mache ich es in der for-Schleife um an die nächste Funktion zu 
kommen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.