wskaźnik do struktury we flashu

0

Słuchajcie mam pewien problem z poprawną deklaracją.
Mam mianowicie utworzoną strukturę w pamięci programu flash i potrzebuję zdefiniować wskaźnik na pierwszy element tejże struktury.
Wyskakuje mi warning, chciałbym go uniknąć. Piszę na AVR'y pod Eclipsem. Listing:

#include <stdint.h>
 #include <avr/pgmspace.h>

typedef struct data_s
{
    uint16_t step;
    uint8_t led_number;
    int8_t pwm_growth;
} data_t;

data_t data[] PROGMEM = { {1,1,1}, (2,2,2} };

typedef data_t prog_data PROGMEM;

#define PGM_DATA_P const prog_data *

PGM_DATA_P data_ptr;

Program się kompiluje. Warning który dostaję to:
warning: ignoring attributes applied to 'struct data_s' after definition

Dodam tylko że brak jest warningów przy standardowej bibliotecznej konstrukcji wskaźnika na bajt we flashu. Bo jest to tak:

uint8_t x PROGMEM;
 typedef char prog_char PROGMEM;
#define PGM_P const prog_char *
PGM_P ptr = &x;

Ja mam podobnie tylko ze strukturą co już daje warning. Wie ktoś jak się go pozbyć ?

1

Z dokumentacji znalezionej w sieci:

This typedef is now deprecated because the usage of the _​_progmem​_​_ attribute on a type is not supported in GCC. However, the use of the _​_progmem_​_ attribute on a variable declaration is supported, and this is now the recommended usage.

Inaczej mówiąc, PROGMEM chyba powinieneś używać do definicji zmiennych, a nie typedefów.

0

Gdybym zrobił tak jak mówisz to kompilator założyłby że ten wskaźnik istotnie pokazuje na tą strukturę ale w ramie. Inaczej, wskaźnik byłby wówczas wskaźnikiem do ramu a nie do flasha.
Zresztą mówię, podobnie jest w przykładzie bibliotecznym w którym jest:

 typedef char prog_char PROGMEM;

, i tutaj jakoś warning nie wyskakuje...

Problem zatem sprowadza się do deklaracji wskaźnika na strukturę umieszczoną we flashu. Kto wie coś na ten temat ?
Oczywiście sam wskaźnik musi być w ramie bo będzie modyfikowany stosując tzw. arytmetykę wskaźników.

1

Skasuj data_s po typedef struct.

Edit:
Poza tym masz syntax error w linijce z wypełnianiem tablicy struktur ("(" zamiast "{").

Edit2:
Moim zdaniem przekombinowałeś. Używasz jakiejś zwariowanej i nikomu niepotrzebnej deklaracji typu tylko po to, żeby użyć go później do deklaracji wskaźnika, który powinien tylko wskazywać poprawnie na tablicę data. Daruj sobie te sztuczki składniowe i zostaw to tak:

#include <stdint.h>
#include <avr/pgmspace.h>
 
typedef struct
{
    uint16_t step;
    uint8_t led_number;
    int8_t pwm_growth;
} data_t;
 
data_t data[] PROGMEM = { {1,1,1}, (2,2,2} };
data_t *data_ptr = &data;

Możesz sobie potem uzywać data_ptr i normalnej arytmetyki wskaźników, bo przecież to wszystko będzie w RAMie.

0

Tablice inicjalizujemy używając klamer a nie nawiasów okrągłych, do inicjalizacji struktur to może okrągłych tego nie wiem ale na pewno nie tablic.
Po drugie: nic nie daje że skasuję data_s ponieważ warning jest ten sam tylko zamiast "data_s" pokazuje się w nim "anonymous..."
Po trzecie jak zrobię tak jak piszesz czyli tak: data_t *data_ptr = &data;
to jaką mam pewność że obiekt data_t będzie w ramie czy we flashu ? Inaczej : czy wg Ciebie nie ma różnicy w deklaracji wskaźnika pokazującego na strukturę osadzoną w ramie i we flashu ? Przecież może być tak:
data_t data1 = ...
albo też tak: data_t data1 PROGMEM = ...
...
Potem wyłuskując (deref.) spod tego wskaźnika w zależności od tego na co on pokazuje robi się tak :

*data_ptr

dla przypadku gdy struktura w ramie
albo tak:

pgm_read_byte(data_ptr)

gdy struktura we flashu

Tylko w tym drugim przypadku jak dostać się za pomocą tego wskazania do wybranego pola tej struktury ?

0

OK, mam rozwiązanie.
Kolega podpowiedział i wszystko gra.

W takich momentach wskaźnik definiujemy normalnie, tylko że odczyt spod jego wskazania musimy przeprowadzić funkcjami pgm_read_byte...
Aby dostać się do wybranego pola struktury na którą ten wskaźnik pokazuje należy zrobić po prostu tak:

  pgm_read_byte( &data_ptr->pole_struktury );

Temat zamykam. Dzięki za zainteresowanie!

PS. Niech mi ktoś na szybko tylko powie jak się tutaj "zamyka temat" ???

1 użytkowników online, w tym zalogowanych: 0, gości: 1