Stránka 2 z 2

Napsal: 05 čer 2008, 17:27
od rnbw
AT91PS_PMC bude ta struktura.

Ten #define znamena, ze preprocesor kazdy vyskyt symbolu

Kód: Vybrat vše

AT91C_BASE_PMC

zmeni na

Kód: Vybrat vše

((AT91PS_PMC) 0xFFFFFC00)

takze riadok

Kód: Vybrat vše

AT91C_BASE_PMC -> PMC_PCER = 1<<AT91C_ID_UDP;

zmeni na

Kód: Vybrat vše

((AT91PS_PMC) 0xFFFFFC00) -> PMC_PCER = 1<<AT91C_ID_UDP;

Napsal: 06 čer 2008, 08:39
od piitr
Tak jsem si to promyslel a i něco našel: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

Takže ten můj způsob 1 by šel taky, protože by překladač předpokládal, že ta adresa registru se může změnit, takže by ho četl znova, ale výsledek by nebyl optimální. Správné řešení je říci, že hodnota v tom registru se může změnit. A to jde udělat tak, že se volatile napíše do definice té struktury přímo k té položce PCM_PCER. Asi nějak takhle:

typedef struct
{
volatile int PMC_PCER;
...
} *AT91PS_PMC;

Napsal: 06 čer 2008, 08:57
od rnbw
Ano, to vyzera dobre. Bolo by vhodne prelozit kratky kod a pozriet sa na vysledok disassemblerom.

Napsal: 06 čer 2008, 09:31
od piitr
Teda, někdy je možná třeba tu strukturu použít i jinak, třeba pro kopii hodnot registrů, a tam to volatile nechci. Pak by to šlo třeba takhle:

typedef struct
{
int a;
} STRUKTURA;

#define IO ( (volatile STRUKTURA *) 0xABCDE )

void f(void)
{
STRUKTURA zaloha;
IO->a = zaloha.a;
}

Napsal: 06 čer 2008, 10:52
od Návštěvník
piitr píše:Tak jsem si to promyslel a i něco našel: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

Takže ten můj způsob 1 by šel taky, protože by překladač předpokládal, že ta adresa registru se může změnit, takže by ho četl znova, ale výsledek by nebyl optimální. Správné řešení je říci, že hodnota v tom registru se může změnit. A to jde udělat tak, že se volatile napíše do definice té struktury přímo k té položce PCM_PCER. Asi nějak takhle:

typedef struct
{
volatile int PMC_PCER;
...
} *AT91PS_PMC;


Přesně je to tam definováno takto:

Kód: Vybrat vše

typedef volatile unsigned int AT91_REG;// Hardware register definition

typedef struct _AT91S_PMC {
....
   AT91_REG    PMC_PCER;    // Peripheral Clock Enable Register
   AT91_REG    PMC_PCDR;    // Peripheral Clock Disable Register
....
} AT91S_PMC, *AT91PS_PMC;

Takže je to volatile a přesto to nefunguje :(

Napsal: 06 čer 2008, 11:22
od piitr
Hmm, to mi přijde dobře napsané. Alespoň podle té dokumentace.
Takže je to asi chyba překladače.
Nebo možná jede ten překladač podle nějaké starší specifikace, kde se to volatile nesmí používat tak bohatě. Možná je to blbost, ale mám dojem že to céčko se taky nějak postupně vyvíjelo a doplňovalo. Nevím. Já jsem tyhle věci vždy řešil v assembleru nebo funkcema outp() a tak.

Napsal: 06 čer 2008, 11:30
od piitr
Teda, předpokládám, že to AT91C_BASE_UDP -> UDP_TXVC je definováno taky tak.

Napsal: 06 čer 2008, 12:12
od Jak21
AT91C_BASE_PMC -> PMC_PCER = 1<<AT91C_ID_UDP;
#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address

Takže struktura je umístěná na pevné adrese 0xfffffc00?
To je víc než 4 miliardy.

Napsal: 06 čer 2008, 12:19
od Návštěvník
Jak21 píše:
AT91C_BASE_PMC -> PMC_PCER = 1<<AT91C_ID_UDP;
#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address

Takže struktura je umístěná na pevné adrese 0xfffffc00?
To je víc než 4 miliardy.

ARM7 má adresní prostor 4GB a periferie jsou u AT91SAM7 na konci.

Napsal: 06 čer 2008, 13:19
od piitr
Jenom pro jistotu: Je to AT91C_BASE_UDP -> UDP_TXVC taky volatile?

Napsal: 06 čer 2008, 14:04
od Návštěvník
piitr píše:Jenom pro jistotu: Je to AT91C_BASE_UDP -> UDP_TXVC taky volatile?

Ano, je to stejné, všechny ty struktury jsou složené z AT91_REG a ten je volatile.

Napsal: 06 čer 2008, 15:36
od piitr
V tom případě si myslím, že to je chyba překladače. To je dost mrzuté.
Možná bych zkusil:
#define AT91C_BASE_PMC ((volatile AT91S_PMC *) 0xFFFFFC00)
Pokud to zapomíná v tom typedef nebo to nemá rád ve strukturách, tak by to mohlo pomoci.
Jinak nevím.

Napsal: 07 čer 2008, 21:50
od Jak21
Tento problém mne zneklidňuje.
Doposud jsem si myslel, že optimizátor může vynechat část kódu, ale že by přehodil pořadí příkazů, to je podle mne nepřípustné.

Zkusil bych (jenom pro test) vložit mezi příkazy krátký delay.

Stálo by za to poslat dotaz na http://www.avrfreaks.net/index.php?name ... file=index
kde odpovídají experti na překladače.

Napsal: 14 črc 2008, 22:32
od Fojtik
No jeste upresnim :wink: - volatile se pouziva nejen pro staticke promenne, ale pro veskere typy promennych.

A jeste jeden napad - vy jste resili jen jednu stranu.

Co takhle resit i tu druhou:
volatile int i = 1<<AT91C_ID_UDP;
AT91C_BASE_PMC -> PMC_PCER = i;

Tohle se zcela jiste nezoptimalizuje.