Skocz do zawartości

Problem ze zrozumieniem operacji na tablicach i wskaźników (STM32 DMA)


aldenham

Pomocna odpowiedź

Poniższe pytanie zostało wydzielone z kursu: https://forbot.pl/forum/topic/10506-kurs-stm32-f1-hal-8-bezposredni-dostep-do-pamieci/

 

Witam

W zadaniu 8.1 wyniki z copy_cpu() i copy_dma() mam jednakowe i są następujące:

Bufor zrodlowy: 536873560
Bufor docelowy: 536873592

Jak widać, wartości są różne.

W ogóle wyświetlam wartości src_buffer i dst_buffer za pomocą printf. Jakiego formatu używać do wyświetlania liczb typu uint8_t albo uint16_t, bo %d zwraca ostrzeżenia.

Link do komentarza
Share on other sites

@Elvis Fakt, trochę zakręciłem. Chodzi mi o to, że funkcje copy_cpu() i copy_dma() dają takie same wyniki. A wyniki są takie, jak umieściłem powyżej, czyli

Bufor zrodlowy: 536873560
Bufor docelowy: 536873592

Jak widać wartości obu buforów nie są równe 😀

I przy okazji ponawiam pytanie o formatowanie w printf - jak formatować zmienne typu uint8_t i uint16_t?

Link do komentarza
Share on other sites

Przyznam, że nic nie zrozumiałem - bufory mają i powinny mieć inne adresy, to co wstawiasz wygląda właśnie na adres bufora źródłowego, bo 536873560 czyli 0x20000a58 to adres w pamięci SRAM. Co więcej 536873592 - 536873560 = 32, a tyle wynosi wielkość bufora źródłowego, więc możemy się domyślać że wyświetliłeś tutaj adresy buforów, a nie ich zawartość.

Funkcje copy_cpu/dma nie zmieniają adresów buforów, a jedynie kopiują dane. Więc adresy powinny być różne, ale ich zawartość identyczna.

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@Elvis Ok, to zadam trochę inne pytanie. W zadaniu 8.1 mamy wyświetlić wartości zmiennych src_buffer i dst_buffer po wykonaniu kolejno funkcji copy_cpu() i copy_dma(). Zrobiłem to tym razem trochę inaczej. Nadmienię, że nie zmieniałem nic w kodzie funkcji copy_cpu() i copy_dma().

    // wypelniamy bufor przykladowymi danymi
    for (i = 0; i < BUFFER_SIZE; i++)
        src_buffer[i] = 100 + i;

    copy_cpu();
	printf("src_buffer z copy_cpu: %d\n", src_buffer[BUFFER_SIZE]);
	printf("dst_buffer z copy_cpu: %d\n", dst_buffer[BUFFER_SIZE]);

    copy_dma();
	printf("src_buffer z copy_dma: %d\n", src_buffer[BUFFER_SIZE]);
	printf("dst_buffer z copy_dma: %d\n", dst_buffer[BUFFER_SIZE]);

Otrzymuję takie wyniki:

src_buffer z copy_cpu: 100
dst_buffer z copy_cpu: 0
src_buffer z copy_dma: 100
dst_buffer z copy_dma: 0

Z tego, co piszesz, to wyświetlałem wcześniej adresy zmiennych src_buffer i dst_buffer. Wtedy kod wyglądał tak:

    // wypelniamy bufor przykladowymi danymi
    for (i = 0; i < BUFFER_SIZE; i++)
        src_buffer[i] = 100 + i;

    copy_cpu();
	printf("src_buffer z copy_cpu: %d\n", src_buffer);
	printf("dst_buffer z copy_cpu: %d\n", dst_buffer);

    copy_dma();
	printf("src_buffer z copy_dma: %d\n", src_buffer);
	printf("dst_buffer z copy_dma: %d\n", dst_buffer);

Co tak naprawdę wyświetlam w tych przykładach? Wygląda mi to bardziej na wartość elementu zerowego zmiennych tablicowych src_buffer i dst_buffer. Czy naprawdę poprzednio wyświetlałem adresy zmiennych src_buffer i dst_buffer?

Skoro wartości src_buffer i dst_buffer różniły się o 32, to wygląda mi to bardziej na różnicę ilości elementów tablicy (bo BUFFER_SIZE == 32).

Link do komentarza
Share on other sites

W pierwszym przypadku wyświetlasz zawartość n-tego elementu tablicy tylko jest taki problem, że próbujesz dostać się do elementu, który jest tuż za tablicą bo wyszedłeś poza zakres. Dzięki temu, że bufor docelowy jest w pamięci umiejscowiony od razu za buforem źródłowym to przez src_buffer[BUFFER_SIZE] daje tak na prawdę dst_buffer[0].  dst_buffer[BUFFER_SIZE] też daje wartość elementu za tablicą, ale że tam może być cokolwiek, akurat u Ciebie 0 to jest taki wynik.

Drugi przypadek. Nazwa tablicy to wskaźnik (adres) na jej pierwszy element. Tablice zawierają 32 elementy, każdy po bajcie, a że są w pamięci obok siebie to adresy pierwszych elementów różnią się o te 32 bajty. 

  • Lubię! 2
Link do komentarza
Share on other sites

Widzę, że kolega @miszczu18 wyprzedził mnie w tłumaczeniu o co chodziło w programie 🙂

Proponuję więc zostawienie DMA na chwilę w spokoju i powtórkę z działania tablic oraz wskaźników w języku C - bez tego raczej ciężko będzie napisać właściwie jakikolwiek program.

Natomiast od administratora mam prośbę o wydzielenie tej dyskusji do oddzielnego tematu, dotyczy ona podstaw C i nie ma nic wspólnego z DMA, ani kursem STM32.

Link do komentarza
Share on other sites

@aldenham Bardzo dobrze, że pytałeś i bardzo się cieszę że sprawa się wyjaśniła 🙂 Po prostu skoro już wiemy, że problem nie dotyczył DMA można pytania wydzielić z tego tematu - to nic złego i mam nadzieję że admin bez problemu to załatwi.

Jeśli będziesz miał kolejne pytania odnośnie tablic, wskaźników i printf-ów, to też pytaj - na pewno pomożemy, w końcu po to jest Forbot.

Wracając do printf-ów, nie wiem jakie ostrzeżenia generował kompilator, mogło chodzić o użycie typów bez znaku i wtedy zamiast %d można zastosować %u. Ale możliwe, że ostrzeżenia dotyczyły użycia wskaźników w miejscu gdzie powinny być liczby - więc jeśli ten problem pojawi się przy poprawnym użyciu tablic, napisz co wyświetla kompilator i jaki dokładnie masz kod.

  • Lubię! 1
Link do komentarza
Share on other sites

@Elvis Już doszedłem z wszystkim do ładu, dzięki za pomoc. Przy wyświetlaniu wartości dowolnego z elementów zmiennych tablicowych src/dst_buffer, %u załatwia sprawę.

Wcześniej kompilator wyświetlał ostrzeżenie przy próbie wyświetlenia adresu tablicy (tutaj np. z użyciem formatowania %u):

warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'uint8_t * {aka unsigned char *}' [-Wformat=]

W ogóle ten kurs i wasza pomoc na forum to świetna sprawa. Pewne tematy wydają się oczywiste, ale człowiek uczy się na błędach. Gdybym na pytania otrzymał odpowiedzi typu: "poczytaj w necie", albo "nie znasz się", to pewnie bym się zniechęcił do dalszej nauki. W polskiej części internetu nie ma drugiego takiego miejsca, w którym można tyle się nauczyć i otrzymać odpowiedź na tyle pytań związanych z STM32. Także naprawdę wielki szacunek dla waszej wiedzy i ogromne dzięki za pomoc!

  • Lubię! 1
Link do komentarza
Share on other sites

9 godzin temu, aldenham napisał:

W ogóle ten kurs i wasza pomoc na forum to świetna sprawa. Pewne tematy wydają się oczywiste, ale człowiek uczy się na błędach. Gdybym na pytania otrzymał odpowiedzi typu: "poczytaj w necie", albo "nie znasz się", to pewnie bym się zniechęcił do dalszej nauki. W polskiej części internetu nie ma drugiego takiego miejsca, w którym można tyle się nauczyć i otrzymać odpowiedź na tyle pytań związanych z STM32. Także naprawdę wielki szacunek dla waszej wiedzy i ogromne dzięki za pomoc!

Aż sobie zapiszę, bardzo miło czytać takie opinie - dzięki!

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.