Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

CAN + microSD + DMA + freeRTOS

Chef_C 18 May 2019 14:20 522 9
  • #1
    Chef_C
    Level 4  
    Cześć,

    Próbuję stworzyć zapis na kartę microSD danych z CAN''a na płytce stm32f7-nucleo767zi. Na razie to dane 8-bitowe z dwóch potencjometrów, ale w przyszłości będzie ich więcej. Obsługa przerwania CAN działa(na ledach testowane), zapis działa, muszę to jakoś połączyć. Koncepcja jest taka, że przy obsłudze przerwania sprawdza ID ramki i na tej podstawie zapisuje daną do odpowiedniego pliku .txt na karcie. Dopiero zaczynam zabawę z obsługą microSD na STM32, jak na razie stworzyłem to :

    Kod na sam zapis :
    Code: c
    Log in, to see the code

    Inicjalizacja zegara, do CAN''a i jednocześnie microSD. I tutaj pojawiają się moje wątpliwości, czy nie lepiej byłoby skonfigurować dwa zegary, osobno dla CAN i dla microSD?

    Code: c
    Log in, to see the code


    microSD:

    Code: c
    Log in, to see the code


    Obsługa przerwania od CAN
    Code: c
    Log in, to see the code


    Prosiłbym o sugestie w jaki sposób to najlepiej się za to zabrać, aby sensownie działało i przy większej ilości danych transfer był wystarczająco szybki :)
  • #2
    User removed account
    Level 1  
  • #3
    LChucki
    Level 31  
    stmx wrote:
    zapis do sd na pewno nie w przerwaniu :) CAN.

    Na pewno nie, bo standardowy timeout to 500ms.

    stmx wrote:
    take rzeczy robi się najlepiej w wielu watkach.

    Najłatwiej ale idąc w zaparte, można sobie podzielić operacje obsługi karty SD na wiele "kawałków", tyle, że trzeba grzebać w obsłudze karty SD.

    Pozostaje wielowątkowość i zmniejszenie timeoutów albo, chyba więc najprościej, RTOS.

    Co do wielowątkowości i obsługo kart SD, typowo operacje nie przekraczają 10ms (1..6ms) ale ten nieszczęsny timeout (można zmienić w opcjach). Jeśli więc 10ms to nie problem to wielowątkowość, jeśli 10ms to długo, to RTOS.


    PS
    Setek programów z FS i SD nie napisałem więc te typowe 10ms może być dłuższe.
  • #4
    User removed account
    Level 1  
  • #5
    Chef_C
    Level 4  
    Dzięki za podpowiedzi, zaczynam "uczyć się" RTOS na STM32, a na razie zrobiłem to w taki sposób, że na przerwanie od CAN'a dana po odpowiednim ID idzie do "buforu", array'a 32kB i po zapełnieniu przekopiowuje cały array na kartę microSD. Testowałem na 3kB dla dwóch potencjometrów i działa całkiem nieźle, ciekawe jak przy większej ilości czujników...
  • #6
    LChucki
    Level 31  
    stmx wrote:
    LChucki wrote:
    Jeśli więc 10ms to nie problem to wielowątkowość, jeśli 10ms to długo, to RTOS.
    A dlaczego takie rozróżnienie? czy RTOS to nie wielowatkowosc?

    Tak, ale w wielowątkowości, takiej bez RTOS, operacja jakaś tam nie zostanie przerwana (pomijam przerwania) po np 10ms. Oczywiście da się tak napisać soft aby nie nadużywał czasu CPU, ale jak mam taki np FILESYSTEM, to jest dużo roboty. RTOS rozwiązuje takie problemy łatwo i przyjemnie, no nie do końca łatwo, bo na RTOS trzeba "nauczyć" sie pisac - znam to z Amigi, gdzie wcześniej C-64 i PC z DOS.
  • #7
    Chef_C
    Level 4  
    Próbuję stworzyć zapis na microSD we FreeRTOS i potrzebuję koncepcji, w jaki sposób to najlepiej zrobić dla takiej ilości danych, które mają być zapisywanie. Powinno działać płynnie dla około 30 ramek z 8-bajtowymi danymi, które są wysyłane z częstotliwością około 10Hz do magistrali CAN. Każda dana powinna być zapisywana do innego pliku .txt.

    Mam taki pomysł, żeby na przyjście ramki z CAN'a ustawić flagę po RxHeader.ID, która odblokuje Thread do zapisu danej do odpowiedniego buforu. Po przepełnieniu buforu, kolejny wątek przepisze bufor do pliku.

    Czy kilka wątków może jednocześnie kopiować na microSD z użyciem f_mount, f_open, f_printf, f_close?

    Teraz pojawiają się wątpliwości, jaki rozmiar buforu najlepiej ustawić oraz jaki rozmiar stack'ów dla Threadów? Czy zapis do buforu i kopiowanie do pliku powinny być w osobnych wątkach, czy w tym samym wątku na prostym if'ie? Może to jest kiepskie rozwiązanie?

    Proszę o pomoc :D
  • Helpful post
    #8
    User removed account
    Level 1  
  • #9
    Chef_C
    Level 4  
    Dzięki za pomoc :D Mam problem z zapisem uint8_t do pliku z użyciem funkcji f_write, z f_prinf działa bez problemów :

    Code:
    f_printf(&myFile, "%d\n", buff_data[i]);


    Jednak zależy mi na szybkości zapisu, jak powinna wyglądać funkcja zapisu tablicy uint_8_t z f_write?
  • #10
    Chef_C
    Level 4  
    Próbuję dodać timestamp do ramki CAN i dzieje się dziwna rzecz :o timestamp wysyłam jako dwie 8-bitowe liczby, które datalogger łączy w jedną, 16-bitową liczbę.
    Samo wysyłanie ramki jest wykonywane na timerze w częstotliwością 20Hz. Próbowałem to zrobić na różne sposoby i za każdym razem z takim samym skutkiem : działa idealnie do 65 i zatrzymuje transmisję :o Pierwszy kod na zawarcie w ramce timestamp'u :

    Code: c
    Log in, to see the code



    Drugi sposób :
    Code: c
    Log in, to see the code


    Ktoś mi jest w stanie wytłumaczyć, dlaczego za każdym razem transmisja zatrzymuje się przy dojściu do time_1/timestamp = 65? Przy wysyłaniu danych z samych czujników (0-255) w &msg nic takiego się nie dzieje, działa idealnie...