tmf napisał: Tu jest jeszcze problem pobierania adresu czegos umieszczonego powyzej granicy 64kB. Nie da sie tego zrobic za pomoca operatora "&", musisz skorzystac z biblioteki Carlosa Lamasa, w ktorej jest definicja GET_FAR_ADDRESS sluzacego do tego celu.
Dlaczego nie można tego zrobić za pomocą operatora &? Jak w takim razie mam tę tablicę umieścić, bo przecież część danych będzie we flashu poniżej 64kB, a część powyżej. Czy mogę tę bibliotekę zastosować do zarówno krótkich jak i długich adresów(tzn powyżej 64kB)?
Dodano po 41 [minuty]: Witam. Zamieniłem odczyt w kodzie z
byte = pgm_read_byte_far(&(tab1[i]));
na
byte = pgm_read_byte_far(0x10000UL + (uint32_t) (uint16_t) (tab1[i]));
W sumie wygląda to tak:
for(j=0;j<24413;j++)
{
//byte = pgm_read_byte_far(&(tab1[i]));
byte = pgm_read_byte_far(0x10000UL + (uint32_t) (uint16_t) (tab1[i]));
SPI_MasterTransmit(byte);
}
for(j=0;j<24413;j++)
{
//byte = pgm_read_byte_far(&(tab2[i]));
byte = pgm_read_byte_far(0x10000UL + (uint32_t) (uint16_t) (tab2[i]));
SPI_MasterTransmit(byte);
}
for(j=0;j<24413;j++)
{
//byte = pgm_read_byte_far(&(tab3[i]));
byte = pgm_read_byte_far(0x10000UL + (uint32_t) (uint16_t) (tab3[i]));
SPI_MasterTransmit(byte);
}
for(j=0;j<24413;j++)
{
//byte = pgm_read_byte_far(&(tab4[i]));
byte = pgm_read_byte_far(0x10000UL + (uint32_t) (uint16_t) (tab4[i]));
SPI_MasterTransmit(byte);
}
W przypadku zastosowania
#define GET_FAR_ADDRESS(var) \
({ \
uint32_t tmp; \
\
__asm__ __volatile__( \
\
"ldi %A0, lo8(%1)" "\n\t" \
"ldi %B0, hi8(%1)" "\n\t" \
"ldi %C0, hh8(%1)" "\n\t" \
"clr %D0" "\n\t" \
: \
"=d" (tmp) \
: \
"p" (&(var)) \
); \
tmp; \
.
.jakis kod
.
uint32_t adres = 0;
.
.jakis kod
.
adres = GET_FAR_ADDRESS(tab1[i]);
})
wyrzuca mi błąd :
C:\Documents and Settings\Piotrek\Moje dokumenty\loader\default/../main.c:97: undefined reference to `r28'
Nie znam assemblera na avrki(zaczynam tego powoli żałować) i nie wiem co ten błąd oznacza. Może ktoś wie?
Mam jeszcze jedno pytanie. Ponieważ adres powyzej 64kB jest 24 bitowy? to odczytuje ten powyzszy kod assemblerowy odczytuje najpierw mlodsze 8 bitow potem starsze 8 bitow a potem jeszcze jakis 8 bitow i to jest adres? Czy moge uzyc tego
byte = pgm_read_byte_far(0x10000UL + (uint32_t) (uint16_t) (tab1[i]));
lub tego GET_FAR_ADRESS do całej pamieci flash czy tylko powyzej 64kB? Domyslam sie, ze nie za bardzo wiec moze ktos wie jak wrzucic cala tablice pod adres we flashu powyzej 64kB?