[C][Keil uVsion] Przesuwanie adresu wskaźnika... 2+2 nie równe 4

0

Mam dość dziwny problem z moim programem napisanym w języku C. Jest on stworzony dla mikrokontrolera STM32 i ma służyć do kopiowania bloków danych pomiędzy pamięcią RAM i FlashROM. Ze względnu na pewne ograniczenia mechanizmu zapisu do tej drugiej muszę kopiować z niej całą zawartość zmienianej strony (1kB) do pamięci RAM, tam nanosić dane a następnie zapisywać z powrotem do Flash..

Tyle tytułem wstępu teoretycznego a teraz mój problem. Kod mojej funkcji znajduje się poniżej:

void ProgramFlashFromBlock(unsigned int FlashAddr, unsigned int* pMemStartAddr, unsigned short size) {
    /* Funkcja kopiuje okreslonych rozmiarow dane z pamieci programu do pamieci flash. 
       Calosc danych musi zmiescic sie w jednej stronie pamieci flash
       
       Parametry przekazywane do funkcji:
       -> FlashAddr - adres w pamieci Flash stanowiacy poczatek obszaru do ktorego beda przepisywane dane
       -> pMemStartAddr - wskaznik na poczatek obszaru pamieci programu zawierajacego dane do skopiowania
       -> size - rozmiar danych do przeniesienia
       */
//    unsigned short int dat_m, dat_l;            // dane rozdzielone na dwie części
    unsigned int rw_addr = 0;                // adres aktualnie zapisywanej lub odczytywanej strony
    int fi;
    int pagenum;                                // zmienna przechowuje numer strony w której będą zapisywane dane
    int in_page_off;                            // ilość 16bitowych przesunięć od początku strony do których mają być zapisane dane 
    pagenum = (int)((FlashAddr - 0x8000000)/PAGE_CAPACITY);    // obliczanie numeru strony do zaprogramowania
    in_page_off = (FlashAddr - (0x8000000 + pagenum * PAGE_CAPACITY)) / 2;    // obliczanie przesunięcie 16bitowe od początku strony

    for (fi = 0; fi < BLOCKSNUM; fi++) {
        page_data[fi] = *(unsigned short int*)(rw_addr + 0x8000000 + pagenum * PAGE_CAPACITY);
        // przepisywanie zawartości zmienianej strony do pamięci RAM. Przepisywanie odbywa się po 16 bitów
        rw_addr += 2;
    }
    rw_addr = 0;
    for (fi = 0; fi <= (size/2) ; rw_addr += 2, fi++) {
        page_data[in_page_off+fi] = (unsigned short)*(pMemStartAddr + (unsigned int)rw_addr);
    }                                                                           /* POPRAWIĆ*/ 
    FlashUnlock();
    EraseFlashPage(FlashAddr);
    FLASH->CR |= FLASH_CR_PG;            // włączenie zapisu
    rw_addr = 0;
    for (fi = 0; fi < 1024; fi++) {
        *(unsigned short int*)(rw_addr + 0x8000000 + pagenum * PAGE_CAPACITY) = page_data[fi];
        while ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY);
        rw_addr += 2;
    }
    FLASH->CR &= (0xFFFFFFFF ^ FLASH_CR_PG);        // wyłączenie zapisu
    FlashLock();

}


 

Problematyczna jest linijka

    page_data[in_page_off+fi] = (unsigned short)*(pMemStartAddr + (unsigned int)rw_addr); 

Zmienna rw_addr jest wprawdzie poprawnie zwiększana o 2 przy każdym przejściu pętli for. Problem polega na tym, że gdy dodam ją do adresu wskazywanego przez pMemStartAddr nie otrzymuję poprawnego wyniku działania. Całość została przedstawiona na dołączonym do postu zrzucie ekranowym.
http://obrazki.elektroda.pl/2392926800_1383167655.png
Z czego może wynikać takie zachowanie programu? Czy może nie wiem o jakiejś właściwości wskaźników w języku C?

Mateusz

0

Wszystko jest jak powinno być.

pMemStartAddr to wskaźnik na unsigned int. Przesuwasz go o rw_addr * sizeof(unsigned int). unsigned int to u Ciebie 4 bajty. 0x1C + (2 * 4) = 0x24.

Co Ty chciałeś uzyskać? Dodanie do wskaźnika liczby n nie powoduje przesunięcia o n bajtów, tylko o "n zmiennych". Przecież to absolutnie podstawowa zasada działania arytmetyki wskaźników.

1 użytkowników online, w tym zalogowanych: 0, gości: 1