Skocz do zawartości

Zapis danych uint8_t do tablicy uint32_t


radek04

Pomocna odpowiedź

Cześć,

z uwagi na ograniczoną ilość pamięci w STM32H7, w celu pełnego wykorzystania jej zasobów, chciałbym współdzielić jeden duży bufor do dwóch zadań (gdy pierwsze zadanie się skończy, zaczyna się drugie, więc dane "nie kłócą się ze sobą").

Normalnie korzystam z tablic: uint32_t tab1[119256] w jednym programie oraz uint8_t tab2[278528] w drugim ( (round_No=4096)*(liczba_rejestrów=68) ).
Przyszedł czas połączyć programy i okazało się, że pamięci brakuje. Stąd pomysł, by wykorzystać jeden bufor (tablicę) do obu celów.
Mam jednak problem z poprawnym zapisem danych. Próbowałem bardzo różnych kombinacji, może nie będę ich wymieniał, by nie narzucać (złych) pomysłów.

Proszę o pomoc, jak poprawnie skonstruować zapis do tablicy, a następnie zapis tablicy na kartę. Dobrze byłoby, gdybym w pełni wykorzystał tab1 i mógł użyć 2 razy więcej komórek 8-bitowych niż jest komórek 32-bitowych, ale jeśli zostanie mi do dyspozycji owe 119256, to też da radę.

Poniżej krytyczne fragmenty programu, czyli akwizycja danych do tablicy oraz ich zapis na kartę pamięci.

HAL_I2C_Mem_Read_DMA(&hi2c1, MPU9250_ACC_ADDRESS_A, MPU9250_ACCEL_XOUT_H, 1, &tab[round_No*68 + 0*14], 14); //14 registers measurement
HAL_I2C_Mem_Read_DMA(&hi2c2, MPU9250_ACC_ADDRESS_B, MPU9250_ACCEL_XOUT_H, 1, &tab[round_No*68 + 1*14], 14); //14 registers measurement
HAL_I2C_Mem_Read_DMA(&hi2c3, MPU9250_ACC_ADDRESS_C, MPU9250_ACCEL_XOUT_H, 1, &tab[round_No*68 + 2*14], 14); //14 registers measurement
HAL_I2C_Mem_Read_IT (&hi2c4, MPU9250_ACC_ADDRESS_D, MPU9250_ACCEL_XOUT_H, 1, &tab[round_No*68 + 3*14], 14); //14 registers measurement

HAL_I2C_Mem_Read_DMA(&hi2c1, BMP280_ADDRESS_A, BMP280_REG_BAR_MSB, 1, &tab[round_No*68 + 4*14+0*3], 3); //3 registers measurement
HAL_I2C_Mem_Read_DMA(&hi2c2, BMP280_ADDRESS_B, BMP280_REG_BAR_MSB, 1, &tab[round_No*68 + 4*14+1*3], 3); //3 registers measurement
HAL_I2C_Mem_Read_DMA(&hi2c3, BMP280_ADDRESS_C, BMP280_REG_BAR_MSB, 1, &tab[round_No*68 + 4*14+2*3], 3); //3 registers measurement
HAL_I2C_Mem_Read_IT (&hi2c4, BMP280_ADDRESS_D, BMP280_REG_BAR_MSB, 1, &tab[round_No*68 + 4*14+3*3], 3); //3 registers measurement

f_write(&fil, readings_from_registers, sizeof(tab), &numread);

W tej drugiej części (BMP280) dane pobieram z 3 rejestrów 8-bitowych. Ponieważ może być to kłopotliwe, mogę ograniczyć się do 2 lub rozszerzyć do 4, w którym jeden będzie zawsze zerami.

Każda konstruktywna uwaga będzie na dla mnie cenna.

Link do komentarza
Share on other sites

Unia, oczywiste. Tak to jest, gdy się korzysta tylko z najprostszych mechanizmów, nie mając większego pojęcia o programowaniu.

Co do grzyba - fakt, wygląda to dziwnie. Temat jest bardziej złożony. W różnych fragmentach przedstawiałem go w innych tematach na forum. Czasami bez żadnej odpowiedzi. 

W skrócie - tablica ta służy do akwizycji danych z różnych czujników. Dopóki zapisuję je w tablicy, pomiary są robione ze stałym okresem próbkowania. W momencie zapisu na kartę ciągłość pomiaru zostaje zaburzona. Stąd potrzeba jak największej tablicy, by przez jak najdłuższy czas pobierać spójne dane. 

Próbowałem różnych sposobów np. Z 2 buforami używanymi na zmianę, z DMA i in., ale zawsze podczas zapisu na kartę następuje krótka przerwa w akwizycji danych. Pewnie da się to jakoś lepiej zrobić, ale z moimi umiejętnościami programistycznymi się nie powiodło. 

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

Być może czegoś nie rozumiem, albo całości problemu. W moim mniemaniu chodzi o to żeby można było ten sam obszar traktować jako ciąg (tablicę) uint32_t lub uint8_t. Ja bym zrobił to np tak:

uint32_t tab_32[119256] = {0};
uint8_t* tab_8;
tab_8 =   &tab_32[0];
 
tab_32[0] = 0; // dostęp do obszaru tablicy jako 32 bit
tab_32[1] = 65536;
tab_8[2]  = 1; // zapis 3ciego bajtu tab_8 - dostęp do obszaru tablicy jako 8 bit

while (tab_32[0] == tab_32[1]) {} // wieczna pętla jeżeli dane 32 bit są takie same

 

Poprzez dereferencję z kwadratowymi nawiasami jest dostęp do danych. Dalsza sztuka, to jak obliczać offset do danych, to będzie wyrażenie w kwadratowych nawiasach - być może to jest głównym problemem? Choć wg mnie nie powinno. Z prostej zależności wielkości uint32_t i uint8_t danych traktowanych jako 8bit może być 4 razy więcej.

Edytowano przez virtualny
Link do komentarza
Share on other sites

Sposobów jest mnóstwo. Możesz traktować tablicę jako obszar pamięci i operować wskaźnikami (co w C jest dość naturalne). Możesz stworzyć unię, która czasem jest wygodniejsza (też naturalna w C). Nie ma lepszego czy gorszego sposobu... a raczej jest, ale zależy od konkretnego zastosowania.

Link do komentarza
Share on other sites

Nie jestem biegły w C - gdybyś mógł zastąpić/przełożyć mój przykład na unię, to może bym się czegoś nauczył.

Dla mnie bardzo ważne jest doprowadzenie wyrażenia do tablicy z kwadratowymi nawiasami zamiast cudaczenia z gwiazdkami. Wtedy widzę i wiem co robię, a jak są gwiazdki, to widzę ciemność 🙂

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

To się naucz tych gwiazdek, bo bez tego w C raczej nie ruszysz poza miganiem ledą.

union {
  uint8_t a[16];
  uint16_t b[8];
  uint32_t c[4];
  } d;

a potem

d.a[1] = coś;

Ogólnie podręczniki do C są dostępne odkąd pamiętam (czyli od czasu kiedy internet składał się z dwóch komputerów).

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Podręcznik do C posiadam np książkę Helionu 900 stron Język C w pigułce. Zajrzałem tam do opisu unii i niestety nie za wiele zrozumiałem. Teraz po Twoim przykładzie zrozumiałem sens tej unii - wielkie dzięki. Jakimś wielkim mistrzem C to ja już nigdy nie będę. Chodzi o to że np wyrażenie:

(*(u16*)((uint32_t)(0x60000000)))

w porównaniu do :

tab[0]

 

Zanim zrozumiem to pierwsze to z 5 razy dłużej to potrwa. A drugie wyrażenie rozumiem natychmiast (pewnie skrzywienie zakorzenione po delphi erh).

Dzięki za przykład.

Link do komentarza
Share on other sites

Wskaźniki to podstawa, operacja na tablicach również odbywa się za pomocą wskaźnika tylko że tej gwiazdki nie widać. Zamiast Unii możesz zastosować taki zapis 

int main()
{
    
  uint32_t i = 0xffaacc22;
  uint8_t * p = (uint8_t*)&i;
    
    
    printf("%02X %02X %02X %02X", p[3],p[2],p[1],p[0]);

    return 0;
}

 

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

1 godzinę temu, virtualny napisał:

Nie jestem biegły w C - gdybyś mógł zastąpić/przełożyć mój przykład na unię, to może bym się czegoś nauczył.

Dla mnie bardzo ważne jest doprowadzenie wyrażenia do tablicy z kwadratowymi nawiasami zamiast cudaczenia z gwiazdkami. Wtedy widzę i wiem co robię, a jak są gwiazdki, to widzę ciemność 🙂

No to chyba mamy identycznie z tymi światecznymi motywami 😉

Ja zaczynałem od "Symfonii C++" i teraz się zastanawiam, czy warto kupić książkę do ANSI C, czy to niewiele zmieni. W sumie to C używam jedynie do STM32...

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.