|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
zaz Član
Pridružen-a: Pon 06 Apr 2015 14:23 Prispevkov: 89 Aktiv.: 0.81 Kraj: Ljubljana
|
Objavljeno: Sre Sep 12, 2018 12:41 pm Naslov sporočila: STM32 - FLASH pomnilnik |
|
|
Pozdravljeni
ukvarjam se s SW za napravo (temelji na STM32F407VG), ki mora omogočati, da si uporabnik preko parametrov konfigurira napravo po svojih potrebah/željah. Teh parametrov bo približno 10 zagotovo pa ne več kot 15. Kot parameter si predstavljam 16-bitno spremenljivko v kateri bo shranjena neka vrednost.
Parametre želim shraniti v flash pomnilniku, saj se morajo parametri tudi po izklopu naprave ohraniti do naslednjega vklopa. V linker skripti sem dodal nov memory region CONFIG in ga lociral na zadnji 11. sektor FLASH pomnilnika, obstoječi FLASH memory region, pa sem zmanjšal za velikost sektorja 11 (128KB).
Original:
Koda: |
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
} |
Modificiran memory region:
Koda: |
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 896K
CONFIG (rw) : ORIGIN = 0x80E0000, LENGTH = 128K
} |
Dodal sem memory section v CONFIG memory region.
Koda: |
.config :
{
*(.config.TEMP_MAX)
*(.config*)
} > CONFIG |
V .c datoteki, kjer imam spremenljivke deklarirane sem eno od spremenljivk poskušal postaviti v novo ustvarjeni memory region s ukazom:
Koda: |
__attribute__((section(".config.TEMP_MAX"))) uint16_t TEMP_MAX; |
Projekt se po modifikaciji normalno prevede ampak Build Analyzer orodje, ki ga ponuja TrueSTUDIO IDE zazna nov memory region ampak je le ta prazen.
Lahko kdo pomaga z nasvetom kaj počnem narobe?
Dodatek:
Nastavitve želim postaviti v ločen FLASH sektor, ker bo vrednosti možno modificirati med delovanjem naprave in bom na tem sektorju izvedel kvazi emulacijo EEPROM pomnilnika. |
|
Nazaj na vrh |
|
|
zaz Član
Pridružen-a: Pon 06 Apr 2015 14:23 Prispevkov: 89 Aktiv.: 0.81 Kraj: Ljubljana
|
Objavljeno: Čet Sep 13, 2018 8:47 am Naslov sporočila: |
|
|
Težavo sem odpravil. Posredujem odgovor, če bo mogoče še kdo naletel na isto težavo.
Koraki objavljeni v predhodni objavi so pravilni.
V nadaljevanju je potrebno spremenljivko TEMP_MAX še dejansko vpisati v FLASH pomnilnik. Za uspešno vpisovanje spremenljivke v FLASH pomnilnik pa je potrebno flash najprej odkleniti:
Pobrisati vse zastavice:
Koda: |
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR); |
Sektor pobrisati:
Koda: |
FLASH_Erase_Sector(FLASH_SECTOR_11, VOLTAGE_RANGE_3); |
Spremenljivko postaviti v flash:
Koda: |
HAL_FLASH_Program(TYPEPROGRAM_WORD, &TEMP_MAX, TEMP_MAX); |
Če smo z vpisovanjem zaključili flash ponovno zaklenemo:
Pri tem pa se mi poraja vprašanje kam dejansko se ob prevajanju programa shrani TEMP_MAX spremenljivka preden jo prepišemo v flash. |
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.20 Kraj: Črnomelj
|
Objavljeno: Ned Sep 23, 2018 12:26 pm Naslov sporočila: |
|
|
zaz, delo s temi attribute-i pri tebi nima smisla, če hočeš dinamično spreminjati vsebino v flashu. Smiselno pa je, da sectione delaš pri RAM-u, če jih rabiš.
Če ti direktno odgovorim, kam se shrani, potem je odgovor "je del flash binary datoteke, in se ne shrani na določen flash naslov, kot si ti navedel v section".
Drugače pa je dobra praksa, da se naredi eno strukturo, ki se celotna shrani v flash.
Koda: |
// Struktura za tvoj flash
typedef struct {
/* Control section */
uint32_t magic;
uint32_t version;
/* Data section */
int temp_max;
int temp_min;
} flash_str_t;
|
Pri tem pa:
- magic: Vsebuje znano konstantno, s katero preveriš, če so nastavitve v flashu veljavne ali ne
- version: Trenutna verzija formata tvojih nastavitev. Vsakič, ko spremeniš format strukture (dodaš field, recimo humidity_max), ali pa odstraniš kakšen field (recimo temp_min te ne zanima več), povečaš številko v tvojem flashu.
Nekje v headerju določiš vrednosti, ki jih pričakuješ kot default za magic in version:
Koda: |
#define FLASH_SETTINGS_START_ADDR 0x08001000 /* Določiš naslov, kje v flashu bos imel stranjene nastavitve */
#define FLASH_MAGIC 0x12345678
#define FLASH_VERSION 4 //Vsakic, ko posodobis flash_str_t strukturo, takrat povecas stevilko za 1
|
V tvojem programu na začetku narediš spremenljivko tipa flash_str_t strukture.
Koda: |
//Recimo main.c
flash_str_t flash_settings;
void flash_settings_read(void);
void flash_settings_write(void);
int main(void) {
//Preberi nastavitve na začetku programa in jih skopiraj v RAM
flash_settings_read();
}
void
flash_settings_read(void) {
//Preberes vrednosti iz flasha direktno v strukturo locirano v RAM-u
memcpy(&flash_settings, (void *)FLASH_SETTINGS_START_ADDR, sizeof(flash_settings));
//Preveris, ce so podatki veljavni:
if (flash_settings.magic != FLASH_MAGIC || /* Flash se ni bil nikoli vpisan s strani aplikacije */
flash_settings.version != FLASH_VERSION) { /* Flash format struktura se je spremenila in moramo resetirati vrednosti */
//Nastavi default vrednosti
flash_settings.magic = FLASH_MAGIC;
flash_settings.version = FLASH_VERSION;
flash_settings.temp_max = 120; //Default max temperature by app
flash_settings.temp_min = -10; //Default min temperature by app
//Write data back to flash
flash_settings_write();
}
}
void
flash_settings_write(void) {
const uint8_t* data = (const void *)&flash_settings; //Pointer na podatke za v flash
size_t len = sizeof(flash_settings); //Velikost strukture za zapisat v flash
uint32_t addr = FLASH_SETTINGS_START_ADDR;
//Odkleni flash
HAL_FLASH_Unlock()
//Zbriši flash sector, ki ustreza FLASH_SETTINGS_START_ADDR naslovu
//Zapiši vse podatke, tukaj pričakujem, da ima struktura 4-byte alignment v velikosti
len = len >> 2;
while (len-- > 0) {
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, data);
addr += 4;
}
//Zakleni flash
HAL_FLASH_Lock();
} |
Kasneje, vedno, ko bo MCU hotel spremeniti nastavitve in jih straniti v flash, narediš to:
Koda: |
flash_settings.temp_max = ...;
flash_settings_write();
|
Tako imaš sedaj nove vrednosti v RAM-u in takoj imaš tudi write-back v flashu. RAM ti tukaj služi kot kakšen cache.
Zelo preprost example. _________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 76 dni
Powered by phpBB © 2001, 2005 phpBB Group
|