AVR Functionpointertabelle im Flash, Function aufrufen

OP #1395602
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren