-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: &-operator Problem, constante im Programmspeicher, sizeo

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.05.2006
    Beiträge
    183

    &-operator Problem, constante im Programmspeicher, sizeo

    Anzeige

    Hi,

    ich versuch mich gerade an einem Problem mit der Adressübergabe an einen Pointer im .progmem.data -Bereich.

    folgendes:

    Code:
    #ifndef __ATTR_PROGMEM__
     #define __ATTR_PROGMEM__ __attribute__((__progmem__))
    #endif
    
    #ifndef  PROGMEM
     #define PROGMEM __ATTR_PROGMEM__
    #endif
    
    struct PROGMEM Norm 
    {
        prog_U8 faktor;    
        prog_U8 decimal;
                 
        const prog_S8 sNormUnit[NORM_UNIT_MAXLEN];
        const prog_S8 sNormName[NORM_NAME_MAXLEN];  
    };
    
    /*** ---- Normalization ------------- Faktor Decimal  Unit    Name ------ ***/
    struct Norm PROGMEM Norm_Voltage1 = {      1,      0, {"V"},  {"VOLTAGE 1"} };
    struct Norm PROGMEM Norm_Voltage2 = {      1,      3, {"mV"}, {"VOLTAGE 2"} };
    
    struct PROGMEM Norm* PROGMEM NormArray[NORM_AMOUNT] = { &Norm_Voltage1, 
                                                            &Norm_Voltage2
                                                          };

    gibt bei mir immer folgende Warnung:

    ../para.c:58: warning: initialization discards qualifiers from pointer target type


    Was mach ich falsch? Gibt es einen Ersatzoperanten für & für den .progmem.data -Bereich?

    Danke schon mal im voraus

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Also als erstes einmal sind da ganz schön viele PROGMEMs in deinem Code. Dazu kann ich leider nicht allzuviel sagen, da ich bisher nur mal ein Stringarray in den Flash umgeschichtet habe.

    Ich würde aus dem ganzen Wust ein typedef machen. Dann hast du zum Schluß nur noch so was wie norm_t übrig.

    Die Warnung könnte daher rühren, dass du dem Kompiler den Typecast explizit mitteilen musst. zB

    ...
    typedef struct Norm{
    ...
    } norm_t;

    ...
    norm_t PROGMEM NormVoltage1 = ...
    ...

    ...NormArray[...] = { (norm_t*)&Norm_Voltage1,
    ...

    Ich hoffe, das hilft dir weiter

    sast

    雅思特史特芬
    开发及研究

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.05.2006
    Beiträge
    183
    Danke.

    Jetzt hab ich aber noch ne Frage. Mit dem typedef hab ich so meine Schwirigkeiten.

    Bei deinem Beispiel:

    typedef struct Norm{
    ...
    } norm_t;

    ...
    norm_t PROGMEM NormVoltage1 = ...

    >Heißt das nun das, das norm_t soviel wie struct Norm bedeutet? Funzt auf jedenfall.

    Danke nochmal

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.05.2006
    Beiträge
    183
    Hi,
    ich hab das jetzt ein Wenig anders gelöst und steh vor einem neuen Problem:

    sizeof (NormArray[1]) geht (bzw. Compiler hat nichts dagegen) und müsste mir die größe des Array-elements in Byte geben.

    Jetzt hätte ich gerne die Größe des gesamten Arrays in Byte

    Code:
    #ifndef  PROGMEM
     #define PROGMEM __attribute__((__progmem__))
    
     typedef char PROGMEM prog_S8;
    
     typedef unsigned char PROGMEM prog_U8;
    
    #endif
    
    typedef struct Norm
    {
        prog_U8 factor;    
        prog_U8 decimal;
                 
        const prog_S8 sNormUnit[NORM_UNIT_MAXLEN];
        const prog_S8 sNormName[NORM_NAME_MAXLEN];  
    }norm_t;
    
    norm_t PROGMEM NormArray[] =                                  {
    
           // Faktor Decimal    Unit                 Name   *
            {      1,      0, {  "V"}, {       "VOLTAGE 1"} }, //  0
            {      1,      3, { "mV"}, {       "VOLTAGE 2"} }, //  1
            {      1,      0, {  "A"}, {       "CURRENT 1"} }, //  2
                                                                                       };
    
    unsigned char normAmound;
        normAmound = sizeof (NormArray);
    normAmound = sizeof (NormArray);

    gibt bei mir immer folgenden Fehler:

    ../xxxxxxx.c:523: error: invalid application of `sizeof' to incomplete type `({anonymous})'

    Warum ist der type hier anonymous?
    Ich dachte erst das liegt an dem PROGMEM aber es geht auch ohne nicht.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Also bei mir "E:\WinAVR-20090306rc1\utils\bin\make.exe" all
    tuts compilieren ohne warnings und errors

    .c Ausschnitt
    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <avr/pgmspace.h>
    
    #include "main.h"
    
    void initio(void);
    void delay_ms(unsigned int ms);
    	
    	norm_t NormArray[] PROGMEM = 
    	{	// Faktor Decimal Unit Name
    		{1, 0, {  "V"}, {"VOLTAGE 1"}}, //  0
    		{1, 3, { "mV"}, {"VOLTAGE 2"}}, //  1
    		{1, 0, {  "A"}, {"CURRENT 1"}}, //  2
    	};
    
    int main( void )
    {
    	int i;
    
    	unsigned char normAmound;
    	
    	normAmound = sizeof (NormArray); 
    	
    	initio();
    ...
    und die .h
    Code:
    ...
    #define NORM_UNIT_MAXLEN 4
    #define NORM_NAME_MAXLEN 12
    
    
    	
    	typedef char PROGMEM prog_S8;
    
    	typedef unsigned char PROGMEM prog_U8;
    
    typedef struct Norm
    {
        prog_U8 factor;   
        prog_U8 decimal;
                 
        const prog_S8 sNormUnit[NORM_UNIT_MAXLEN];
        const prog_S8 sNormName[NORM_NAME_MAXLEN]; 
    }norm_t;
    Um das normAmound vom ersten Post zu bekommen, müsstest du aber dein sizeof(NormArray) noch durch die Größe des Structs teilen

    normAmount = sizeof(NormArray)/sizeof(norm_t);

    sast

    Edit:

    Nur mal so als Hinweis. Jörg Wunsch hat mal in einem anderen Forum zu PROGMEM geschrieben:
    "It's not required to be global variables, but they ought to
    be variables with static storage duration. All global
    variables do have that, but it can also be applied to local ones."

    雅思特史特芬
    开发及研究

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.05.2006
    Beiträge
    183
    Hi,

    tausend Dank. =D>

    Das geht schon mal.

    Aber ich weiß auch warum es nicht ging. Ich weiß nicht wie man eine Array in einem anderen c-File bekannt macht.

    das h-File
    Code:
    #ifndef __ATTR_PROGMEM__
     #define __ATTR_PROGMEM__ __attribute__((__progmem__))
    #endif
    
    #ifndef  PROGMEM
     #define PROGMEM __ATTR_PROGMEM__
    #endif
    
    typedef struct PROGMEM Norm
    {
        prog_U8 faktor;   
        prog_U8 decimal;
                 
        const prog_S8 sNormUnit[NORM_UNIT_MAXLEN];
        const prog_S8 sNormName[NORM_NAME_MAXLEN]; 
    }norm_t;
    das 1. c-File
    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <avr/pgmspace.h> 
    include h-file
    /*** ---- Normalization ------------- Faktor Decimal  Unit    Name ------ ***/
    norm_t Norm_Voltage1 = {      1,      0, {"V"},  {"VOLTAGE 1"} };
    norm_t Norm_Voltage2 = {      1,      3, {"mV"}, {"VOLTAGE 2"} };
    
    norm_t* PROGMEM NormArray[] = 
    { (norm_t*)&Norm_Voltage1, (norm_t*)&Norm_Voltage2 };
    das 2. c-File
    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <avr/pgmspace.h> 
    include h-file
    extern norm_t* PROGMEM NormArray[];
    
    void foo(void)
    {
    U8 normAmound = sizeof(NormArray);
    ...
    ...
    }
    ich hab schon so ziemlich alle varianten versucht:
    norm_t* PROGMEM NormArray[];
    extern norm_t* PROGMEM NormArray;
    extern norm_t* NormArray[];

    leider ist probieren nicht immer von Erfolg gekröhnt.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Die Variante im Code Teil sieht doch ganz gut aus, was gibt es denn für eine Fehlermeldung?

    Versuch doch mal wieder den obligatorischen typecast in der sizeof Funktion.

    sizeof((norm_t **)NormArray);

    sast

    雅思特史特芬
    开发及研究

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.05.2006
    Beiträge
    183
    Hi,

    zum Glück gibt es Menschen die mich an ihrem Wissen teilhaben lassen.
    Danke jetzt meckert der Compiler nicht mehr und die Funktion teste ich bald und geb ein Feedback.

    mfg
    Christoph

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Schön zu hören, das es jetzt soweit funktioniert.

    Dafür ist das Forum da und außerdem macht helfen auch Spass und man muss sich selbst mal mit Dingen beschäftigen, die man sonst nie selbst gemacht hätte.

    sast

    雅思特史特芬
    开发及研究

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.05.2006
    Beiträge
    183
    Hi,
    das PROGMEM bringt mich noch um, alles was früher mal geklappt hat macht jetzt Schwirigkeiten.

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h> 
    #include "uart.h"  // Peter Fleury
    
    #ifndef __ATTR_PROGMEM__
     #define __ATTR_PROGMEM__ __attribute__((__progmem__))
    #endif
    
    #ifndef  PROGMEM
     #define PROGMEM __ATTR_PROGMEM__
    #endif
    
    S8 sTx[16];
    
    typedef struct PROGMEM Norm
    {
        prog_U8 faktor;   
        prog_U8 decimal;
                 
        const prog_S8 sNormUnit[NORM_UNIT_MAXLEN];
        const prog_S8 sNormName[NORM_NAME_MAXLEN];
    }norm_t; 
    
    /*** ---- Normalization ------------- Faktor Decimal  Unit    Name ------ ***/
    norm_t Norm_Voltage1 = {      1,      0, {"V"},  {"VOLTAGE 1"} };
    norm_t Norm_Voltage2 = {      1,      3, {"mV"}, {"VOLTAGE 2"} };
    
    norm_t* PROGMEM NormArray[] =
    { (norm_t*)&Norm_Voltage1, (norm_t*)&Norm_Voltage2 };
    
    
    void foo(void)
    {
        norm_t* p_norm;
    
         p_norm = (norm_t*) NormArray[0];
    
         uart_puts( (S8*) p_norm->sNormName );   // Da kommt nur mist raus
    
    
       uart_puts( (S8*) ((norm_t*)NormArray[0])->sNormName );  // Da auch
    
    
    
    }
    Offensichtlich habe ich Probleme mit Pointern in den Progmem Bereich.
    Und das nicht nur bei Strings sondern auch Werte kommen falsch raus.

    Code:
    void foo(void)
    {
          uart_puts( itoa( NormArray[i]->factor, sTx, 10) );
    }
    mit den Pointern tu ich mir einfach schwer.
    Weiß hier jemand weiter?

    Oder kennt einer ein Beispiel für Constanten und deren Benutzung im PROGMEM bereich?

    gruß christoph

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •