Skocz do zawartości
aldenham

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

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.

Udostępnij ten post


Link to post
Share on other sites

@aldenham piszesz, że wyniki są jednakowe, a chwilę później że różne. Mogłbyś nieco dokładniej opisać co masz na myśli?

  • Lubię! 1

Udostępnij ten post


Link to post
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?

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
Share on other sites

@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).

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
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.

Udostępnij ten post


Link to post
Share on other sites

@miszczu18 Dzięki, po dobrze przespanej nocy właśnie się zorientowałem, co zrobiłem, tzn. że wykroczyłem poza zakres tablicy.

@Elvis Masz rację, niepotrzebnie pytałem o to w komentarzach do kursu. Kończę ten temat.

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
Share on other sites

Zgodnie z sugestią pytanie wydzieliłem do osobnego tematu. Poprzednia lokalizacja postów: 

 

Udostępnij ten post


Link to post
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

Udostępnij ten post


Link to post
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!

Udostępnij ten post


Link to post
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!

Gość
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...