logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak poprawnie użyć pamięci FLASH do obsługi tekstów?

trebuch1 01 Lut 2023 11:17 540 14
  • #1 20416443
    trebuch1
    Poziom 26  
    Proszę o pomoc. Używam AVR Studio7 i pierwszy raz próbuję skorzystać z pamięci programu do zapisania i odczytów tekstów. Moje dotychczasowe próby kończyły się niepowodzeniem. Poniższy kod kompiluje się bez błędów ale z odczytem było już tylko źle.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zakładam że wyżej mam zdefiniowane teksty oraz mam zadeklarowaną tablicę wskaźników to tych tekstów.
    Proszę o funkcję zwracającą wskazany tekst do bufora, oraz jak powinna być prawidłowo użyta.
  • #2 20416510
    excray
    Poziom 41  
    Zapomnij o PROGMEM. Użyj __flash:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 20417145
    trebuch1
    Poziom 26  
    \Test_pgm\main.c(27,6): error: '__flash' specified for auto variable 'array'
    const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };
    ^


    Niestety kompilator zwraca mi powyższy błąd. Nie zna __flash
  • #4 20417204
    tmf
    VIP Zasłużony dla elektroda
    trebuch1 napisał:
    Nie zna __flash

    Na podstawie czego tak uważasz? Masz tylko komunikat, że __flash nie może być użyty ze zmiennymi automatycznymi - czyli definicję wyrzuć poza funkcję i będzie ok.
  • #5 20417288
    jvoytech
    Poziom 21  
    jak nie chcesz wyrzucić poza funkcję to dodaj "static"
  • #6 20417443
    trebuch1
    Poziom 26  
    Bardzo proszę dokończcie kod a wezmę go wprost do testów.
    Celem jest aby zwracał do bufora znakowego wskazany tekst z FLASH.
    Ja ciągle błądzę.
  • Pomocny post
    #7 20417447
    excray
    Poziom 41  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 20417539
    trebuch1
    Poziom 26  
    Dla kodu :

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Mam taki stan komunikatów:
    Build succeeded.
    ------ Rebuild All started: Project: Test_pgm, Configuration: Debug AVR ------
    Build started.
    Project "Test_pgm.cproj" (default targets):
    Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
    Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project "C:\Users\......Test_pgm\Test_pgm.cproj" (target "Build" depends on it):
    Task "RunCompilerTask"
    Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
    C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 8 --output-sync
    Building file: .././main.c
    Invoking: AVR/GNU C Compiler : 5.4.0
    C:\Users\......\Test_pgm\main.c(10,9): error: expected '=', ',', ';', 'asm' or '__attribute__' before 'const'
    _flash const char txt[] = {"JAKIS NAPIS"};
    ^
    make: *** [main.o] Error 1
    "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -x c -funsigned-char -funsigned-bitfields -DDEBUG -DF_CPU=8000000L -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\include" -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega32a -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\gcc\dev\atmega32a" -c -std=gnu99 -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.c"
    C:\Users\.....Test_pgm\Debug\Makefile(88,1): error: recipe for target 'main.o' failed
    make: *** Waiting for unfinished jobs....
    Building file: .././lcd.c
    Invoking: AVR/GNU C Compiler : 5.4.0
    "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -x c -funsigned-char -funsigned-bitfields -DDEBUG -DF_CPU=8000000L -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\include" -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega32a -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.6.364\gcc\dev\atmega32a" -c -std=gnu99 -MD -MP -MF "lcd.d" -MT"lcd.d" -MT"lcd.o" -o "lcd.o" ".././lcd.c"
    Finished building: .././lcd.c
    Done executing task "RunCompilerTask" -- FAILED.
    Done building target "CoreBuild" in project "Test_pgm.cproj" -- FAILED.
    Done building project "Test_pgm.cproj" -- FAILED.

    Build FAILED.
    ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
  • #9 20417544
    excray
    Poziom 41  
    Ten "flash" to powinien mieć przed sobą dwa znaki "_" - __flash
  • #10 20417562
    trebuch1
    Poziom 26  
    Dziękuję, to było zwykłe niedowidzenie. Poprawiłem i skompilowało się poprawnie.
  • #11 20421599
    trebuch1
    Poziom 26  
    Załączony przykład zadziałał mi poprawnie.
    W funkcji pisz_na_lcd (__flash const char *linia) należało użyć prefiksu __flash.
    Bez niego funkcja zwracała bzdury.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #12 20421604
    tmf
    VIP Zasłużony dla elektroda
    @trebuch1 A tak ogólnie to lepiej użyj nowych AVR, np. ATMega480x lub AVR Dx, Ex - one mają płaską przestrzeń adresową i nie jest potrzebne używanie żadnych modyfikatorów.
  • #13 20422298
    trebuch1
    Poziom 26  
    Poprzedni mój przykład działa poprawnie pod warunkiem że cały jego tekst
    zawarty jest w jednym pliku głównym. Jeśli wywołanie funkcji piszącej do lcd
    nastąpi w innym pliku, to argument funkcji będący zarazem wskaźnikiem do tekstu flash nie zostanie rozpoznany. Obszedłem to poprzez zdefiniowanie
    tekstów flash i makr w jednym pliku "flash.h" (nazwa dowolna ale jako *.h).
    Tu należy koniecznie użyć składni tablicowej txt a nie wskaźnikowej *txt.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Po dołączeniu tego pliku do całości, mogę w dowolnym miejscu programu
    używać zdefiniowanych makr zwracających teksty z pamięci flash.
    Dla mnie jest to w zupełności akceptowalne. Jest sens bawić się w zapisy do flash o ile są one wielobajtowe, aby tworzone w RAM ich wskaźniki zawierały o wiele mniej miejsca niż te same teksty zapisane wprost do RAM.
    Pytanie: czy w omawianym przypadku jest jakaś możliwość zapisania we flash tablicy wskaźników do tekstów zapisanych we flash?

    PS Rozumiem sugestię zmiany procka ale na razie pozostanę przy obecnym.
    Dziękuję wszystkim za dotychczasową pomoc.
  • #14 20422312
    excray
    Poziom 41  
    trebuch1 napisał:
    Pytanie: czy w omawianym przypadku jest jakaś możliwość zapisania we flash tablicy wskaźników do tekstów zapisanych we flash?

    Oczywiście. Zrób sobie tablicę ze stringami korzystając ze struktury.
  • #15 20422412
    tmf
    VIP Zasłużony dla elektroda
    trebuch1 napisał:
    Poprzedni mój przykład działa poprawnie pod warunkiem że cały jego tekst
    zawarty jest w jednym pliku głównym. Jeśli wywołanie funkcji piszącej do lcd
    nastąpi w innym pliku, to argument funkcji będący zarazem wskaźnikiem do tekstu flash nie zostanie rozpoznany. Obszedłem to poprzez zdefiniowanie

    W pliku nagłówkowym powinny być tylko deklaracje, zazwyczaj w pliku nagłówkowym nie umieszcza się definicji czy to funkcji, czy zmiennych. Zapewne wytłumaczenie takiego dziwnego zachowania programu leży w braku zadeklarowanego prototypu funkcji i kompilator przyjmuje jakiś domyślny.
    trebuch1 napisał:
    Dla mnie jest to w zupełności akceptowalne. Jest sens bawić się w zapisy do flash o ile są one wielobajtowe, aby tworzone w RAM ich wskaźniki zawierały o wiele mniej miejsca niż te same teksty zapisane wprost do RAM.
    Pytanie: czy w omawianym przypadku jest jakaś możliwość zapisania we flash tablicy wskaźników do tekstów zapisanych we flash?

    Oczywiście, sam wskaźnik też może być we flash - wystarczy użyć __flash char *wsk __flash. Tablicę wskaźników też można umieścić w flash.

Podsumowanie tematu

Użytkownik próbuje wykorzystać pamięć FLASH w AVR Studio 7 do przechowywania i odczytu tekstów, jednak napotyka problemy z odczytem. W odpowiedziach zasugerowano użycie prefiksu __flash dla zmiennych oraz przeniesienie definicji zmiennych poza funkcje, co rozwiązało problemy z kompilacją. Użytkownicy podzielili się przykładami kodu, w tym funkcjami do wyświetlania tekstu na LCD oraz wskazówkami dotyczącymi organizacji kodu w plikach nagłówkowych. Zwrócono uwagę na konieczność użycia tablicy zamiast wskaźników dla tekstów w pamięci FLASH oraz na zalety nowszych modeli AVR, które nie wymagają modyfikatorów pamięci.
Podsumowanie wygenerowane przez model językowy.
REKLAMA