C > struct > flex Array

OP #6937346
Lesenswert?

Nabend Community,

ich habe ein Array dessen Größe zur Kompilierung schon fest steht.
Ist es möglich das dem Kompiler mitzuteilen? Aktuell schmeißt er 
berechtigte Fehler "initialization of flexible array member in a nested 
context".

Es geht um "*pTim[]"
1
typedef struct
2
{
3
  TIMER_IRQ_t   IRQn;
4
  uint8_t      uiBitReg;
5
  uint8_t     uiSizeOfTims;
6
  TIM_TypeDef    *pTim[];
7
} TIMER_Irq_Cfg_t;
8

9
TIMER_Irq_Cfg_t sTimIRQnCfg[] =
10
{
11
    { TIMER_UPDATE_IRQ,        TIM_DIER_UIE,     7,{ TIM1, TIM3, TIM6, TIM14, TIM15, TIM16, TIM17   }},
12
    { TIMER_CAPTURE_COMPARE_1_IRQ,    TIM_DIER_CC1IE,  6,{ TIM1, TIM3, TIM14, TIM15, TIM16, TIM17       }},
13
    { TIMER_CAPTURE_COMPARE_2_IRQ,   TIM_DIER_CC2IE,  3,{ TIM1, TIM3, TIM15                 }},
14
    { TIMER_CAPTURE_COMPARE_3_IRQ,   TIM_DIER_CC3IE,  2,{ TIM1, TIM3                     }},
15
    { TIMER_CAPTURE_COMPARE_4_IRQ,   TIM_DIER_CC4IE,  2,{ TIM1, TIM3                     }},
16
    { TIMER_COM_IRQ,         TIM_DIER_COMIE,  4,{ TIM1, TIM15, TIM16, TIM17             }},
17
    { TIMER_TRIGGER_IRQ,       TIM_DIER_TIE,    3,{ TIM1, TIM3, TIM15                 }},
18
    { TIMER_BREAK_IRQ,         TIM_DIER_BIE,    4,{ TIM1, TIM15, TIM16, TIM17             }},
19
};
Gast #6937373
Lesenswert?

Das geht so nicht, weil jeder Eintrag des äußeren Arrays (sTimIRQnCfg) 
gleich groß sein muss; daher können die einzelnen 
TIMER_Irq_Cfg_t-Instanzen nicht unterschiedlich lange Arrays beinhalten.
Du musst jedes der Timer-Arrays als separate Variable anlegen und 
Pointer darauf verwenden. Eventuell lässt sich mit Makros & Statement 
Expressions (nur GCC) oder in C++ mit Lambdas etwas frickeln um das 
abzukürzen.
#6937379
Lesenswert?

Hallo,

da alles gleich groß sein muss, könnte man es mit Platzhalter auffüllen. 
Meistens mit 0 oder dem größten Wert des Wertebereiches. Hier mit 
Zeigern in C würde ich es mit NULL auffüllen. Sollte doch gehen?

Ich weiß nicht ob das in C im struct auch geht, Größe einfach festlegen.
1
TIM_TypeDef *pTim[7];
Gast #6937397
Lesenswert?

Sollte mit zusätzlichen statischen Variablen klappen.
1
typedef struct
2
{
3
  TIM_TypeDef    *pTim;
4
} TIMER_Irq_Cfg_t;
5

6
TIM_TypeDef tmp1[] = {...}
7
TIM_TypeDef tmp2[] = {...}
8
...
9

10
TIMER_Irq_Cfg_t sTimIRQnCfg[] =
11
{
12
    { TIMER_UPDATE_IRQ,        TIM_DIER_UIE,     7, tmp1},
13
},
OP #6937461
Lesenswert?

Veit D. schrieb:
> Hallo,
>
> da alles gleich groß sein muss, könnte man es mit Platzhalter auffüllen.
> Meistens mit 0 oder dem größten Wert des Wertebereiches. Hier mit
> Zeigern in C würde ich es mit NULL auffüllen. Sollte doch gehen?
>
> Ich weiß nicht ob das in C im struct auch geht, Größe einfach
> festlegen.TIM_TypeDef *pTim[7];

Ja das funktioniert. Nur werden da viele nützliche Bytes verschwendet, 
die an anderer Stelle mal fehlen könnten.
Gast #6937550
Lesenswert?

> Nur werden da viele nützliche Bytes verschwendet,

Bei meinem Vorschlag auch. Für *pTim baut der Compiler einen 
zusätzlichen Pointer in die Struct ein. Eventuell brauchen die Pointer 
mehr Bytes als das pTim[7]. Und möglicherweise erzeugt der Compiler für 
den Zugriff über einen zusätzlichen Pointer auch noch zusätzlichen 
Maschinencode.
#6937697
Lesenswert?

Hallo,

bau einmal serielle Debugausgaben ein. Zum Bsp. für Irq und 
sTimIRQnCfg[i].IRQn um den Vergleich zu überprüfen ob der überhaupt 
gültig werden kann. Ich vermute ein Problem mit der Zeiger 
Dereferenzierung bzw. fehlender dieser, weil die TIMs sind doch 
Registeradressen? Nicht das es eine Verwechslung mit Adresse und 
Addressinhalt gibt. Kann auch die Parameterübergabe sein ... . Wie man 
es macht wird es verschiedene Möglichkeiten geben, es muss nur 
einheitlich sein. Soviel zu meiner Vermutung.
OP #6937880
Lesenswert?

Veit D. schrieb:
> Hallo,
>
> bau einmal serielle Debugausgaben ein. Zum Bsp. für Irq und
> sTimIRQnCfg[i].IRQn um den Vergleich zu überprüfen ob der überhaupt
> gültig werden kann. Ich vermute ein Problem mit der Zeiger
> Dereferenzierung bzw. fehlender dieser, weil die TIMs sind doch
> Registeradressen? Nicht das es eine Verwechslung mit Adresse und
> Addressinhalt gibt. Kann auch die Parameterübergabe sein ... . Wie man
> es macht wird es verschiedene Möglichkeiten geben, es muss nur
> einheitlich sein. Soviel zu meiner Vermutung.

Das habe ich schon gemacht mit dem CubeIDE Debugger.
Wenn ich das richtig interpretiere greift er auf die Listen[0..7] aber 
auf deren Inhalte nicht. Anbei mal ein Foto.
Angehängte Dateien:
Gast #6937887
Lesenswert?

Ehm, dass du bei "( TIM_TypeDef* )TimList7" casten musst ist doch sehr 
verdächtig - da ist was faul!

Wenn du es genau wie in

Noch ein Kommentar schrieb:
> Sollte mit zusätzlichen statischen Variablen klappen.

geschrieben machst, brauchst du keinen Cast. Bei "if ( pTim == 
sTimIRQnCfg[Index].pTim + IndexTimList )" brauchst du auch keinen.

Insbesondere musst du pTim als gewöhnlichen Pointer definieren:
1
typedef struct
2
{
3
  TIM_TypeDef    *pTim;
4
} TIMER_Irq_Cfg_t;
OP #6937891
Lesenswert?

Programmierer schrieb:
> Ehm, dass du bei "( TIM_TypeDef* )TimList7" casten musst ist doch
> sehr
> verdächtig - da ist was faul!
>
> Wenn du es genau wie in
>
> Noch ein Kommentar schrieb:
>> Sollte mit zusätzlichen statischen Variablen klappen.
>
> geschrieben machst, brauchst du keinen Cast. Bei "if ( pTim ==
> sTimIRQnCfg[Index].pTim + IndexTimList )" brauchst du auch keinen.
>
> Insbesondere musst du pTim als gewöhnlichen Pointer definieren:typedef
> struct
> {
>   TIM_TypeDef    *pTim;
> } TIMER_Irq_Cfg_t;

Habe ich ja gemacht. Wenn ich das so mache..

https://pastebin.com/VX86fb5n

Wirft er mir: "(near initialization for 'sTimIRQnCfg[1].pTim')"
Gast #6937897
Lesenswert?

Ach jetzt hab ich mich selber durcheinander gebracht, die Tiger sind ja 
Pointer... Versuch es mit "struct { TIM_TypeDef **pTim; }". Casts 
sollten da jedenfalls nirgendwo sein.

Jan H. schrieb:
> (near initialization for 'sTimIRQnCfg[1].pTim')"

Das ist übrigens nur ein kleiner Fetzen der eigentlich Fehlermeldung.
OP #6937902
Lesenswert?

Programmierer schrieb:
> Ach jetzt hab ich mich selber durcheinander gebracht, die Tiger
> sind ja
> Pointer... Versuch es mit "struct { TIM_TypeDef **pTim; }". Casts
> sollten da jedenfalls nirgendwo sein.
>
> Jan H. schrieb:
>> (near initialization for 'sTimIRQnCfg[1].pTim')"
>
> Das ist übrigens nur ein kleiner Fetzen der eigentlich Fehlermeldung.

Du hast Recht. Es muss ja ein "Zeiger auf den Zeiger sein".
Danke! Funzt.
Gast #6937907
Lesenswert?

Jan H. schrieb:
>>
>
> Du hast Recht. Es muss ja ein "Zeiger auf den Zeiger sein", war doch so
> oder?

Ja genau.

Jan H. schrieb:
> Wie wird dieser gleich noch referenziert?

Der äußere Zeiger muss in der schleife dereferenziert werden. Mir fällt 
gerade auf dass die auch angepasst werden muss. Bin noch nicht ganz wach 
🤦‍♂️:
1
if ( pTim ==  sTimIRQnCfg[Index].pTim[ IndexTimList])

Der innere Zeiger wird überhaupt nicht dereferenziert, nur verglichen.
OP #6937913
Lesenswert?

Programmierer schrieb:
> Jan H. schrieb:
>>>
>>
>> Du hast Recht. Es muss ja ein "Zeiger auf den Zeiger sein", war doch so
>> oder?
>
> Ja genau.
>
> Jan H. schrieb:
>> Wie wird dieser gleich noch referenziert?
>
> Der äußere Zeiger muss in der schleife dereferenziert werden. Mir fällt
> gerade auf dass die auch angepasst werden muss. Bin noch nicht ganz wach
> 🤦‍♂️:
> if ( pTim ==  sTimIRQnCfg[Index].pTim[ IndexTimList])
>
> Der innere Zeiger wird überhaupt nicht dereferenziert, nur verglichen.

Alles gut ist ja auch Montag :D
Ich habe ihn schon dereferenziert ;).

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