NONOS SDK i zmienne we FLASH

Język C dla mikrokontrolerów Tensilic
ODPOWIEDZ
Awatar użytkownika
squeez
Użytkownik
Posty: 85
Rejestracja: 16 paź 2017, 23:52

NONOS SDK i zmienne we FLASH

Post autor: squeez » 28 gru 2017, 10:18

Jak by ktoś się zastanawiał jak umieścić zmienne we FLASH a potem się do nic dobierać to znalazłem fajne rozwiązanie :) dla ardusrino jest makro podobne do PROGMEM z AVR ale ja nie używam arduino więc musiałem głębiej pokopać.

Do wskazania kompilatorowi gdzie ma umieścić dane (że nie tak normalnie w SRAM) tylko we flash służy makro ICACHE_RODATA_ATTR podobne do ICACHE_FLASH_ATTR, można podejrzeć na co się one rozwijają w pliku c_types.h

Kod: Zaznacz cały

#ifdef ICACHE_FLASH
#define ICACHE_FLASH_ATTR   __attribute__((section(".irom0.text")))
#define ICACHE_RODATA_ATTR  __attribute__((section(".irom.text")))
#else
Należy też pamiętać że zapis w flash wyrównywany jest do 4 bajtów i tak samo odczytywane jest jako 4 bajty, więc jeśli chcemy zapisywać dane 1 bajtowe musimy je wyrównać (dopełnić do 4) a przy odczycie, niejako wyłuskać ze zmiennej 32 bitowej interesujące nas 8 bitów.

I tu pomocne są funkcje do odczytu:

Kod: Zaznacz cały

uint8 ICACHE_FLASH_ATTR read_rom_uint8(const uint8* addr) {
    uint32 bytes;
    bytes = *(uint32*)((uint32)addr & ~3);
    return ((uint8*)&bytes)[(uint32)addr & 3];
}
i dla danych 16 bitowych:

Kod: Zaznacz cały

uint16 read_rom_uint16(const uint16* addr) {
    uint32 bytes;
    bytes = *(uint32*)((uint32)addr & ~3);
    return ((uint16*)&bytes)[((uint32)addr >> 1) & 1];
}
Całość może wyglądać tak:

Kod: Zaznacz cały

const uint8 ICACHE_RODATA_ATTR data[] = {
    0,1,2,3,4,5,6,7,
    8,9,10,11,12,13,14,15
};
 
const uint16 ICACHE_RODATA_ATTR data16[] = {
    300,600,900,1200
};
 
uint8 ICACHE_FLASH_ATTR read_rom_uint8(const uint8* addr) {
    uint32 bytes;
    bytes = *(uint32*)((uint32)addr & ~3);
    return ((uint8*)&bytes)[(uint32)addr & 3];
}
 
uint16 read_rom_uint16(const uint16* addr) {
    uint32 bytes;
    bytes = *(uint32*)((uint32)addr & ~3);
    return ((uint16*)&bytes)[((uint32)addr >> 1) & 1];
}
 
void ICACHE_FLASH_ATTR user_init(void) {
    os_printf("%d\r\n", read_rom_uint8(&data[0]));
    os_printf("%d\r\n", read_rom_uint8(data + 13)); 
    os_printf("%d\r\n", read_rom_uint16(&data16[1]));
}
Wygrzebałem to z bloga Richarda Burtona https://richard.burtons.org/2015/07/08/ ... -on-flash/

Wykorzytstałem ten patent przy zapisie fontów do OLED-a we flashu i działa super :)

Jeśli kogoś by interesował odczyt/zapis do FLASH-a to w SDK są do tego przygotowane funkcje oraz oddzielny dokument, który o tym traktuje + opis sposobu jak nie utracić danych w trakcie zapisu. Taki backup zapisywanych danych http://www.espressif.com/sites/default/ ... v1.0_0.pdf

ODPOWIEDZ