Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 20 kwi 2024, o 12:25


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 
Autor Wiadomość
PostNapisane: 24 sie 2019, o 17:55 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

Cześć,

Pewnie znowu się zbłaźnię głupim pytaniem - ale czasami utykam w martwym punkcie, a pomoc od Was pomaga mi ruszyć dalej.

Problem jest następujący. Używam NRF24L01 oraz bibliotek NRF24L01 oraz SPI.
Udało mi się po wielu próbach uruchomić komunikację.

Problemem jest natomiast (tak mi się wydaje) nie zrozumienie przeze mnie funkcji parse_nrf_data.
Nie za bardzo wiem jak dużo mogę kodu zawierającego tą bibliotekę udostępniać, dlatego dam tylko wycinki.

W miejscu przykładu wstawiłem: (odbiornik)

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i co zabawne - działa tylko np. 97 (a), lub 98 (b).
target przyjmuje poprawną wartość zgodnie z konkretnym ifem.

W przypadku gdy wyślę np. 95 - program przeskakuje po ifach, jakby losowo (pewnie nie losowo, ale ja nie mogę zauważyć prawidłowości).

kod nadajnika:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


I tu znowu dziwna rzecz:
Pobieram dane z UART - wpisuje je do rData i wysyłam przez NRF.
Jak wysyłam a(97), b(98) wszystko jest ok.
Gdy wyślę c(99) - układ się zawiesza (przestaje nadawać, pisać na UART) - muszę zresetować zasilanie. Wszystko potem wraca do normy.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 18:21 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Cześć,

odniosę się, przynajmniej na razie, do tego zdania:
"W przypadku gdy wyślę np. 95 - program przeskakuje po ifach, jakby losowo (pewnie nie losowo, ale ja nie mogę zauważyć prawidłowości)."

Co to znaczy losowo ? Korzystasz z debuggera rozumiem ? Używasz tego na stmie ? nie masz przypadkiem włączonej optymalizacji przy kompilacji ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 18:50 
Offline
Użytkownik

Dołączył(a): 09 lip 2019
Posty: 106
Pomógł: 10

goslawen napisał(a):
[...]
Problemem jest natomiast (tak mi się wydaje) nie zrozumienie przeze mnie funkcji parse_nrf_data.
Nie za bardzo wiem jak dużo mogę kodu zawierającego tą bibliotekę udostępniać, dlatego dam tylko wycinki.

W miejscu przykładu wstawiłem: (odbiornik)

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

[...]
W/g dokoumentacji "The strcmp_P() function is similar to strcmp() except that s2 is pointer to a string in program space."

Jeśli dobrze rozumiem - następujący zapis
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

prawdopodobnie porównuje bufor 'buf' z przypadkową zawartością pamięci programu

Czy liczba 98 nie powinna być przypadkiem w "ciapkach"? (tzn. w cudzysłowach).
Najlepiej chyba jakby te stringi były zdeklarowane gdzieś jako progmem.

czyli coś w tym stylu

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

a w ifach
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i tak dalej. Na początek można też spróbować ze zwykłym strcmp np.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

co do kodu nadajnika - to niestety nie mam doświadczenia :-)


PS. Jeśli faktycznie porównanie miałoby być z pojedynczym znakiem o kodzie 95, to wtedy dla tego kodu string nie powinien być "95" tylko odpowiedni znak ASCII, ale zokończony terminującym zerem, czyli w "ciapkach"
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


lub trzeba by użyć funkcji strncmp_P z podaną długością 1
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 19:45 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

banita 17 napisał(a):
Cześć,

odniosę się, przynajmniej na razie, do tego zdania:
"W przypadku gdy wyślę np. 95 - program przeskakuje po ifach, jakby losowo (pewnie nie losowo, ale ja nie mogę zauważyć prawidłowości)."

Co to znaczy losowo ? Korzystasz z debuggera rozumiem ? Używasz tego na stmie ? nie masz przypadkiem włączonej optymalizacji przy kompilacji ?



Cześć,
Dziękuję za odpowiedź.
Tak, używam debuggera ( Atmel-ICE). To niejako samoczynnie odpowiada na kolejne pytanie - używam tego w AVR- konkretniej ATmega 32u4.
Pracuję w AVR studio. Nie wiem czy mam włączoną optymalizację - faktycznie sprawdzę i przetestuję.

------------------------ [ Dodano po: kilkunastu sekundach ]

moscow napisał(a):
goslawen napisał(a):
[...]
Problemem jest natomiast (tak mi się wydaje) nie zrozumienie przeze mnie funkcji parse_nrf_data.
Nie za bardzo wiem jak dużo mogę kodu zawierającego tą bibliotekę udostępniać, dlatego dam tylko wycinki.

W miejscu przykładu wstawiłem: (odbiornik)

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

[...]
W/g dokoumentacji "The strcmp_P() function is similar to strcmp() except that s2 is pointer to a string in program space."

Jeśli dobrze rozumiem - następujący zapis
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

prawdopodobnie porównuje bufor 'buf' z przypadkową zawartością pamięci programu

Czy liczba 98 nie powinna być przypadkiem w "ciapkach"? (tzn. w cudzysłowach).
Najlepiej chyba jakby te stringi były zdeklarowane gdzieś jako progmem.

czyli coś w tym stylu

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

a w ifach
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i tak dalej. Na początek można też spróbować ze zwykłym strcmp np.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

co do kodu nadajnika - to niestety nie mam doświadczenia :-)


PS. Jeśli faktycznie porównanie miałoby być z pojedynczym znakiem o kodzie 95, to wtedy dla tego kodu string nie powinien być "95" tylko odpowiedni znak ASCII, ale zokończony terminującym zerem, czyli w "ciapkach"
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


lub trzeba by użyć funkcji strncmp_P z podaną długością 1
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Dziękuję za obszerną poradę, chwilę mi zajmie jej przeanalizowanie. Wrócę mam nadzieję z rozwiązaniem problemu lub co mniej optymistyczne z prośbą o kolejne rady.
Postaram się odpowiedzieć jeszcze dzisiaj.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 20:03 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Nie wiem jak jest w TrueStudio niemniej w konsoli podczas kompilacji powinieneś mieć jakieś logi (tylko się domyślam) i tam w opcjach kompilatora gdzieś powinien być zapis "-O0" jeżeli jest inny tzn. np -O1 to może być przyczyną 'dziwnie' zachowującego się debuggera. Przykładowy link z konsoli w którym widać wybraną optymalizację:

Obrazek

a co do reszty problemów to tak jak mówił użytkownik 'moscow' powinieneś porównywać stringi co znaczy ciągi znaków. Zakładam, że wiesz czym różni się taki zapis:
char string[] = "a";

od takiego zapisu:
char znak[1];
znak[0] = 'a'

W tym przypadku string przechowuje dwa znaki: znak litery 'a' oraz znak końca łańcucha znaków tzn NULL natomiast znak[0] przechowuje jedynie znak litery 'a'.

Ponadto funkcja "strcmp_P" porównuje dwa ciągi znaków przy czym zakłada, że jeden z nich znajduje się w pamięci Flash (PROGMEM) myślę, że na to również powinieneś zwrócić uwagę



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 20:10 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W taki użyciu niestety zawsze mi wchodzi do każdego IFa.
Zadeklarowałem:
const char str_95 PROGMEM = '_';
const char str_97 PROGMEM = 'a';
const char str_98 PROGMEM = 'b';

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 20:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Bo funkcja strcmp_P() porównuje stringi tzn ciągi znaków. Brakuje jej znaku NULL na końcu. Spróbuj tak:

const char str_95[] PROGMEM = "_";
const char str_97[] PROGMEM = "a'';
const char str_98[] PROGMEM = "b";


Jeszcze jedna sprawa. Przy Twoich wcześniejszych próbach tzn:

const char str_95 PROGMEM = '_';
const char str_97 PROGMEM = 'a';
const char str_98 PROGMEM = 'b';

powinieneś użyć dodatkowo znaku '&' przy wywołaniu funkcji strcmp_P() tzn: if (!strncmp_P(buf, &str_97, 1)); z uwagi na to, że funkcja strcmp_P przyjmuje wskaźniki. tzn adres do komórki pamięci gdzie się znajduje ciąg znaków.

w przypadku zmiennej 'buf' znaku '&' nie trzeba używać bo jest to tablica a w języku C nazwa tablicy bez żadnych innych znaków jest adresem na jej pierwszy element. (buf oraz &buf[0] jest tożsame)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 20:30 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

Faktycznie miałem włączoną optymalizację.
Ustawia się ją w drzewku "solution explorer" -> "properties -> toolchain -> optimalizer -> None (-O0).
Niestety niewiele to zmieniło.

Po wprowadzeniu zmian w
const char str_95[] PROGMEM = "_";
const char str_97[] PROGMEM = "a'';
const char str_98[] PROGMEM = "b";

nadal debugger "odwiedza" każdy z IFów.
Zakładam, że teraz jest poprawnie po stronie odbiornika, więc może jakiś podobny problem jest z nadajnikiem?

Przyznam szczerze, że do tej pory wydawało mi się, że rozumiem różnice pomiędzy większością zapisów dotyczących np. char[1] itp, ale gdy przyszło do praktyki zaczęło mi się strasznie wszystko mieszać.

------------------------ [ Dodano po: 14 minutach ]

Dla sprawdzenia i upewnienia się:

char znak[1]; // tablica 1 "miejscowa"
znak[0] = 'a' // "miejsce" zerowe w tablicy

'a' -> to po prostu a
"a" -> to a + \0
string[] "a" - > a+\0

Zgadza się?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 20:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Optymalizacja zmieniła teraz tyle, że podczas debugowania nie ma problemów ze 'skaczącym' debuggerem ale nie mogła ona mieć wpływu na sposób wykonywania się programu. Nie mniej polecam debugować programy bez optymalizacji :P

Jest możliwość, żebyś sprawdził co znajduje się w zmiennej buf ? za pomocą debuggera oczywiście.

Bo szczerze mówiąc to wydaje się, że powinno to działać. Ewentualnie skompiluj sobie prosty/pusty program w w którym zrobisz coś takiego:


char str_97[] PROGMEM = "a";
char buf[] = "a"

if (!strncmp_P(buf, str_97, 1));
{
// zrób coś np zapal diodę
}
else
{
//zalap inną diodę
}

Powinna się zapalić dioda z pierwszej klamerki jeżeli wszystko działa tak jak sobie wyobrażamy. Jeżeli nie zadziała zgodnie z oczekiwaniami no to wtedy trzeba będzie to dalej szlifować :D

------------------------ [ Dodano po: 4 minutach ]

goslawen napisał(a):
Faktycznie miałem włączoną optymalizację.
Dla sprawdzenia i upewnienia się:

char znak[1]; // tablica 1 "miejscowa"
znak[0] = 'a' // "miejsce" zerowe w tablicy

'a' -> to po prostu a
"a" -> to a + \0
string[] "a" - > a+\0

Zgadza się?


Zgadza się. Aczkolwiek prawdę mówiąc to jak spojrzysz sobie na funkcję int strncmp_P(const char * s1,const char * s2, size_t n ) to ona sprawdza określoną liczbę znaków - określasz to parametrem size_t n. Wiec w tym przypadku nie ma wielkiego znaczenia czy porównujesz string do stringa czy string do tablicy ze znakami ale bez nulla na końcu. Ale gdybyś nie miał tutaj parametru size_t n to byłoby to niebezpieczne porównywać string do tablicy ze znakami/znakiem()bez nulla (w niektórych przypadkach mogłoby działać w innych by się wykrzaczyło z hukiem)


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 20:56 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

banita 17 napisał(a):

Jest możliwość, żebyś sprawdził co znajduje się w zmiennej buf ? za pomocą debuggera oczywiście.



W zmiennej buf aktualnie znajduje się:

0x0103 // wysyłam b

i teraz żeby było śmieszniej

0x0103 // wysylam a

teraz juz zdębiałem...

str_95 =0x00ac
str_97 =0x00ae
// debugger wydaje się działać poprawnie...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 21:07 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Jesteś pewien, że na debuggerze podglądasz wartość zmiennej a nie adres w pamięci pod jakim zmienna się znajduje ?
Jak patrzysz na to:

str_95 =0x00ac
str_97 =0x00ae

to wcale nie wydaje mi się, żeby to był dobry wynik. Jak włączysz sobie tablicę ASCII to okaże się, że litera 'a' ma w decu wartość 97 a w hexie wartość 0x61 co nijak ma się do wartości 0x00ae. Upewnij się więc, że sprawdzasz faktycznie wartości zmiennych a nie adresy w pamięci pod jakimi te zmienne się znajdują



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 21:10 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

Nie wiedziałem, że mogę wykonać to źle :)
Po prostu nakierowuję myszkę na zmienną i wyświetla się wartość.
W przypadku innych zmiennych tak to właśnie działa.
Można to podejrzeć inaczej?

watch 1:

name | Value | Type
buf | 0x0103 | char*{data}@0x0acb ([R28]+1)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 21:18 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

heheheh.. No tak. Śmieszna sprawa. Czym jest wskaźnik ? Wskaźnik to jest adres w pamięci programu. Czyli jednym słowem wartości wskaźnika to jest adres w pamięci. Czyli jak doczytujesz debuggerem zmienną 'buf' która jest zdefiniowana jako tablica np char buf[5] to debugger poda ci wartość czyli adres. Jeżeli chcesz podejrzeć jakie znaki znajdują się w tym buforze to musisz zrobić tak:

char pierwszyZnakBufora = buf[0];
char drugiZnakBufora = buf[1];

i teraz dopiero debuggerem/myszką najechać na zmienne 'pierwszyZnakBufora ' i 'drugiZnakBufora ' i wtedy dowiesz się jakie znaki faktycznie tam się znajdują. Analogicznie ze zmiennymi w pamięci PROGMEM.

Mam nadzieję, że rozumiesz ? Jeżeli za słabo to wytłumaczyłem to śmiało mów bardziej się wysilę :D


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 21:28 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

znak0 = buf[0]; - wartość 192
znak1 = buf[1]; - wartość 10
znak2 = buf[2]; - wartość 148
znak3 = buf[3]; - wartość 110
znak4 = buf[4]; - wartość 200

Przez przypadek zauważyłem też, że zdarza się "wylecieć" programowi z powrotem do main().

Po chwili - nadajnik ciągle wysyła -> f

znak0 = buf[0]; - wartość 192
znak1 = buf[1]; - wartość 7
znak2 = buf[2]; - wartość 12
znak3 = buf[3]; - wartość 148
znak4 = buf[4]; - wartość 108



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 21:39 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Hmmm... czyli jednym słowem w zmiennej buf znajduje się coś czego zupełnie się nie spodziewamy. Wydaje mi się, że musisz 'pójść' z debuggerem wcześniej tzn przed wywołanie funkcji: void parse_nrf_data ( char * buf, uint8_t len ) i sprawdzić czy tam w którejś ze zmiennych które później przekazujemy do tablicy buff jest to czego byśmy się spodziewali. Bo liczba 192 jest poza zakresem tablicy ASCII.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 22:04 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

W związku z tym, że sprawdzenie mojego problemu rozbija się o miejsca w kodzie Mirka napisałem wiadomość prywatną, żeby nie udostępniać wycinków biblioteki.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 22:46 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27224
Lokalizacja: Szczecin
Pomógł: 1041

No i tak to bywa - debuger nie załatwi sam pewnych spraw za programistę ... Tak poczytałem ten wątek ... i aż troszkę strach bierze gdy kolega autor wątku pisze np takie coś:

Cytuj:
char str_95 PROGMEM = '_';
strncmp_P(buf, str_95, 1);


Po prostu tragedia - proponuję jednak wrócić do podstaw i zastanowić się co to jest C-String, czyli string w C ... bo to nigdy w życiu nie jest stringiem, i jeśli korzystanie z funkcji strncmp_P() lub podobnych powoduje wykładanie się procka do góry nogami i jak kolega pisze powrót do main() ;) albo losowe działanie IF'ów to - .... to panie kochany ....

1. to nie jest żaden powrót do main tylko "pierdyknięcie stosu" bo próbujesz porównywać nie stringa tylko np pół pamięci FLASH zanim funkcja porównująca dojdzie do końca tego rzekomego stringa czyli do zera

2. to nie jest żadne losowe działanie IFów tylko mega PASKUDNY niestety czy tego chcesz czy nie babol programisty, który nie wie co to jest STRING w języku C

i na to nie pomoże żaden DEBUGER jak widać - bo już od dłuższego czasu widzę walczysz z debugerem i wciąż ten sam efekt.

---------------------------------

Przypominam już w Bluebooku masz napisane co to jest C-String .... otóż taki STRING MUSI być Qurczę zakończony znakiem NULL czyli zerem

to:

Cytuj:
char str_95 PROGMEM = '_'; // to zajmie JEDEN koci bajt !!!


nie jest żaden Qurdę string tylko jakaś definicja stałej dosłownej - w tym wypadku jednego znaku i nie ZAKOŃCZONA zerem rozumiesz ? Już pomijam że brakuje specyfikatotra const

TO jest STRING

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


no to są PODSTAWY PODSTAW z Bluebooka i bardzo dobrze tam opisane. Jeśli się tego nie zrozumie - to się będzie miało do czynienia z GIGANTYCZNYMI KASZANAMI w kodzie i dlatego tak dużo miejsca temu poświęciłem. W języku C - trzeba zrozumieć co to jest STRING.

------------------------ [ Dodano po: 3 minutach ]

Stałe dosłowne, literały są często umiejscawiane w pamięci FLASH przez kompilator na samym początku przed kodem programu. Przez co za takim literałem nie zakończonym zerem mogą być kolejne znaki i kolejne aż w końcu kod programu i długo może nie być zera ... próba używania funkcji do operacji na stringach - którym daje się do jedzenia TAK NIESTRAWNE danie w postaci sztucznych zatrutych stringów - spowoduje, że procek dostanie niestrawności i wymiotów

a na poważnie to i stos może się przekręcić aby na końcu zresetować procka - a tobie się wydaje, że program wraca w jakiś dziwny tajemniczy sposób do main(). Nie - nie wraca tylko następuje najzwyklejszy okrutny restart

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 sie 2019, o 23:16 
Offline
Nowy

Dołączył(a): 03 sty 2014
Posty: 19
Pomógł: 0

Mirku,

Jak wcześniej możesz zauważyć w moim kodzie nie było zupełnie

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


czy

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Pisząc te kody koledzy wyjaśniali mi jakie mogą być potencjalne problemy.

Dziękuję bardzo, bo trochę mi się to wszystko poukładało, a takie przykłady pozwalają dopiero to zrozumieć. Bez prób, często tych najgłupszych nigdy nie jestem w stanie czegoś zrozumieć do końca.

Niestety mimo użycia

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


program dalej zachowuje się dziwnie, czego nie jestem w stanie zrozumieć.

Jak zauważysz wyżej, po sugestii kolegi w buf[x] pojawiają się dziwne wartości, więc albo coś mocno sknociłem w kodzie w innym miejscu albo mam np.wadliwe nrf.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 sie 2019, o 05:09 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27224
Lokalizacja: Szczecin
Pomógł: 1041

goslawen napisał(a):
program dalej zachowuje się dziwnie, czego nie jestem w stanie zrozumieć.

No to twoim zadaniem jest WYIZOLOWAĆ problem. Czyli ? ...

Skróć go tak jak się da - pokaż tylko ten fragment który ci nie działa i opisz co to znaczy, że zachowuje się dziwnie - bo wybacz ale to bez sensu - zadawać pytanie na forum typu:

"Panowie program zachowuje mi się dziwnie - pomożecie?"

Po tym co robisz widać, że nie ma to nic a nic wspólnego z jakimś NRF ... porzuć zatem ten projekt na chwilę, załóż nowy i wymyśl sobie prosty test do porównywania stringów - bo widać, że zdaje się z tym masz największy problem.

Do tego wystarczy kawałek wyświetlacza LCD a zdaje się masz zestawik ATB to nie powinno być kłopotu napisać jakiś mały fragment kodu do przetestowania .... i zamiast też pisać, że

" ... mimo użycia czegoś tam - nadal mi nie działa"

Panie kod swój pokazuj jeśli wprowadzasz poprawki - mówię o tym testowym ok? No niestety tego też trzeba się nauczyć - to PODSTAWA PODSTAW jeśli chodzi o programowanie

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 sie 2019, o 08:42 
Offline
Użytkownik

Dołączył(a): 18 sie 2019
Posty: 69
Zbananowany użytkownik

Pomógł: 2

banita 17 napisał(a):
Nie mniej polecam debugować programy bez optymalizacji :P

Nie jest to dobry pomysł. Niektóre operacje ne peryferiach nie będą działać, bo pomiędzy zapisami będzie pauza większa niż 4 cykle zegara. Nie da się wiec zapisać EEPROM, ustawiać watchdoga, itp.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 sie 2019, o 09:59 
Offline
Użytkownik

Dołączył(a): 09 lip 2019
Posty: 106
Pomógł: 10

mirekk36 napisał(a):
No i tak to bywa - debuger nie załatwi sam pewnych spraw za programistę ... Tak poczytałem ten wątek ... i aż troszkę strach bierze gdy kolega autor wątku pisze np takie coś:

Cytuj:
char str_95 PROGMEM = '_';
strncmp_P(buf, str_95, 1);


Po prostu tragedia - proponuję jednak wrócić do podstaw i zastanowić się co to jest C-String, czyli string w C ... bo to nigdy w życiu nie jest stringiem, i jeśli korzystanie z funkcji strncmp_P() lub podobnych powoduje wykładanie się procka do góry nogami i jak kolega pisze powrót do main() ;) albo losowe działanie IF'ów to - .... to panie kochany .... [...[

Tak gwoli ścisłości, to akurat ta dokładnie konstrukcja zadziała (przy założeniu, że zawartość buf[] jest zgodna z oczekiwaniami) i nie spowoduje wyłożenia się procka.
To jest strncmp (ograniczony do jednego bajtu ostatnim argumentem), a nie strcmp.
Co prawda wygląda na to, że akurat strncmp_P jest napisane w asemblerze, ale typowa implementacja zwykłego strncmp wygląda mniej więcej tak jak niżej i sprawdzenie końca ciągu znaków odbywa się explicite tylko dla s1
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Czy jej użycie ma sens - to inna historia. Zasugerowałem ją, bo nie wiedziałem z pierwszego postu o co dokładnie chodzi... czy porównywany ma być pojedynczy znak, czy para znaków.
Dla pojedynczego znaku i przy pewności, że chodzi porównanie będzie dotyczyło pierwszego znaku w buforze - pewnie wystarczyłoby zwykłe
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Co do pozostałych uwag - całkowicie się zgadzam :-) Niemniej z tego co Koledzy już zauważyli - problem jest raczej po stronie zawartości pamięci wskazywanej przez zmienną buf a nie samych porównań :-)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 sie 2019, o 10:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 24 mar 2012
Posty: 72
Pomógł: 5

Semi napisał(a):
banita 17 napisał(a):
Nie mniej polecam debugować programy bez optymalizacji :P

Nie jest to dobry pomysł. Niektóre operacje ne peryferiach nie będą działać, bo pomiędzy zapisami będzie pauza większa niż 4 cykle zegara. Nie da się wiec zapisać EEPROM, ustawiać watchdoga, itp.


Ciekawa teza aczkolwiek ostatecznie uważam, że nie masz racji. Masz jakieś doświadczenia z tym związane ? Jakaś opis który by to potwierdził ? (Jak coś to nie jestem złośliwy tylko ciekawy, chętnie się czegoś nowego dowiem :) )


A co do autora wątku to nie musimy uciekać na prv. Będziesz musiał sam trochę popracować ;) Możesz wstawić linijkę z wywołaniem funkcji: void parse_nrf_data ( char * buf, uint8_t len ) oraz linijkę w której pokazałbyś skąd dane biorą się w buforze którego wskaźnik przekazujesz do funkcji parse_nrf_data do argumentu 'buf'.

I tak jak Mirek powiedział musisz zjeść tego słonia po kawałku tzn krok po kroku analizuj co i gdzie. Masz wyświetlacz, diody + do tego debugger to naprawdę spore możliwości. Musisz iść w stronę 'źródła' danych bufora 'buf' i sprawdzić w którym kroku dysponujesz danymi których faktycznie oczekujesz



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 sie 2019, o 14:33 
Offline
Użytkownik

Dołączył(a): 18 sie 2019
Posty: 69
Zbananowany użytkownik

Pomógł: 2

banita 17 napisał(a):
Semi napisał(a):
banita 17 napisał(a):
Nie mniej polecam debugować programy bez optymalizacji :P

Nie jest to dobry pomysł. Niektóre operacje ne peryferiach nie będą działać, bo pomiędzy zapisami będzie pauza większa niż 4 cykle zegara. Nie da się wiec zapisać EEPROM, ustawiać watchdoga, itp.


Ciekawa teza aczkolwiek ostatecznie uważam, że nie masz racji. Masz jakieś doświadczenia z tym związane ? Jakaś opis który by to potwierdził ? (Jak coś to nie jestem złośliwy tylko ciekawy, chętnie się czegoś nowego dowiem :) )

Skompiluj program bez optymalizacji i zobacz rozwinięcie asm.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 7 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO