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

STM32 CortexM3 - Implementacja fseek w syscalls, poprawne działanie

szczepar 17 Lis 2014 08:43 1005 8
REKLAMA
  • #1 14139266
    szczepar
    Poziom 20  
    Posty: 333
    Pomógł: 27
    Ocena: 59
    Od dłuższego czasu mordowałem się z implementacja syscalls tak aby uzyskać pewne efekty mnie zadowalające.
    Jednym z nim było uzyskanie wyświetlacza LCD jako strumienia z obsługą przy pomocy standardowych funkcji np : "fsetpos".

    Srodowisko :
    Sourcery CodeBench Lite for ARM EABI z plikami Freediego Chopina

    Do poprawnej pracy potrzebna była implementacja funkcji "fseek" i tu zaczynają się problemy :)

    Jaki jest poprawny opis działania jaki ma spełniać ta funkcja ?
    Ta ? Link
    Czy ta ? Link

    Wg manuala dostarczonego z kompilatorem wynika że funkcja zwraca wartość 0 lub - 1 w zależności czy działanie się powiodło czy nie.
    Ale działanie innych funkcji wskazuje na wersję pierwszą , czyli zwrot wartości indeksu w strumieniu.

    Przykład obrazujący problem (wycinek kodu):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Krótkie wyjasnienie :
    _read_r - funkcja działa poprawnie , zwraca wartość 4.
    _lseek_r - funkcja działająca dla wersji "niezgodnej z dokumentacją dostarczoną z kompilatorem"
    fgetpos - zwraca w zmiennej pozycja wartość 15.

    Pytanie która z definicji działania funkcji fseek jest prawidłowa ?
  • REKLAMA
  • Pomocny post
    #2 14139320
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    szczepar napisał:
    Jaki jest poprawny opis działania jaki ma spełniać ta funkcja ?
    Ta ? Link
    Czy ta ? Link

    Wg manuala dostarczonego z kompilatorem wynika że funkcja zwraca wartość 0 lub - 1 w zależności czy działanie się powiodło czy nie.
    Ale działanie innych funkcji wskazuje na wersję pierwszą , czyli zwrot wartości indeksu w strumieniu.

    Osobiście nie widzę sprzeczności w tych dwóch opisach, natomiast informacja jakoby lseek() powinno zwracać -1 lub 0 jest uproszczeniem mającym zastosowanie tylko gdy zakładasz, że w strumieniu nie da się "szukać".

    Tak wiec lseek() powinno zwracać -1 jeśli wystąpił błąd (powód błędu powinien znaleźć się w zmiennej errno), lub pozycję od początku pliku w bajtach (np. 0 albo 15 albo 341254252).

    Przy okazji - wg mnie najlepszym źródłem informacji o tym co powinny robić funkcje tego typu jest specyfikacja POSIX - w końcu lseek() to funkcja z POSIXa.

    http://pubs.opengroup.org/onlinepubs/9699919799/ -> http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html

    Drugie "przy okazji" - warto sobie dać już spokój z CodeSourcery - toolchain ten ostatnio "umarł", Mentor Graphics już go nie udostępnia i udostępniać nigdy nie będzie.

    http://www.mentor.com/embedded-software/sourc...ols/sourcery-codebench/editions/lite-edition/
    Cytat:
    ARM & Intel Processors

    Sourcery CodeBench Lite releases for ARM EABI, ARM GNU/Linux, ARM AARCH64-Linux, IA32/IA64 GNU/Linux and ELF are no longer available.

    Please click here to download a free trial of the full-featured Sourcery CodeBench for ARM or IA32.


    Warto wybrać linaro ( https://launchpad.net/gcc-arm-embedded ) lub - tutaj autoreklama - bleeding-edge-toolchain ( https://www.elektroda.pl/rtvforum/topic2495264.html ).

    4\/3!!
  • #3 14139344
    szczepar
    Poziom 20  
    Posty: 333
    Pomógł: 27
    Ocena: 59
    Teoretycznie nie udostępnia:
    Cytat:

    C:\>arm-none-eabi-gcc --version
    arm-none-eabi-gcc (Sourcery CodeBench Lite 2014.05-28) 4.8.3 20140320 (prereleas
    e)
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    W praktyce w październiku to ściągałem. :)
    Mimo że na stronie głównej piszą to co piszą. :P
    (jak dla mnie ograniczają ich licencje GNU i dopóki nie przepiszą wszystkiego na swój kod jedyne co mogą to utrudniać dostęp)
    Stali się ofiarami swojego sukcesu (między innymi za sprawą osób takich jak ty - i twoim genialnym przykładem i tutotrialem)

    Freedie wiem o istnieniu obu wersj , ale chce zakończyć pewne sprawy i pewne porządkowanie kodu. Jak pozbędę się prowizorek programistycznych jak np LCD_GOTO na przemian z printfami. :)
    Przesiadkę na pewno zrobię
    Dzięki za wskazanie kompetentnych źródeł - bo wychwycenie zachowania lseek na podstawie działania programu - czyli odpowiednie testy diagnostyczne zjadły mi 3 dni.
  • REKLAMA
  • Pomocny post
    #4 14139428
    PDT
    Poziom 24  
    Posty: 511
    Pomógł: 79
    Ocena: 50
    szczepar napisał:
    Pytanie która z definicji działania funkcji fseek jest prawidłowa ?


    W tym przypadku mamy do czynienia ze strumieniem znakowym, zatem:

    Pierwszy opis:
    The behavior of lseek() on devices which are incapable of seeking is implementation-defined. The value of the file offset associated with such a device is undefined.

    Drugi opis:
    On Linux, using lseek() on a terminal device returns ESPIPE.

    Obie definicje są prawidłowe.
    Tradycyjny '/dev/tty' to był dalekopis, drukował znak po znaku 'hardcopy' na papier. Jako urządzenie we/wy działał bez buforowania. Jakiekolwiek 'lseek' nie miało sensu.
    Oczywiście według 1. opisu można zdefiniować dla LCD 'lseek' jako 'GotoXY', będzie to już niezgodność z Linux'em (drugi opis).

    Pzdr
  • #5 14139460
    szczepar
    Poziom 20  
    Posty: 333
    Pomógł: 27
    Ocena: 59
    Problem wynikł podczas testowania poszczególnych przypadków :
    fseek(f_LCD_MENU, 5, SEEK_SET); - działał poprawnie - tu adresowanie bezwzględne.

    fseek(f_LCD_MENU, 5, SEEK_CUR); - to tu nie działało poprawnie.
    Ponieważ znalazłem niezgodność dokumentacji dostarczonej z kompilatorem z tym co się działo przy poszczególnych wypadkach trafiłem tu : i całe zamieszanie mogę określić jako "niepełną dokumentację dostarczoną z kompilatorem".

    Ja traktuje Wyświetlacz LCD jako plik 80 znakowy a nie dosłownie jako terminal.
    Może to lekko kreatywne podejście do interpretacji dokumentacji , ale przy takim podejściu chyba nie jest niezgodne z opisem Linux'owym ?

    Może niefortunnie podałem to jako źródło (opis funkcji Linux) - ale co szukałem to znajdowałem opisy funkcji fseek jako wersjie 0, -1.
  • #6 14139736
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    szczepar napisał:
    W praktyce w październiku to ściągałem.
    Mimo że na stronie głównej piszą to co piszą.
    (jak dla mnie ograniczają ich licencje GNU i dopóki nie przepiszą wszystkiego na swój kod jedyne co mogą to utrudniać dostęp)

    Ta "śmierć" tego pakietu to nowa sprawa - sam kilka miesięcy ściągnąłem ostatnią wersję (tą którą Ty masz), ale zauważ, że ona ma już pół roku. Teraz już nowych nie będzie i niczego nie ściągniesz (; Licencja GNU wiele tutaj nie zmienia. Nie muszą udostępniać kodu WSZYSTKIM - tylko tym którzy kupią/ściągną ich wersję płatną. A Ci mogą, ale nie muszą, udostępnić ją całemu światu, ale nie liczyłbym na to. Generalnie Mentor (a wcześniej CodeSourcery) trochę "przycinało po bandzie" w sprawie licencji...

    szczepar napisał:
    Ja traktuje Wyświetlacz LCD jako plik 80 znakowy a nie dosłownie jako terminal.
    Może to lekko kreatywne podejście do interpretacji dokumentacji , ale przy takim podejściu chyba nie jest niezgodne z opisem Linux'owym ?

    Można rozwiązać ten problem bez lseek() - wystarczyłoby dodać obsługę znaków formatujących (backspace, CR) oraz specjalnych sekwencji terminala VT100 - takich jak "wyczyść linię" itp.

    szczepar napisał:
    Może niefortunnie podałem to jako źródło (opis funkcji Linux) - ale co szukałem to znajdowałem opisy funkcji fseek jako wersjie 0, -1.

    No bo fseek() i lseek() to co innego <:

    4\/3!!
  • REKLAMA
  • #7 14139804
    szczepar
    Poziom 20  
    Posty: 333
    Pomógł: 27
    Ocena: 59
    W dniu w którym ściągałem tą wersję komunikat o braku wersji ARM już był na stronie.
    Nadal jednak można ją ściągnąć poprzez aktywną subskrypcję dla wersji LITE.
    (czyli zlikwidowali tylko odwołanie do niej na stronie głównej)
    To czy nadal będzie rozwijana czy nie - nie wiem , wiem że wersje LITE były wydawane nieregularnie i w związku z tym przerwa półroczna nie jest czymś dziwnym.

    Jak dla mnie pojechali po bandzie i to kwestia czasu kiedy ludzie przejdą na linaro lub bet :)

    Co do różnicy pomiędzy fseek() i lseek() - po 3 dniach walki możliwe ze poprzestawiało mi się w głowie. Możliwe że zamiast szukać lseek szukałem fseek (na swoje usprawiedliwienie mogę dodać jedynie, że dokumentacja syscalls dla tego kompilatora jest uboga)

    Gdy pojawia się błąd myślowy jedyne co może ci pomóc to spojrzenie innej osoby.
    Dlatego udałem się tu :) - wiedziałem że :
    - ktoś pokaże mi moją ignorancję
    - pokaże mi że źle myślę
    - wskaże literówkę której nie widzę
    - w inny sposób zmiecie mnie konstruktywną krytyką
    I tego oczekiwałem :) i za to dziękuję :).

    Co do użycia znaków specjalnych zamiast zabawy z lseek ()
    Można, masz rację.
    Ja chciałem jednak aby LCD zachowywał się jak file[80].
    A jak pojawił się błąd to nie mogłem go zignorować , obejść - tylko musiałem zrozumieć czemu wystąpił.
  • #8 14139839
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    szczepar napisał:
    Dlatego udałem się tu - wiedziałem że :
    - ktoś pokaże mi moją ignorancję
    - pokaże mi że źle myślę
    - wskaże literówkę której nie widzę
    - w inny sposób zmiecie mnie konstruktywną krytyką
    I tego oczekiwałem i za to dziękuję .

    Nie wiem gdzie się czegokolwiek takiego dopatrzyłeś w tym wątku (; no może poza tą literówką fseek/lseek...

    4\/3!!
  • REKLAMA
  • #9 14142331
    szczepar
    Poziom 20  
    Posty: 333
    Pomógł: 27
    Ocena: 59
    Reasumując na przyszłość :
    Rozróżniać lseek() od fseek() :)
    I korzystać z sprawdzonych źródeł z opisem działania funkcji.

Podsumowanie tematu

✨ Dyskusja dotyczy implementacji funkcji syscalls w kontekście użycia funkcji "fseek" w systemie STM32 CortexM3, szczególnie w odniesieniu do wyświetlacza LCD jako strumienia. Użytkownik napotkał problemy z działaniem "fseek" w przypadku różnych trybów adresowania (SEEK_SET i SEEK_CUR). Uczestnicy podkreślili, że "lseek" i "fseek" to różne funkcje, a ich zachowanie w kontekście urządzeń, które nie obsługują operacji szukania, jest zdefiniowane w specyfikacji POSIX. Zasugerowano również, aby użytkownik rozważył przejście na toolchain Linaro, ponieważ CodeSourcery przestał być rozwijany. Wskazano na potrzebę dokładnego rozróżniania funkcji oraz korzystania z wiarygodnych źródeł dokumentacji.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA