typedef struct an funktion übergeben

OP #2749224
Lesenswert?

Hallo Allerseits!

Ich arbeite mit dem uVision von Keil und dem STM32F103VDT6.

Ich habe verschiedene Variablen in einem typedef struct angelegt. Diese 
Variablen möchte ich jetzt der gleichen Funktion nacheinander übergeben.
1
typedef struct  {
2
                  tMotorCurrentSample MotI_TableCCW[TRAV_MAXDIST_SAMPLES];
3
                  BOOL                cal_OK;
4
                  int                 MotDistCal_PulsesMax;
5
                  float               MotDistCal_pmm;
6
                  tPIDparameter       PIDpar;
7
                  int                 ShttrueIdx[CNTSHT];
8
                  int                 Nmbr_of_Shttr;
9
                }
10
                tSetup;


1
extern tSetup     Setup;


1
void set_in_Flasht(tSetup data)
2
{
3
  FLASH_Unlock();
4
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR |   FLASH_FLAG_WRPRTERR);
5
  FLASH_ErasePage(flshBseAdr);
6
  FLASH_ProgramWord(flshBseAdr, data);
7
  FLASH_Lock();
8
}


1
set_in_Flash(Setup.Nmbr_of_Shttr);


Fehlermeldung:

tsk_functions.c(1234): error:  #167: argument of type "int" is 
incompatible with parameter of type "tSetup"
compiling flash_functions.c...
flash_functions.c(98): error:  #167: argument of type "tSetup" is 
incompatible with parameter of type "uint32_t"



Was habe ich noch nicht verstanden? Habe von einem Beispiel aus dem 
Forum abgeschaut!


Danke und Gruss!

M.B.
Gast #2749228
Lesenswert?

> set_in_Flash(Setup.Nmbr_of_Shttr);
die function will doch die komplette stuct nicht nur ein teil von ihr.

set_in_Flash(Setup);

das ganze ist aber wenig effizent, weil dabei eine kopie der struct 
angelegt wird. Hier sollte man mit zeigern oder Referenzen arbeiten.
Gast #2749229
Lesenswert?

M. B. schrieb:
> tsk_functions.c(1234): error:  #167: argument of type "int" is
> incompatible with parameter of type "tSetup"

Zeig mal Zeile 1234 und den Prototypen der dort aufgerufenen Funktion.

> compiling flash_functions.c...
> flash_functions.c(98): error:  #167: argument of type "tSetup" is
> incompatible with parameter of type "uint32_t"

Zeig mal Zeile 98 und den Prototypen der dort aufgerufenen Funktion.
Gast #2749269
Lesenswert?

Wenn du die Größe deines Structs ( in int ) weisst, dann kannst du das 
über einen Pointer machen:
1
typedef struct  {
2
                  tMotorCurrentSample MotI_TableCCW[TRAV_MAXDIST_SAMPLES];
3
                  BOOL                cal_OK;
4
                  int                 MotDistCal_PulsesMax;
5
                  float               MotDistCal_pmm;
6
                  tPIDparameter       PIDpar;
7
                  int                 ShttrueIdx[CNTSHT];
8
                  int                 Nmbr_of_Shttr;
9
                }
10
                tSetup;
1
void set_in_Flash(tSetup *setup)
2
{
3
  uint32_t *pData = (uint32_t *)setup;
4
  uint8_t i;
5

6
  FLASH_Unlock();
7
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR |   FLASH_FLAG_WRPRTERR);
8
  FLASH_ErasePage(flshBseAdr);
9

10
  for(i=0; i<GROESSE_STRUCT; i++)
11
    FLASH_ProgramWord(flshBseAdr, pData[i]);
12

13
  FLASH_Lock();
14
}
Gast #2749277
Lesenswert?

void set_in_Flasht(int data)
{
  FLASH_Unlock();
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | 
FLASH_FLAG_WRPRTERR);
  FLASH_ErasePage(flshBseAdr);
  FLASH_ProgramWord(flshBseAdr, data);
  FLASH_Lock();
}

Aufruf:

set_in_Flasht(12345);

Die orginale Funktion will aber einen Strukturpointer von dir wenn sie 
richtig definiert ist:

void set_in_Flasht(tSetup* data)
{
  FLASH_Unlock();
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | 
FLASH_FLAG_WRPRTERR);
  FLASH_ErasePage(flshBseAdr);
  FLASH_ProgramWord(flshBseAdr, data);
  FLASH_Lock();
}


Aufruf: set_in_Flasht(&Setup);
OP #2749294
Lesenswert?

Lösungsansatz:
1
set_in_Flash(Setup);

1
void set_in_Flash(tSetup *Setup)
2
{
3
  
4
  uint32_t *pData = (uint32_t *)Setup;
5
  uint8_t i;
6
  int x = sizeof(tSetup);
7
  FLASH_Unlock();
8
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
9
  FLASH_ErasePage(flshBseAdr);
10
  for(i=0;i<x;i++)
11
  {
12
    FLASH_ProgramWord(flshBseAdr, pData[i]);
13
  }
14
  FLASH_Lock();
15
  
16
}

Fehlermeldung:

tsk_functions.c(1234): error:  #167: argument of type "tSetup" is 
incompatible with parameter of type "tSetup *"
#2749341
Lesenswert?

AVerr schrieb:
>
1
set_in_Flash(&Setup);
>
> und bei int x = sizeof(tSetup);
> fehlt glaube ich noch ein /4, da sizeof die Größe in Bytes zurückgibt
> und du sie in int haben willst.

wenn schon dann

   sizeof(tSetup)/sizeof(int)

und nicht /4


Allerdings frage ich mich, was der ganze Quatsch soll?

Wenn du sowieso die komplette Struktur sichern willst, warum suchst du 
dir dann nicht einen Ersatz für

  FLASH_ProgramWord

der eben nicht nur ein Word sondern einen kompletten Speicherbereich 
sichern kann?
#2749359
Lesenswert?

M. B. schrieb:
> Dies wäre natürlich die beste Lösung! Wusste nicht, dass es das gibt!

Ich weiß auch nicht ob es das in deinem System gibt.
Aber das Header File, aus dem die Funktion FLASH_ProgramWord stammt, die 
weiß es. Wenn es eine derartige Funktion gibt, dann ist sie dort drinnen 
aufgeführt.

Und ja: Auch in Systemheaderfiles darf man mit einem Editor 
hineinschauen. Und nochmals ja: es ist nicht verboten die Doku zu seinem 
Compiler zu lesen. Denn auch dort steht drinnen, welche Funktionen es 
gibt.

Das hier
> Habe von einem Beispiel aus dem Forum abgeschaut!
ist gut um eine Idee zu bekommen. Aber gleich danach steht das Studium 
der Hilfe (erste Anlaufstelle) oder des Headerfiles (zweite 
Anlaufstelle, wenn man mit der Hilfe alleine nicht weiterkommt)
#2749389
Lesenswert?

Da gibts keine, die einen Speicherbereich programmiert. Aber sowas kann
man sich mit den vorhandenen Funktionen auch selber schreiben, solange
sizeof(x) eine gerade Zahl ist.
1
void FLASH_ProgramMemory( uint32_t Address, void* Data, size_t DataSize )
2
{
3
  DataSize /= sizeof( uint16_t );   // Halfword
4

5
  for( size_t i = 0; i < DataSize; i++ )
6
    FLASH_ProgramHalfWord( Address + i * sizeof( uint16_t ),
7
                           ((uint16_t*)pData)[i] );
8
}

1
  FLASH_ProgramMemory( flshBseAdr, &Setup, sizeof( Setup ) );



(uint16_t deswegen, weil ich die 'kleinere' Funktion genommen habe. Ist 
sichergestellt, dass sizeof(Setup) ein Vielfaches von sizeof(uint32_t) 
ist, dann kann man auch auf Word Behandlung ausweichen.
#2749393
Lesenswert?

Peter II schrieb:
> Karl Heinz Buchegger schrieb:
>> wenn schon dann
>>
>>    sizeof(tSetup)/sizeof(int)
>>
>> und nicht /4
>
> sollte es nicht besser
>
> sizeof(tSetup)/sizeof(Word)
>
> sein, denn die funktion heist FLASH_ProgramWord

Ich weiß nicht, ob es einen Datentyp Word gibt. Wenn ja, wäre das die 
bessere Wahl. Aber auch die vorgegebene Program Funktion selber hat 
diese Signatur:

FLASH_Status   FLASH_ProgramWord (uint32_t Address, uint32_t Data)

Also explizit einen uint32_t als 'Word'
OP #2749437
Lesenswert?

>
1
FLASH_ProgramHalfWord( Address + i * sizeof( uint16_t ),
2
                           ((uint16_t*)pData)[i] );

pData wäre Data


entweder ich bin zu blöd um Abzuschreiben oder es hat noch einen 
Fehler!?

Fehlermeldung:

flash_functions.c(97): error:  #254: type name is not allowed
1
for(size_t i = 0; i < DataSize;i++)

flash_functions.c(97): error:  #65: expected a ";"
1
for(size_t i = 0; i < DataSize;i++)

flash_functions.c(97): error:  #20: identifier "i" is undefined
1
for(size_t i = 0; i < DataSize;i++)

hat es mit dem size_t zu tun?
OP #2749489
Lesenswert?

Beschreibung von Keil zu Fehler 254:


    type name is not allowed

    This occurs when a typedef name is being used directly in an 
expression:
1
    typedef int footype;
2

3
    int x = footype; // reports Error: #254: type name is not allowed
    To fix this, first create an instance of that type (for example, a 
variable of the new type):
1
    typedef int footype;
2
    footype bar = 1;
3
    int x = bar;

Das versteh ich jetzt nicht!
#2749608
Lesenswert?

M. B. schrieb:
>
1
> x = sizeof(Setup);
2
>
>
> x = 4


Dann stimmt das aber nicht mit
1
typedef struct  {
2
                  tMotorCurrentSample MotI_TableCCW[TRAV_MAXDIST_SAMPLES];
3
                  BOOL                cal_OK;
4
                  int                 MotDistCal_PulsesMax;
5
                  float               MotDistCal_pmm;
6
                  tPIDparameter       PIDpar;
7
                  int                 ShttrueIdx[CNTSHT];
8
                  int                 Nmbr_of_Shttr;
9
                }
10
                tSetup;
11

12

13
extern tSetup     Setup;

zusammen.
Hier kann Setup unmöglich eine sizeof() von 4 haben.
Hast du da irgendwo noch einen Pointer im Gebälk?
Du musst schon drauf achten:
  Nehme ich jetzt die sizeof von einem Strukturobjekt,
  oder ist das was ich habe ein Pointer auf so ein Objekt?
OP #2749615
Lesenswert?

1
typedef struct  {
2
                  float motspd_max;     // [mm/s] normal full travelling speed
3
                  float motspd_cal_max; // [mm/s] Reference speed value 
4
                  float motspd_inc;     // [mm/s] Speed added when ramping up
5
                  float motspd_dec;     // [mm/s] Speed added when ramping down
6
  
7
                  tMotorCurrentSample MotI_TableCW[TRAV_MAXDIST_SAMPLES];  // = 2100
8
                  tMotorCurrentSample MotI_TableCCW[TRAV_MAXDIST_SAMPLES];
9
                  BOOL                cal_OK;
10
                  int                 MotDistCal_PulsesMax;
11
                  float               MotDistCal_pmm;
12
                  tPIDparameter       PIDpar;
13
                  int                 ShttrueIdx[CNTSHT];
14
                  int                 Nmbr_of_Shttr;
15
                  int                 MotDir;
16
                }
17
                tSetup;

Wurde erweitert! Aber da müsste sizeof(Setup) noch grösser sein?
OP #2749676
Lesenswert?

hmm...

im setup.h file
1
typedef struct  {
2
                  float motspd_max;     // [mm/s] normal full travelling speed
3
                  float motspd_cal_max; // [mm/s] Reference speed value 
4
                  float motspd_inc;     // [mm/s] Speed added when ramping up
5
                  float motspd_dec;     // [mm/s] Speed added when ramping down
6
  
7
                  tMotorCurrentSample MotI_TableCW[TRAV_MAXDIST_SAMPLES];  // = 2100
8
                  tMotorCurrentSample MotI_TableCCW[TRAV_MAXDIST_SAMPLES];
9
                  BOOL                cal_OK;
10
                  int                 MotDistCal_PulsesMax;
11
                  float               MotDistCal_pmm;
12
                  tPIDparameter       PIDpar;
13
                  int                 ShttrueIdx[CNTSHT];
14
                  int                 Nmbr_of_Shttr;
15
                  int                 MotDir;
16
                }
17
                tSetup;
18

19
//**************
20
extern tSetup     Setup;

im setup.c
1
tSetup  Setup;


im flash.h
1
extern void set_in_Flash(tSetup *setup);
2
extern void FLASH_ProgramMemory(uint32_t Address, void* Data, size_t DataSize);



im flash.c file
1
void FLASH_ProgramMemory(uint32_t Address, void* Data, size_t DataSize)
2
{
3
  size_t i;
4
  DataSize /= sizeof(uint16_t);
5
  
6
  for(i = 0; i < DataSize;i++)
7
  {
8
    FLASH_ProgramHalfWord(Address + i * sizeof(uint16_t), ((uint16_t*) Data)[i]);
9
  }
10

11
}
12

13

14

15
void set_in_Flash(tSetup *Setup)
16
{
17
  FLASH_Unlock();
18
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
19
  FLASH_ErasePage(flshBseAdr);
20
  FLASH_ProgramMemory(flshBseAdr, &Setup, sizeof(Setup));
21
  FLASH_Lock();
22
}


Funktionsaufruf in func.c file
1
set_in_Flash(&Setup);
Gast #2749720
Lesenswert?

Also, erstmal eine Fehlerquelle nebenbei:
Du hast eine globale Variable namens Setup, die per extern auch an 
flash.c/.h weitergegeben wird.
Die Funktion set_in_Flash hat auch einen Parameter namens Setup.
Das ist zwar für den Compiler kein Problem, aber birgt für den Leser 
eine Fehlerquelle, die man vermeiden könnte, indem du z.B. in 
set_in_Flash das setup klein schreibst.

Und dann fällt auch auf, warum bei
1
void set_in_Flash(tSetup *Setup)
2
{
3
  FLASH_Unlock();
4
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
5
  FLASH_ErasePage(flshBseAdr);
6
  FLASH_ProgramMemory(flshBseAdr, &Setup, sizeof(Setup));
7
  FLASH_Lock();
8
}
als Größe von Setup 4 rauskommt ... es ist die Größe eines Pointers und 
nicht vom struct.

Besser wäre:
1
void set_in_Flash(tSetup *setup)
2
{
3
  FLASH_Unlock();
4
  FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
5
  FLASH_ErasePage(flshBseAdr);
6
  FLASH_ProgramMemory(flshBseAdr, &Setup, sizeof(*setup));
7
  FLASH_Lock();
8
}
#2749928
Lesenswert?

M. B. schrieb:
> x = 8476
Scheint zu stimmen, weil:
4Byte  float motspd_max;     // [mm/s] normal full travelling speed
4Byte  float motspd_cal_max; // [mm/s] Reference speed value
4Byte  float motspd_inc;     // [mm/s] Speed added when ramping up
4Byte  float motspd_dec;     // [mm/s] Speed added when ramping down

...2100 Elemente vom Typ tMotorCurrentSample sind wohl
4200Bytes MotI_TableCW[TRAV_MAXDIST_SAMPLES];  // = 2100
4200Bytes MotI_TableCCW[TRAV_MAXDIST_SAMPLES];
1Byte BOOL                cal_OK;
4Byte int                 MotDistCal_PulsesMax;
4Byte float               MotDistCal_pmm;
wieviele auch immer tPIDparameter       PIDpar;
4Byte int                 ShttrueIdx[CNTSHT];
4Byte int                 Nmbr_of_Shttr;
4Byte int                 MotDir;
========
8437+Größe von tPIDparameter

Ziemlich dicker Struct.

tschuessle
Bernhard
OP #2750369
Lesenswert?

Morgen!
1
typedef struct  {
2
                  float   iMin; // Minimum allowable integrator state
3
                  float   iMax; // Maximum allowable integrator state
4
                  float   iGain;// integral gain
5
                  float   pGain;// proportional gain
6
                  float   dGain;// derivative gain
7
                }
8
        tPIDparameter;


1
typedef uint16_t tMotorCurrentSample ;

...2100 Elemente vom Typ tMotorCurrentSample sind wohl

4200Bytes MotI_TableCW[TRAV_MAXDIST_SAMPLES];  // = 2100
4200Bytes MotI_TableCCW[TRAV_MAXDIST_SAMPLES];

1Byte BOOL                cal_OK;
4Byte int                 ShttrueIdx[CNTSHT];
4Byte int                 Nmbr_of_Shttr;
4Byte int                 MotDir;


So habe es auf das Minimum eingegrenzt, vorerst!


Kann ich die " Tabellen MotI_TableCW[TRAV_MAXDIST_SAMPLES]", die ja 
4,2kB gross sind auf 3 Pages verteilen?

Danke und Gruss!

M.B.
OP #2750412
Lesenswert?

@ Karl Heinz Buchegger

Die Funktion
1
void FLASH_ProgramMemory( uint32_t Address, void* Data, size_t DataSize )

speichert in eine Page mit der Startadresse "Address", was passiert, 
wenn ich eine 4,2kB grosse Variable so speichere? Die würde ja 3 Pages 
benötigen?

Ich gebe ja die Adresse der letzten Page an!

danke und Gruss!
Gast #2750565
Lesenswert?

M. B. schrieb:
> was passiert,
> wenn ich eine 4,2kB grosse Variable so speichere?

Er speichert um genau zu sein ab der Adresse, die du ihm übergibst.
D.h. wenn du bei der drittletzten Page anfängst, wird das auch auf die 
letzten 3 pages verteilt.
Aber dafür musst du die Funktion noch so anpassen, dass sie auch die 
letzten 3 pages löscht und nicht nur eine.

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