RTV forum PL | NewsGroups PL

Jak używać opóźnień w C++ na platformie GNU ARM z definicjami w ms i us?

Problemy z C++ (GNU ARM)

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Jak używać opóźnień w C++ na platformie GNU ARM z definicjami w ms i us?

Goto page 1, 2  Next

Konop
Guest

Thu May 15, 2008 7:46 pm   



Witam!

Mam mały problem... który wynika z mojej nieznajomości tego języka
Wink.. Otóż chciałbym w ARMach robić sobie takie proste opóźnienia w stylu:
for (i=0;i<10000;i++);
Tylko zamiast podawać wartość maksymalną wprost chciałbym używać stałych
ms i us i definiować je w zależności od szybkości zegara Wink... No to
robię tak:
const int ms = 3025;
(...)
for (i=0;i<10*ms;i++);

No i działa Smile... gorzej z mikrosekundami :/... Niestety, jak wpiszę tak:
const float us = 3.025
(...)
for (i=0;i<10*us;i++);

To wyskakują błędy:
undefined reference to `__floatsisf' lpc-2378stk main.c line 61
undefined reference to `__ltsf2' lpc-2378stk main.c line 61 undefined
reference to `__mulsf3' lpc-2378stk main.c line 61

No i domyślam się o co chodzi... nie mam bibliotek do mnożenia liczb
zmiennoprzecinkowych itp... Tylko mi nie o to chodzi!! Smile... ja bym
chciał, zeby kompilator pomnożył mi 10*3.025, zaokrąglił i de facto
wpisał i<30 i tyle... no ale niestey, stała jest w tym języku niezmienną
zmienną i nic nie idzie zrobić Sad... I stąd dwa pytania:
1) jaką dodać bibliotekę, żeby to ruszyło Wink...
2) jak to zrobić, żeby to działało tak, jak ja chcę (bo wiem, że mój
zapis jest błędny, ale lepszego wymyślić nie umiem Sad)

Pozdrawiam
Konoppo

John Smith
Guest

Thu May 15, 2008 8:10 pm   



Quote:
Tylko zamiast podawać wartość maksymalną wprost chciałbym używać stałych
ms i us i definiować je w zależności od szybkości zegara Wink... No to
robię tak:
const int ms = 3025;
(...)
for (i=0;i<10*ms;i++);

No i działa Smile... gorzej z mikrosekundami :/... Niestety, jak wpiszę tak:
const float us = 3.025
(...)
for (i=0;i<10*us;i++);


Spróbuj może:
const int us = 3.025 * 10;
for (i=0;i<us;i++);
Wtedy mnożenie wykonane typu float zostanie na etapie kompilacji. Sprawdzić trzeba.
K.

Konop
Guest

Thu May 15, 2008 8:28 pm   



John Smith pisze:
Quote:
Tylko zamiast podawać wartość maksymalną wprost chciałbym używać
stałych ms i us i definiować je w zależności od szybkości zegara Wink...
No to robię tak:
const int ms = 3025;
(...)
for (i=0;i<10*ms;i++);

No i działa Smile... gorzej z mikrosekundami :/... Niestety, jak wpiszę tak:
const float us = 3.025
(...)
for (i=0;i<10*us;i++);


Spróbuj może:
const int us = 3.025 * 10;
for (i=0;i<us;i++);
Wtedy mnożenie wykonane typu float zostanie na etapie kompilacji.
Sprawdzić trzeba.
K.

No tak, jakbym chciał zdefiniować jedną stałą, to bym nie kombinował z

mnożeniem... ale chodzi o to, ze chciałem mieć możliwość wrzucania
for'ów z róznymi opóźnieniami:
for (i=0;i<1*us;i++);
for (i=0;i<5*us;i++);
for (i=0;i<100*us;i++);

Chyba nie ma sensu definiować stałych _1us, _5us, _100us i wszystkich
innych możliwych Wink...

Pozdrawiam
Konop

Sebastian Bialy
Guest

Thu May 15, 2008 8:38 pm   



Konop wrote:
Quote:
const float us = 3.025
(...)
for (i=0;i<10*us;i++);

A tak:

const float us = 3025

for (i=0;i<(10*us)/1000;i++);

Sebastian Bialy
Guest

Thu May 15, 2008 8:40 pm   



Sebastian Bialy wrote:
Quote:
const float us = 3025

sorry ...

const int us = 3025

Konop
Guest

Thu May 15, 2008 8:54 pm   



Sebastian Bialy pisze:
Quote:
Sebastian Bialy wrote:
const float us = 3025

sorry ...

const int us = 3025

Zrobiłem tak:

#define ms 3750
#define us ms/1000

i chyba działa Wink.. chyba, tzn. jak używam us i zmieniam wartość ms, to
opóźnienie się zmienia Wink... niestety, nie mam porządnego
częstościomierza, ten w multimetrze widze, że jest szajski... no ale tak
czy siak:
-bibliotek do floata to nie wymaga Wink...
-nie zaokrągla us do 3 albo 4, bo zmiana ms z 3600 na 3750 powoduje
zmianę czasu generowanego przez us Wink...

no ale dalej nie wiem, czy to obliczył kompilator, czy to ARM liczy w
każdej pętli Wink... no ale de-asemblera chyba nie mam ;P...

Dzięki wielkie za sugestię, żeby użyć /

Pozdrawiam
Konop

Sebastian Bialy
Guest

Thu May 15, 2008 8:57 pm   



Konop wrote:
Quote:
no ale de-asemblera chyba nie mam ;P...

@arm-elf-objdump -h -S program.elf >program.lst

Quote:
Dzięki wielkie za sugestię, żeby użyć /

Się było kiedyś koderem na MC68000 Smile

Konop
Guest

Thu May 15, 2008 8:59 pm   



Konop pisze:
Quote:
Sebastian Bialy pisze:
Sebastian Bialy wrote:
const float us = 3025

sorry ...

const int us = 3025

Zrobiłem tak:

#define ms 3750
#define us ms/1000

i chyba działa Wink.. chyba, tzn. jak używam us i zmieniam wartość ms, to
opóźnienie się zmienia Wink... niestety, nie mam porządnego
częstościomierza, ten w multimetrze widze, że jest szajski... no ale tak
czy siak:
-bibliotek do floata to nie wymaga Wink...
-nie zaokrągla us do 3 albo 4, bo zmiana ms z 3600 na 3750 powoduje
zmianę czasu generowanego przez us Wink...

no ale dalej nie wiem, czy to obliczył kompilator, czy to ARM liczy w
każdej pętli Wink... no ale de-asemblera chyba nie mam ;P...

Dzięki wielkie za sugestię, żeby użyć /

Pozdrawiam
Konop
A nie, jednak coś zaokrągla ;(... i moją i Twoją metodą - zmiana ms z

3750 na 3740 powoduję zmianę częstotliwości z 2.044kHz na 1.6xxkHz... aż
tak tragicznej rozdzielczości to ten miernik chyba nie ma Wink... mogę
sprawdzić na oscyloskopie (analogowym) jakby co Wink... tę częstotliwość
to generują 2 fory 250*us albo (250*ms)/1000

Zbych
Guest

Thu May 15, 2008 9:22 pm   



Konop przemówił ludzkim głosem:
Quote:
Witam!

Mam mały problem... który wynika z mojej nieznajomości tego języka
Wink.. Otóż chciałbym w ARMach robić sobie takie proste opóźnienia w stylu:
for (i=0;i<10000;i++);
Tylko zamiast podawać wartość maksymalną wprost chciałbym używać stałych
ms i us i definiować je w zależności od szybkości zegara Wink... No to

Po pierwsze, nie używaj do opóźnień pętli w c bo w zależności gdzie to
wstawisz to możesz otrzymywać różny kod w assemblerze (i różny czas
wykonania). Lepiej zrobić funkcję inline ze wstawką asemblerową i jako
parametr przekazywać liczbę obiegów pętli. Oczywiście i tak się wszystko
będzie rozjeżdżało jeśli masz włączone przerwania, MAM, cache, albo
kilka obszarów pamięci z różnymi wait-state'ami.
Po drugie napisz sobie makro, które wyliczy ilość obiegów pętli.
Poniższy kod nie jest dla ARMa, ale bez problemów powinieneś to sobie
przerobić.



static __inline void Wait(unsigned long Delay){
unsigned long Result;

asm volatile ("L_%=:\n"
"\tdec.l #1,%0 \n"
"\tbne L_%= \n":"=r"(Result): "0"(Delay));
}


#define WaitMs(a) Wait( (unsigned long)((a) * 18000000.0 / F_CPU) )
#define WaitUs(a) Wait( (unsigned long)((a) * 18000.0 / F_CPU) )

Współczynniki musisz sobie wyliczyć, albo dobrać przy pomocy
oscyloskopu. Wersja full-wypas może dodatkowo sprawdzać czy wartość
parametru "a" da się wyliczyć na etapie kompilacji i w razie czego
generować błąd ( poszukaj opisu funkcji __builtin_constant_p )

Konop
Guest

Thu May 15, 2008 9:31 pm   



Quote:
A nie, jednak coś zaokrągla ;(... i moją i Twoją metodą - zmiana ms z
3750 na 3740 powoduję zmianę częstotliwości z 2.044kHz na 1.6xxkHz... aż
tak tragicznej rozdzielczości to ten miernik chyba nie ma Wink... mogę
sprawdzić na oscyloskopie (analogowym) jakby co Wink... tę częstotliwość
to generują 2 fory 250*us albo (250*ms)/1000

No niestety... na oscyloskopie czas dla 3740 ma 2 działki, a dla 3750 -
3 dzialki (tak w przybliżeniu ;P)... no nic, postaram się wrzucić to
jednak do asemblera Wink... Ale dzięki, za uwagi Smile..

Pozdrawiam
Konop

Adam Dybkowski
Guest

Thu May 15, 2008 11:15 pm   



Konop pisze:

Quote:
Mam mały problem... który wynika z mojej nieznajomości tego języka
Wink.. Otóż chciałbym w ARMach robić sobie takie proste opóźnienia w stylu:
for (i=0;i<10000;i++);

Uważaj na poziom optymalizacji. Ja bym się nie zdziwił, gdy powyższa
linia zostanie zastąpiona jedynie podstawieniem i=10000 (albo i tego
brak gdy zmienna "i" nie jest potem używana).

Do robienia opóźnień polecam skorzystanie z dobrodziejstw peryferiów
(zależy jakiego dokładnie masz ARMa), np. licznika RTT albo chociaż
swobodnie tykającego timera (np. co 1 us).

--
Adam Dybkowski
http://dybkowski.net/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

Konop
Guest

Fri May 16, 2008 12:03 am   





Konop
Guest

Fri May 16, 2008 12:06 am   



Adam Dybkowski pisze:
Quote:
Konop pisze:

Mam mały problem... który wynika z mojej nieznajomości tego języka
Wink.. Otóż chciałbym w ARMach robić sobie takie proste opóźnienia w stylu:
for (i=0;i<10000;i++);

Fakt, o optymalizacji nie pomyslałem, ale już jest w ASM, volatile, to
chyba mi tego nie ruszy Wink..

Quote:
Do robienia opóźnień polecam skorzystanie z dobrodziejstw peryferiów
(zależy jakiego dokładnie masz ARMa), np. licznika RTT albo chociaż
swobodnie tykającego timera (np. co 1 us).

Co do opóźniej - masz rację, najlepszy jest timer, ale nie zawsze
super-dokładność jest potrzebna, a ja jednocześnie uczę się C, C++ i
ARMów, dlatego chciałem zacząć od czegoś prostego, do timerów jeszcze
nie doszedłem Wink... Z drugiej strony - chciałem, żeby z tej "nauki"
powstało coś przydatnego - stąd pomysł stworzenia uniwersalnej funkcji
opóźniającej Wink....

Pozdrawiam
Konop

Konop
Guest

Fri May 16, 2008 10:12 am   



Adam Dybkowski pisze:
Quote:
Konop pisze:

Mam mały problem... który wynika z mojej nieznajomości tego języka
Wink.. Otóż chciałbym w ARMach robić sobie takie proste opóźnienia w stylu:
for (i=0;i<10000;i++);

Uważaj na poziom optymalizacji. Ja bym się nie zdziwił, gdy powyższa
linia zostanie zastąpiona jedynie podstawieniem i=10000 (albo i tego
brak gdy zmienna "i" nie jest potem używana).

Do robienia opóźnień polecam skorzystanie z dobrodziejstw peryferiów
(zależy jakiego dokładnie masz ARMa), np. licznika RTT albo chociaż
swobodnie tykającego timera (np. co 1 us).


A może wiesz, skąd się wzięło takie coś?

Mam wait'a zdefiniowanego tak, jak pisałem wcześniej:

I potem w main mam coś takiego:

// endless loop to toggle the red LED P0.0
while (1)
{
IOSET0 = 1;
Waitms (500);
IOCLR0 = 1;
Waitms (500);
}


Bo zrobieniu pliku main.lst z pliku main.out uzyskuje:

// endless loop to toggle the red LED P0.0
while (1)
{
IOSET0 = 1;
998: e3a0324e mov r3, #-536870908 ; 0xe0000004
99c: e283390a add r3, r3, #163840 ; 0x28000
9a0: e3a02001 mov r2, #1 ; 0x1
9a4: e5832000 str r2, [r3]
Waitms (500);
9a8: e3a00861 mov r0, #6356992 ; 0x610000
9ac: e2800c25 add r0, r0, #9472 ; 0x2500
9b0: e2800024 add r0, r0, #36 ; 0x24
9b4: eb000008 bl 9dc <delay>
IOCLR0 = 1;
9b8: e3a032ce mov r3, #-536870900 ; 0xe000000c
9bc: e283390a add r3, r3, #163840 ; 0x28000
9c0: e3a02001 mov r2, #1 ; 0x1
9c4: e5832000 str r2, [r3]
Waitms (500);
9c8: e3a00861 mov r0, #6356992 ; 0x610000
9cc: e2800c25 add r0, r0, #9472 ; 0x2500
9d0: e2800024 add r0, r0, #36 ; 0x24
9d4: eb000000 bl 9dc <delay>
}
9d8: eaffffee b 998 <main+0xa8>

000009dc <delay>:
9dc: e1a0c00d mov ip, sp
9e0: e92dd800 stmdb sp!, {fp, ip, lr, pc}
9e4: e24cb004 sub fp, ip, #4 ; 0x4
9e8: e24dd004 sub sp, sp, #4 ; 0x4
9ec: e50b0010 str r0, [fp, #-16]
9f0: e51b3010 ldr r3, [fp, #-16]

000009f4 <petla100>:
9f4: e2533001 subs r3, r3, #1 ; 0x1
9f8: 1afffffd bne 9f4 <petla100>
9fc: e89da808 ldmia sp, {r3, fp, sp, pc}

O co chodzi? Po pierwsze, instrukcja IOSET składa się z przypisania do
r3 wartości E0000004h i potem dodaniu 28000h, jakby od razu nie mógł
przypisać E0028004h :/:/:/... Po drugie - delay nie jest wykonywany jako
__inline, tylko normalna funkcja.. nie wspominajac, ze nie mam pojęcia
co on tam oblicza na początku tego delaya Sad...

Może ktoś coś poradzić?? Bo już nie mogę... to jest dla mnie za duży
szok... pierwszy raz stykam się z ARMami, z narzędziami tego typu (pliki
makefile i inne cuda, to nie to samo, co przycisk COMPILE czy BULID w
AVT Studio itp ;P), praktycznie pierwsze zetkniecie z C i C++... za duzo
tego ;P...

Pozdrawiam
Konop

entroper
Guest

Fri May 16, 2008 12:34 pm   



Użytkownik "Konop" <konoppo@gazeta.pl> napisał w wiadomości
news:g0iflf$hlj$2@inews.gazeta.pl...

Quote:
(...) stąd pomysł stworzenia uniwersalnej funkcji
opóźniającej Wink....

tonący delaya się chwyta

;)

e.

Goto page 1, 2  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Jak używać opóźnień w C++ na platformie GNU ARM z definicjami w ms i us?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map