RTV forum PL | NewsGroups PL

Czy różnice w pętli `while` w Keil C mogą wpływać na działanie programu?

Zagwozdka w C Keil.

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Czy różnice w pętli `while` w Keil C mogą wpływać na działanie programu?

Goto page Previous  1, 2, 3, 4, 5, 6  Next

J.F.
Guest

Mon Feb 11, 2019 12:17 pm   



Użytkownik "Queequeg" napisał w wiadomości grup
dyskusyjnych:6ec55fa2-26d9-449d-ac7e-42741c8f7c6b@trust.no1...
J.F. <jfox_xnospamx@poczta.onet.pl> wrote:
Quote:
ewentualnie ... kompilator potraktowal to jako wartosc logiczna, i
uznal ze mu LSB wystarczy, albo wrecz ma niejawny typ logiczny,
8-bit, dokonal konwersji i sprawdzenia ... i mu sie MSB
zoptymalzowal.

Nie mógł tak zrobić. Przecież 0x0100 to prawda a nie fałsz. Tylko
zero
jest fałszem.

Ale jesli wewnetrznie uwaza, ze typ bool (wymysl Keil, bo w C nie ma)
jest reprezentowany przez char,
to dokonuje konwersji ... i choc prawidlowe to nie jest, to
wiedzielibysmy z grubsza dlaczego :-)

Quote:
Sprobuj
while(DEL_STEP != 0);

To tożsame z `while(DEL_STEP);`.

Czy tozsame to sie na listingu w assemblerze okaze :-)

J.

Queequeg
Guest

Mon Feb 11, 2019 12:54 pm   



J.F. <jfox_xnospamx@poczta.onet.pl> wrote:

Quote:
ewentualnie ... kompilator potraktowal to jako wartosc logiczna, i
uznal ze mu LSB wystarczy, albo wrecz ma niejawny typ logiczny,
8-bit, dokonal konwersji i sprawdzenia ... i mu sie MSB zoptymalzowal.

Nie mógł tak zrobić. Przecież 0x0100 to prawda a nie fałsz. Tylko zero
jest fałszem.

Quote:
Sprobuj
while(DEL_STEP != 0);

To tożsame z `while(DEL_STEP);`.

--
Eksperymentalnie: http://facebook.com/groups/pl.misc.elektronika

Queequeg
Guest

Mon Feb 11, 2019 12:59 pm   



Irek.N. <tajny@jakis.taki.jest.pl> wrote:

Quote:
Znalazłem błąd w starym kodzie. Ze zdziwieniem odkryłem, że w komendzie
while(DEL_STEP); kompilator sprawdza tylko LSB zmiennej.

W jaki sposób to odkryłeś i potwierdziłeś?

Masz wygenerowany kod assemblerowy?

Czy jeżeli na sztywno przypiszesz do DEL_STEP wartość np. 0x0100, i
nigdzie nie będziesz jej zmieniał, to pętla z `while` się nie "odetka",
a odetka się, gdy przypiszesz 0x0101?

(zakładam że to '51, czyli 8-bitowiec)

--
Eksperymentalnie: http://facebook.com/groups/pl.misc.elektronika

Mateusz Viste
Guest

Mon Feb 11, 2019 2:27 pm   



On Mon, 11 Feb 2019 04:45:35 -0800, kropelka wrote:
Quote:
Ja wiem, że embedded to skansen ale idąc drogą "C to tylko C90" nie
można by było uznać za program w C nawet takiego, który deklaruje
zmienną gdzie indziej niż na początku programu/funkcji.

Bo to zaiste nie (ANSI) C. Na co komu deklarowanie zmiennych w środku
kodu? Jeśli odczuwasz taką potrzebę, to zapewne twój kod wymaga
refaktoryzacji. Prawdziwe C to C89, wszystko inne to wymysły młodzieży,
której się nudziło.

No ok - uczciwie muszę przyznać, że zdarza mi się korzystać z 'long
long', ale to jedyna rzecz której mi czasem braknie w C89. :)

Mateusz

Guest

Mon Feb 11, 2019 2:45 pm   



W dniu poniedziałek, 11 lutego 2019 12:18:54 UTC+1 użytkownik J.F.. napisał:
Quote:
Ale jesli wewnetrznie uwaza, ze typ bool (wymysl Keil, bo w C nie ma)
jest reprezentowany przez char,
Hej, standard C99 będzie niedługo obchodził swoje dwudzieste urodziny:)

Ja wiem, że embedded to skansen ale idąc drogą "C to tylko C90" nie można
by było uznać za program w C nawet takiego, który deklaruje zmienną gdzie
indziej niż na początku programu/funkcji.

Pozdrawiam,
--
Karol Piotrowski

Guest

Tue Feb 12, 2019 3:33 am   



W dniu poniedziałek, 11 lutego 2019 14:27:54 UTC+1 użytkownik Mateusz Viste napisał:
Quote:
Bo to zaiste nie (ANSI) C. Na co komu deklarowanie zmiennych w środku
kodu? Jeśli odczuwasz taką potrzebę, to zapewne twój kod wymaga
refaktoryzacji. Prawdziwe C to C89, wszystko inne to wymysły młodzieży,
której się nudziło.
Wiem, że rozmawiamy trochę z przymrużeniem oka, więc miałem kiedyś

przygodę, kiedy utrzymywana przeze mnie paczka (co gorsza, w Pythonie)
przestała się budować. Tam był kod w C który był generowany
automatycznie, a narzędzia do współpracy Python - C na pewnym etapie
przestawiły flagi kompilatora z domyślnego "ANSI C z typowymi bajerami"
na "brak wstępu dla młodzieży, wyrzucaj error przy czymkolwiek
czego nie można według C89". Wszystko dzięki temu, że generowany
kod miał "int i;" przed forem a nie na początku funkcji.
Wtedy się dowiedziałem, że tego nie było w standardzie bo wszystkie
kompilatory C jakich w życiu używałem nie miały co do tego
obiekcji;)

Quote:
No ok - uczciwie muszę przyznać, że zdarza mi się korzystać z 'long
long', ale to jedyna rzecz której mi czasem braknie w C89. Smile
Ja patrzę z punktu widzenia kogoś, kto czasem napisze coś na

"normalny" komputer i chyba nigdy nie udało mi się napisać programu
w C, który używa poza jakimiś niekrytycznymi pętlami po 100 elementach
któregokolwiek z typów danych z C89. Standard C w tym zakresie jest
spuścizną po czasach Unixa, kiedy starano się zrobić jeden przenośny język oprogramowania i system operacyjny obejmujący miriadę komputerów.
Efekt jest taki, że w kontekście zwykłego x86-64 windowsowy long
ma 32 bity, a uniksowy 64 i obydwa podejścia są zupełnie koszerne
pod względem standardu. Long long rzeczywiście jest sposobem
na wymuszenie zmiennej, która będzie miała te >= 64 bity ;)

Pozdrawiam,
--
Karol Piotrowski

Mateusz Viste
Guest

Tue Feb 12, 2019 9:31 am   



On Mon, 11 Feb 2019 17:33:25 -0800, kropelka wrote:
Quote:
Ja patrzę z punktu widzenia kogoś, kto czasem napisze coś na "normalny"
komputer i chyba nigdy nie udało mi się napisać programu w C, który
używa poza jakimiś niekrytycznymi pętlami po 100 elementach
któregokolwiek z typów danych z C89.

Ale przecież typy danych w C89 są całkiem normalne: char, short, int,
long... Ich szerokości mogą zmieniać się z jednego komputera na drugi
(np. taki int może mieć raz 16, raz 32, a innym razem 64 bity), ale to
wszystko jest zgodne z C89. long natomiast ma zawsze co najmniej 32 bity
- w jakich zastosowaniach jest potrzeba więcej na "normalnym" komputerze?

Mi zdarza się (rzadko, ale jednak) użyć uint64_t do liczenia jakichś
naprawdę dużych wielkości, np. do zliczania cykli CPU, a czasem nawet po
_uint128_t (gcc) sięgnę jak potrzebuję popracować na adresach IPv6. Ale
to naprawdę sporadyczne przypadki, stąd ciekaw jestem co takiego piszesz
że w C89 nie da się :)

Mateusz

Irek.N.
Guest

Tue Feb 12, 2019 10:39 pm   



No więc znalazłem chwilę aby podjechać do klienta i popatrzeć dokładnie
w kod.
Na wstępie małe usprawiedliwienie - procedura była napisana na 8051 i
uruchomiona na jednym z pierwszych PLC jakie zrobiłem, w latach 90, ale
stosowana też później*. W tamtych czasach wydawało mi się, że ogarniam
podstawy C :)

W maszynie którą diagnozowałem definicja zmiennej DEL_STEP była o zgrozo
jako unsigned char. Nie zwróciłem na to uwagi, choć zauważyłem, że
sprawdzany jest tylko młodszy - przekazany - bajt zmiennej z którą
wywołano funkcję. Wygląda więc na to, że kompilator miał rację.

Po zmianie definicji na unsigned int kompilator robi OLR na obu
połówkach zmiennej DEL_STEP a następnie sprawdza czy wynik operacji jest
zerowy. Bardzo ładne rozwiązanie moim zdaniem.

Zrobiłem jeszcze jedną rzecz. Ponieważ jak zauważyliście, nie ma
gwarancji, że sprawdzenie 16 bitów będzie poprawne w przypadku gdy
przerwanie może je zmienić, podłączyłem oscyloskop, persystencję na
nieskończoną i obserwowałem czas generowany przez procedurę. Zdarzały
się błędnie odliczone interwały, ale nie za często. Zrobiłem jak Mateusz
podpowiedział - flaga w przerwaniu modyfikującym zmienną. Nie złapałem
żadnego błędnego odliczenia.

Tak więc przepraszam, ale wychodzi na to, że sensacji nie ma, kompilator
jednak dawał radę, a ja znowu się czegoś nauczyłem :)

Dzięki wszystkim za pomoc.


Miłego.
Irek.N.
* w późniejszych wersjach kodu (trochę inna wersja PLC) już była
poprawna definicja jako typ 16 bitowy, czyli kiedyś to zauważyłem,
poprawiłem i zapomniałem Sad

stary grzyb
Guest

Tue Feb 12, 2019 11:02 pm   



Quote:
... kiedyś to zauważyłem, poprawiłem i zapomniałem Sad

Przynajmniej jakaś pociecha dla mnie - myślałem, że tylko ja mam sklerozę Wink

HF5BS
Guest

Wed Feb 13, 2019 9:10 am   



Użytkownik "stary grzyb" <starygrzyb@onet.pl> napisał w wiadomości
news:q3vfp6$rq6$2@dont-email.me...
Quote:
... kiedyś to zauważyłem, poprawiłem i zapomniałem :(

Przynajmniej jakaś pociecha dla mnie - myślałem, że tylko ja mam sklerozę
Wink

Panie, ja tam nie mam sklerozy, odpukać! Puk puk... Kto tam? Smile:)

Kiedyś mi prawie półtora roku zajęło, aby złapać, dlaczego przy pracy z TC,
wyskakuje mi pewne (niepożądane) okienko. Banał, że śmiać sie chce Smile
Czemu tyle? Bo stale zapomniałem wyłapać okoliczności, w jakich się to
staje.

--
Łapy, łapy, cztery łapy,
A na łapach pies kudłaty.
Kto dogoni psa? Kto dogoni psa?
Może ty? Może ty? Może jednak ja...?

Piotr Gałka
Guest

Wed Feb 13, 2019 10:44 am   



W dniu 2019-02-12 o 23:02, stary grzyb pisze:
Quote:
... kiedyś to zauważyłem, poprawiłem i zapomniałem :(

Przynajmniej jakaś pociecha dla mnie - myślałem, że tylko ja mam
sklerozę Wink

Zdarzyło mi się kiedyś, że postanowiłem, że coś muszę zmodyfikować w
jednym programie. Wyszukałem miejsce gdzie to należy poprawić - a tu
"już ktoś to zrobił". Według daty pliku wynikało, że góra miesiąc temu Sad
P.G.

J.F.
Guest

Wed Feb 13, 2019 11:28 am   



Użytkownik "Irek.N." napisał w wiadomości grup
dyskusyjnych:q3vee4$o74$1@node1.news.atman.pl...
Quote:
Na wstępie małe usprawiedliwienie - procedura była napisana na 8051 i
uruchomiona na jednym z pierwszych PLC jakie zrobiłem, w latach 90,
ale stosowana też później*. W tamtych czasach wydawało mi się, że
ogarniam podstawy C :)

W maszynie którą diagnozowałem definicja zmiennej DEL_STEP była o
zgrozo jako unsigned char. Nie zwróciłem na to uwagi, choć
zauważyłem, że sprawdzany jest tylko młodszy - przekazany - bajt
zmiennej z którą wywołano funkcję. Wygląda więc na to, że kompilator
miał rację.

uzyc niewlasciwy typ - zdarza sie.
Ale nie spojrzec jaki to typ przy sprawdzaniu/szukaniu bledu ... czas
na lecytyne :-)

Quote:
Po zmianie definicji na unsigned int kompilator robi OLR na obu
połówkach zmiennej DEL_STEP a następnie sprawdza czy wynik operacji
jest zerowy. Bardzo ładne rozwiązanie moim zdaniem.

Typowe.

Quote:
Zrobiłem jeszcze jedną rzecz. Ponieważ jak zauważyliście, nie ma
gwarancji, że sprawdzenie 16 bitów będzie poprawne w przypadku gdy
przerwanie może je zmienić, podłączyłem oscyloskop, persystencję na
nieskończoną i obserwowałem czas generowany przez procedurę. Zdarzały
się błędnie odliczone interwały, ale nie za często.

Czyli potrafi przerwanie trafic miedzy dwie instrukcje ?
No w sumie - zawsze miedzy dwie trafia, tylko kwestia
prawdopodobienstwa, kiedy trafi miedzy dwie istotne.

A tych instrukcji przy ORL byc moze nawet wiecej.

Quote:
Zrobiłem jak Mateusz podpowiedział - flaga w przerwaniu modyfikującym
zmienną. Nie złapałem żadnego błędnego odliczenia.

Rozumiem, ze najpierw zmieniles typ zmiennej na int ?

Ale nie bardzo rozumiem - przerwanie ustawia flage, modyfikuje
zmienna, gasi flage ?
na przetwarzanie w procesie głownym nie ma to znaczenia - sprawdzi
sobie, ze flagi nie ma, zacznie czytac zmienna ... i tu przerwanie
przychodzi.
Co innego gdy uzywa zmiennej przerwanie wyzszego poziomu.

Ja bym tam wylaczyl przerwania na czas sprawdzenia, to raptem kilka
instrukcji, ale w pojedynczym while zaprogramowac to trudno.

A swoja droga - czy Keil sam ich nie wylacza ? Dla zmiennych volatile
powinien.

Quote:
* w późniejszych wersjach kodu (trochę inna wersja PLC) już była
poprawna definicja jako typ 16 bitowy, czyli kiedyś to zauważyłem,
poprawiłem i zapomniałem Sad

Ale o co chodzi - powiekszyles wartosc opoznienia ponad 255, i sie
okazalo, ze nie czeka tyle co powinien ?

J.

Janusz
Guest

Wed Feb 13, 2019 1:48 pm   



W dniu 2019-02-13 o 11:28, J.F. pisze:
Quote:
Użytkownik "Irek.N."  napisał w wiadomości grup
dyskusyjnych:q3vee4$o74$1@node1.news.atman.pl...
Na wstępie małe usprawiedliwienie - procedura była napisana na 8051 i
uruchomiona na jednym z pierwszych PLC jakie zrobiłem, w latach 90,
ale stosowana też później*. W tamtych czasach wydawało mi się, że
ogarniam podstawy C :)

W maszynie którą diagnozowałem definicja zmiennej DEL_STEP była o
zgrozo jako unsigned char. Nie zwróciłem na to uwagi, choć zauważyłem,
że sprawdzany jest tylko młodszy - przekazany - bajt zmiennej z którą
wywołano funkcję. Wygląda więc na to, że kompilator miał rację.

uzyc niewlasciwy typ - zdarza sie.
Ale nie spojrzec jaki to typ przy sprawdzaniu/szukaniu bledu ... czas na
lecytyne :-)

Po zmianie definicji na unsigned int kompilator robi OLR na obu
połówkach zmiennej DEL_STEP a następnie sprawdza czy wynik operacji
jest zerowy. Bardzo ładne rozwiązanie moim zdaniem.

Typowe.

Zrobiłem jeszcze jedną rzecz. Ponieważ jak zauważyliście, nie ma
gwarancji, że sprawdzenie 16 bitów będzie poprawne w przypadku gdy
przerwanie może je zmienić, podłączyłem oscyloskop, persystencję na
nieskończoną i obserwowałem czas generowany przez procedurę. Zdarzały
się błędnie odliczone interwały, ale nie za często.

Czyli potrafi przerwanie trafic miedzy dwie instrukcje ?
No w sumie - zawsze miedzy dwie trafia, tylko kwestia
prawdopodobienstwa, kiedy trafi miedzy dwie istotne.

A tych instrukcji przy ORL byc moze nawet wiecej.

Zrobiłem jak Mateusz podpowiedział - flaga w przerwaniu modyfikującym
zmienną. Nie złapałem żadnego błędnego odliczenia.

Rozumiem, ze najpierw zmieniles typ zmiennej na int ?

Ale nie bardzo rozumiem - przerwanie ustawia flage, modyfikuje zmienna,
gasi flage ?
na przetwarzanie w procesie głownym nie ma to znaczenia - sprawdzi
sobie, ze flagi nie ma, zacznie czytac zmienna ... i tu przerwanie
przychodzi.
Co innego gdy uzywa zmiennej przerwanie wyzszego poziomu.

Ja bym tam wylaczyl przerwania na czas sprawdzenia, to raptem kilka
instrukcji, ale w pojedynczym while zaprogramowac to trudno.

A swoja droga - czy Keil sam ich nie wylacza ? Dla zmiennych volatile
powinien.
W avr studio nie wyłącza, i keil pewnie też,

w gcc jest do tego osobna sekcja, atomic block się nazywa
i w niej sie takie porównania robi.


--
Pozdr
Janusz

stary grzyb
Guest

Wed Feb 13, 2019 4:22 pm   



Quote:
Przynajmniej jakaś pociecha dla mnie - myślałem, że tylko ja mam
sklerozę ;)

Kiedyś mi prawie półtora roku zajęło, aby złapać, dlaczego przy pracy z
TC, wyskakuje mi pewne (niepożądane) okienko. Banał, że śmiać sie chce Smile
Czemu tyle? Bo stale zapomniałem wyłapać okoliczności, w jakich się to
staje.

Ja mam nawet tabletki na poprawę pamięci, ale co z tego, skoro ...
zapominam je brać Smile

Irek.N.
Guest

Wed Feb 13, 2019 9:13 pm   



Quote:
Po zmianie definicji na unsigned int kompilator robi OLR na obu
połówkach zmiennej DEL_STEP a następnie sprawdza czy wynik operacji
jest zerowy. Bardzo ładne rozwiązanie moim zdaniem.

Typowe.

Dla mnie bardzo eleganckie :)

Quote:
Rozumiem, ze najpierw zmieniles typ zmiennej na int ?

W * pisałem, że już kiedyś to znalazłem. Oczywiście że poprawiłem :)

Quote:
Ale nie bardzo rozumiem - przerwanie ustawia flage, modyfikuje zmienna,
gasi flage ?
na przetwarzanie w procesie głownym nie ma to znaczenia - sprawdzi
sobie, ze flagi nie ma, zacznie czytac zmienna ... i tu przerwanie
przychodzi.
Co innego gdy uzywa zmiennej przerwanie wyzszego poziomu.

Procedura ustawiająca zmienną modyfikowaną w przerwaniu ustawia flagę i
czeka na jej zgaszenie. Przerwanie odlicza i jak doliczy to gasi flagę.

Quote:
Ja bym tam wylaczyl przerwania na czas sprawdzenia, to raptem kilka
instrukcji, ale w pojedynczym while zaprogramowac to trudno.

Niepotrzebna zabawa. Poza tym wprowadzasz dodatkowy jitter ;)

Quote:
A swoja droga - czy Keil sam ich nie wylacza ? Dla zmiennych volatile
powinien.

Niestety ale ignoruje zupełnie volatile, a nie powinien moim zdaniem.


Quote:
Ale o co chodzi - powiekszyles wartosc opoznienia ponad 255, i sie
okazalo, ze nie czeka tyle co powinien ?


No ba, dajesz operatorowi możliwość ustawiania parametru w zakresie
100-500, a tu zonk, czasami maszyna się buntuje :)

Miłego.
Irek.N.

Goto page Previous  1, 2, 3, 4, 5, 6  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Czy różnice w pętli `while` w Keil C mogą wpływać na działanie programu?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map