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



Teraz jest 30 sty 2026, o 13:28


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 
Autor Wiadomość
PostNapisane: 22 gru 2014, o 22:55 
Offline
Użytkownik

Dołączył(a): 01 mar 2014
Posty: 117
Lokalizacja: Kraków
Zbananowany użytkownik

Pomógł: 1

Od razu do rzeczy.
W projekcie mam m.in. dwa pliki nagłówkowe, każdy z nich zawiera dwie tablice po 19200 elementów bajtowych (musiałem rozbić na dwie tablice, bo 38400 elementów dla AVRa to za dużo). Generalnie są to 2 obrazy monochromatyczne 640x480:

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

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


Wykorzystuję je w ten sposób:

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


Jeden z obrazów wyświetla się na LCD prawidłowo, ale drugi (testowo przełączają się cyklicznie co 3 sekundy - zmienna scr_switch) zawiera kawałek pierwszego - zawsze ten sam fragment i w tym samym miejscu. Nie jest to wina błędu w tablicach - zrobiłem dwa komplety tablic z identyczną zawartością - to samo. Ale kiedy zostawię tylko jedną parę tablic i przełączam tak (czyli przełączam to samo):

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

To wszystko jest OK. Wnioskuję z tego, że sama metoda zapisu danych do LCD jest w porządku.

Czy możliwe jest, żeby kompilator/procek nie radził sobie z tak dużą ilością danych i coś mieszał? Z drugiej strony to tylko 77660 bajtów to tylko 60% FLASHu.

Mam pomysł na jeszcze jeden test, ale nie wiem, jak sprawić, żeby kompilator zapisał do wsadu również nieużywane tablice. Będę przełączał tylko jeden obraz (ostatni przykład), ale do pamięci wrzucę oba. Sprawdzę czy ilość danych ma wpływ na działanie.

------------------------ [ Dodano po: 20 minutach ]

kudzu napisał(a):
Mam pomysł na jeszcze jeden test, ale nie wiem, jak sprawić, żeby kompilator zapisał do wsadu również nieużywane tablice. Będę przełączał tylko jeden obraz (ostatni przykład), ale do pamięci wrzucę oba. Sprawdzę czy ilość danych ma wpływ na działanie.


I już wiem. Szczerze mówiąc bardzo mnie to zaskoczyło! Otóż, jeżeli we wsadzie umieszczę oba obrazy (obie pary tablic), ale "przełączam" (przepisuję do LCD) ciągle ten sam obraz, to w przypadku jednej pary tablic jest dobrze, a drugiej źle.
I jeszcze jedno spostrzeżenie - jeżeli kolejność dołączania plików nagłówkowych ma odzwierciedlenie w kolejności danych we wsadzie, to problemy mam z pierwszym plikiem nagłówkowym. Zamiana kolejności #include zmienia sytuację.

------------------------ [ Dodano po: 23 minutach ]

Cytuj:
I jeszcze jedno spostrzeżenie - jeżeli kolejność dołączania plików nagłówkowych ma odzwierciedlenie w kolejności danych we wsadzie, to problemy mam z pierwszym plikiem nagłówkowym.

Tu sprostowanie, bo robiłem już próby z obiema parami tablic w jednym pliku - te same błędy. Czyli nie jest to wina plików nagłówkowych, a stricte tablic we wsadzie:/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 gru 2014, o 00:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 kwi 2014
Posty: 438
Lokalizacja: Zambrów
Pomógł: 22

Ja to się nie znam, ale może przyczyna tkwi w funkcji odczytywania danych z pamięci FLASH. Mianowicie powyżej 64kB stosować należy funkcję pgm_read_byte_far, a poniżej pgm_read_byte_near co jest to samo co pgm_read_byte. Może część obrazka jest w tej dalszej części, a przez to, że adres użyty w funkcji pgm_read_byte jest krótszy niż w tej drugiej z "far" to wskazuje na część obrazka pierwszego we wcześniejszej części pamięci.

Niestety nie miałem jeszcze w praktyce z tym do czynienia więc nie wiem czy to to akurat jest problemem i co gorsza jak sprawdzić jaką funkcję użyć :D


Autor postu otrzymał pochwałę

_________________
.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 gru 2014, o 15:44 
Offline
Użytkownik

Dołączył(a): 01 mar 2014
Posty: 117
Lokalizacja: Kraków
Zbananowany użytkownik

Pomógł: 1

Kurcze, nie znałem tego problemu... Nie wiem czy tu leży problem, ale stanowczo muszę o tym poczytać:) Dzięki!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 gru 2014, o 21:21 
Offline
Użytkownik

Dołączył(a): 01 mar 2014
Posty: 117
Lokalizacja: Kraków
Zbananowany użytkownik

Pomógł: 1

misiulu napisał(a):
powyżej 64kB stosować należy funkcję pgm_read_byte_far

I tu chyba właśnie leży problem. Niestety zmiana wprost pgm_read_byte na .._far powoduje wykrzyczenie przez kompilator ostrzeżenia:
Cytuj:
cast from pointer to integer of different size [-Wpointer-to-int-cast]

Zignorowanie ostrzeżenia sprawia, że na ekranie pojawia się tylko ten nieprawidłowy fragment obrazka, a pozostała, prawidłowa część jest niewidoczna.
Nie potrafię na razie poprawnie zmodyfikować kodu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 gru 2014, o 23:18 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 kwi 2014
Posty: 438
Lokalizacja: Zambrów
Pomógł: 22

No to przynajmniej jakiś postęp :) Teraz trzeba by tylko wykombinować jak sprawdzić i automatycznie użyć odpowiedniej funkcji w zależności od adresu.

Nie wiem czy to zadziała, ale argumentem funkcji pgm_read_byte jest przecież adres w pamięci FLASH. Więc może wystarczy sprawdzić czy ten adres jest większy niż "wartość 64kB" i użyć wtedy funkcji pgm_read_byte_far, a jeżeli mniejszy to wtedy użyć funkcji pgm_read_byte.

Jednak nie wiem dokładnie jaka jest to graniczna wartość. Chyba dla każdego mikrokontrolera będzie inna. Trzeba by zobaczyć w datasheecie od jakiego adresu zaczyna się pamięć FLASH w twoim przypadku ATmedze 128 i zobaczyć jaki będzie adres po tych 64kB od początku FLASH. Metodą prób i błędów patrząc na obrazek czy jest wyświetlany poprawnie może uda się dopasować adres do porównania i wtedy będzie dokładnie wiadomo jak to obliczać w przyszłości :D

------------------------ [ Dodano po: 18 minutach ]

kudzu napisał(a):
misiulu napisał(a):
powyżej 64kB stosować należy funkcję pgm_read_byte_far

I tu chyba właśnie leży problem. Niestety zmiana wprost pgm_read_byte na .._far powoduje wykrzyczenie przez kompilator ostrzeżenia:
Cytuj:
cast from pointer to integer of different size [-Wpointer-to-int-cast]

Zignorowanie ostrzeżenia sprawia, że na ekranie pojawia się tylko ten nieprawidłowy fragment obrazka, a pozostała, prawidłowa część jest niewidoczna.
Nie potrafię na razie poprawnie zmodyfikować kodu.


Bo teraz sam doczytałem, że operator wyłuskania adresu "&" działa tylko do 16 bitów. Spróbuj w funkcji pgm_read_byte_far użyć pgm_get_far_address (zmienna). Może wtedy kompilator przestanie krzyczeć i wszystko zacznie działać przynajmniej w części ;)

_________________
.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2015, o 13:55 
Offline
Użytkownik

Dołączył(a): 01 mar 2014
Posty: 117
Lokalizacja: Kraków
Zbananowany użytkownik

Pomógł: 1

misiulu napisał(a):
Bo teraz sam doczytałem, że operator wyłuskania adresu "&" działa tylko do 16 bitów. Spróbuj w funkcji pgm_read_byte_far użyć pgm_get_far_address (zmienna). Może wtedy kompilator przestanie krzyczeć i wszystko zacznie działać przynajmniej w części ;)

Spróbowałem tak:

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

jak również pośrednio przez dodatkowe zmienne, ale za każdym razem w konsoli pojawia mi się:

Cytuj:
./eg9018c.o: In function `memory_fill':
eg9018c.c:(.text.memory_fill+0x22): undefined reference to `r30'
eg9018c.c:(.text.memory_fill+0x24): undefined reference to `r30'
eg9018c.c:(.text.memory_fill+0x26): undefined reference to `r30'
eg9018c.c:(.text.memory_fill+0x34): undefined reference to `r30'
eg9018c.c:(.text.memory_fill+0x36): undefined reference to `r30'
./eg9018c.o:eg9018c.c:(.text.memory_fill+0x38): more undefined references to `r30' follow
collect2.exe: error: ld returned 1 exit status
make: *** [Terminal.elf] Błąd 1


Podejrzałem sobie asemblera i wychodzi na to, że ostatnia tablica połową jest przed 64k, a połową za.
Nie miałem pojęcia, że mogą pojawić się tak duże problemy z odczytem danych z flasha:/

Jeszcze dla unaocznienia problemu wklejam zdjęcie:

Obrazek

------------------------ [ Dodano po: 22 minutach ]

http://www.avrfreaks.net/forum/controller-jumps-wrong-pgm-array - jakbym to pisał...

------------------------ [ Dodano po: 47 minutach ]

Pierwszy sukces! Działa taka konstrukcja:

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

Problem jest tylko taki, że nie rozpoznaje danych poniżej 64k. Kwestia czasu...:D



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2015, o 17:00 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 kwi 2014
Posty: 438
Lokalizacja: Zambrów
Pomógł: 22

No to super, że są postępy :)

Ja niestety nie mam akurat na wyposażeniu procka > 64kB Flash więc nie mogę Ci pomóc w praktyce :(

Ale jak Ci się uda to dla potomnych będzie i na pewno się przyda hehe :D

kudzu napisał(a):
Pierwszy sukces! Działa taka konstrukcja:

byte_a = pgm_read_byte_far(0x10000 | (uint16_t)&lcd_test_screen_1a[k]);


Problem jest tylko taki, że nie rozpoznaje danych poniżej 64k. Kwestia czasu...:D


A zobacz co zwraca te całe wyrażenie przedstawione wyżej poniżej 64Kb. Może jest to jakaś stała wartość. Wtedy jak ona występuje to dać odczyt po staremu, a resztę puścić z tym co działa powyżej 64k.

_________________
.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2015, o 19:19 
Offline
Użytkownik

Dołączył(a): 01 mar 2014
Posty: 117
Lokalizacja: Kraków
Zbananowany użytkownik

Pomógł: 1

GET_FAR_ADDRESS macro has many limitations. It requires a compile-time known constant address (that's the reason to fail when the array element is accesed using a variable index) and operates at run-time (that's the reason why GET_FAR_ADDRESS it's not allowed to be used in variable initializations for const, flash, and generally for any static storage).


Wspomniane makro GET_FAR_ADDRESS to to samo, co oryginalne pgm_get_far_address.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2015, o 22:38 
Offline
Użytkownik

Dołączył(a): 01 mar 2014
Posty: 117
Lokalizacja: Kraków
Zbananowany użytkownik

Pomógł: 1

SUKCES!:D

Zrobiłem to tak:

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


Trochę mało wydajne, ale działa! Jakież to fantastyczne, że człowiek potrafi się z takich małych sukcesów cieszyć jak głupi;)
I właśnie skończyło mi się w butelce piwo... Kormoran Jasny (mocno chmielony) - przyzwoity;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 sty 2015, o 23:04 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 19 kwi 2014
Posty: 438
Lokalizacja: Zambrów
Pomógł: 22

Brawo ! Gratulacje !!! :>

Teraz przynajmniej już jest rozwiązanie :)

W przyszłości może ktoś je zoptymalizuje hehe, ale ważne że jest działająca podstawa :D

_________________
.



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: 10 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 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