Spuštění LittleFS (NVRAM s omezením zápisu do flash paměti) / Habr
Všechno je lepší, když to má uvnitř NVRAM.

Prolog
V programování MCU je někdy nutné řešit opravdu složité problémy. Složitost spočívá jak z algoritmického hlediska, tak v množství kódu, který je třeba napsat.
Zde je názorný příklad. Potřebujete spustit NVRAM na mikrokontroléru, kde není možnost zapisovat paměťové intervaly (například FC7300x). Upřímně řečeno, ne každý programátor mikrokontroléru je schopen takovou NVRAM vyvinout. Abyste vytvořili NVRAM s podmínkou zákazu zápisu, potřebujete nějakou seriózní algoritmickou přípravu (dvojitě propojené seznamy, stromy, defragmentace paměti atd.).
Existují dva přístupy k programování
- Napište si všechno sami. Je to těžké. Ale máte kontrolu nad každým řádkem kódu v projektu a můžete implementovat velmi flexibilní produktovou politiku.
- Přeneste softwarové komponenty z Open-Source (třetí strany). Je to rychlé. Ale ztrácíte kontrolu nad funkčností.
Nicméně ať se na to díváte jakkoli, někdy musíte pracovat s kódem třetí strany. A teď se takový případ stal.
Vyjádření problému
Uspořádejte NVRAM na mikrokontroléru s jednorázovou flash pamětí. Spusťte souborový systém LittleFs na mikrokontroléru. Pochopte, jak konfigurovat LittleFs.
Požadavky na NVRAM
1 – Povolit zápis dat libovolná délka (a nejen mocniny dvou).
2—Ne nechat před nahráváním Stránky flash paměti.
3 – NVRAM musí podporovat Líné psaníNezapisujte data, pokud již existují.
4 – Pokud mytí blesk, pak sektory o 8k bajtech
5 – Pokud psát blesk, pak pouze stránky 128 bajtů.
6—Pište na zarovnané adresa (128 bajtů)
7—Prát s podšívkou adresa (8 kB)
8 – Získejte kód na Si
9—Racionální používání paměti Nor-Flash (optimalizace odolnosti). Nezapisujte vždy na jedno místo
10 – Data musí být chráněna před náhlou ztrátou. výpadky proudu (tolerance při výpadku napájení).
11—Jednoduchost implementace tak, aby se nic nerozbilo.
12 – Soubor musí se rychle najde podle názvu (13 – Soubor musí rychle se zaregistrujte (14 – Soubor musí rychle umýt (15—Kompaktnost kódu, který implementuje tento algoritmus NVRAM. Čím méně kódu, tím více souborů můžete načíst.
To jsou omezení. Je to normální, ne?
Definice
Abyste správně pochopili zdrojové kódy LittleFs, musíte jasně rozumět těmto konceptům.
zarovnaná adresa — adresa, která může nabývat hodnot s určitou periodou počínaje nulou. Periodami zarovnaných adres jsou obvykle hodnoty mocnin dvojky: 128 nebo 8192.
Paměťový sektor — zarovnaný kus paměti o velikosti 8 kB
třetí stranou — kód zvenčí. Softwarová komponenta, kterou jste si stáhli z internetu.
Блок — v podstatě se jedná o sektor flash paměti. LittleF maže po blocích. V mém mikrokontroléru má blok velikost 8 kB.
Page — minimální možná velikost pro zápis. V mém současném mikrokontroléru má stránka 128 bajtů. Paměťová stránka je zarovnaný kus paměti o velikosti 128 bajtů.
NVRAM — energeticky nezávislá paměť (NV) s náhodným přístupem (RAM). V podstatě Key Val-Map(ka). Může ukládat jakákoli binární data spojená s jejím identifikačním číslem.
meč (dvojité slovo) je 4bajtová proměnná (32 bitů).
slovo — Toto je dvoubajtová proměnná (16 bitů)
byte – toto je 8bitová proměnná
data — pole hexadecimálních bajtů o zadané délce
Soubor — je pojmenované binární pole bajtů v paměti. Paměť může být RAM, ROM (Flash), FRAM, EEPROM, SD karty, kompaktní disky, diskety, magnetická páska, sklo. Cokoli. Co znamená slovo pojmenovaný? Znamená to, že k těmto datům lze přistupovat pomocí hodnoty. Nechť je to přirozené 32bitové číslo. Je to jednodušší. Protože se jedná o pole, je zřejmé, že je také třeba uložit délka tohoto pole.
Líné psaní — je algoritmus zápisu, který zapisuje data pouze tehdy, pokud se ve skutečnosti v paměti nenacházejí. Pokud se taková data již nacházejí, procedura zápisu jednoduše nic nedělá a vrací OK. Je to jako když si chcete do telefonu zapsat nové číslo a ono tam už je, tak ho už znovu nezapíšete.
Prozkoumejte problém
FatF není vhodný, protože neposkytuje stabilitu při výpadku napájení. FatF nemá mechanismus pro vyrovnávání opotřebení paměťových polí Flash. FatF se obvykle spouští na SD kartách, které implementují mechanismus pro opotřebení Flash paměti.
uskutečnění
Před deseti lety jsem byl svědkem toho, jak jsme obešli absenci plnohodnotné NVRAM. Vypadá to takto. Obvodoví konstruktéři dali do desky 3 nebo 6 GPIO pinů a pomocí jumperů nastavili binární kód na GPIO, aby při spuštění dali firmwaru nějaký příkaz. Ukázalo se, že 1x3x6 = 18 krychlových milimetrů na 1 bit. Normální, že? NVRAM na jumperech je nejvýraznějším příkladem zuřivého technického zoufalství. V tomto textu jsem napsal, jak s minimálním úsilím naprogramovat plnohodnotnou NVRAM.
Už jsem měl texty o různých algoritmických implementacích NVRAM. Zde jsou.
Jméno
URL
Typ
NVRAM pro mikrokontroléry
NVRAM na externí SPI-NOR Flash paměti
Všechny tyto implementační algoritmy NVRAM fungují pouze tehdy, je-li možné vzít a předzáznam Adresy flash paměti. Je však třeba poznamenat, že takový luxus prostě není u mnoha rodin mikrokontrolérů dostupný! Ano. Den předtím jsem narazil na MCU s jednorázovou flash pamětí. Nebýt omezení Flashe, zvolil bych stávající odladěný algoritmus a tím by to skončilo. Omezení mě však přiměla hledat různé alternativní mechanismy pro budování souborových systémů na mikrokontroléru.
Po rozsáhlém a intenzivním výzkumu této problematiky jsem zjistil, že existuje open-source projekt s názvem LittleFsRozhodl jsem se, že to zkusím zvládnout.
Vzdělávací program LittleFs
Little Fs je malý, chybově odolný souborový systém navržený speciálně pro mikrokontroléry a napsaný v čistém jazyce C (C99). Má tři klíčové vlastnosti:
Odolnost vůči výpadkům napájení — littlefs je navržen tak, aby zvládal náhodné výpadky napájení. Všechny operace se soubory mají silnou záruku kopírování při zápisu a v případě výpadku napájení se souborový systém vrátí do posledního známého provozního stavu. Dynamické vyrovnávání opotřebení — littlefs je navržen s ohledem na flash paměť a poskytuje vyrovnávání opotřebení dynamických bloků. Kromě toho dokáže littlefs detekovat vadné bloky a obejít je. Omezená RAM/ROM — littlefs je navržen pro práci s malým množstvím paměti. Využití RAM je přísně omezené, což znamená, že spotřeba RAM se nemění s růstem souborového systému. Souborový systém neobsahuje neomezenou rekurzi a dynamická paměť je omezena na konfigurovatelné vyrovnávací paměti, které lze staticky přidělovat.
Nejdřív jsem se pokusil spustit LittleFS jako konzolovou aplikaci pro Windows na svém notebooku. Zpočátku se zdálo, že LittleFS vůbec nefunguje. Po cyklech zápisu a čtení souboru (block_cycles) souborový systém zhroutí a přestane cokoli dělat. Ukázalo se, že jsem zapomněl přidat tento člen do výpočtu fyzické adresy. ofsetPak jsem zjistil, že LittleFs úspěšně zapisuje a čte až do přetečení prvního sektoru. Ukázalo se, že při čtení a zápisu bylo nutné násobit Blok nemá 128 bajtů, ale 8192 bajtů. Výsledkem je, že se vykrystalizoval správný konfigurační kód pro FC7300 MC. Zde je.
#include "little_fs_config.h" #include "data_utils.h" #include "sw_nor_flash.h" #include "log.h" #define LITTLE_FS_NOR_FLASH_NUM 1 #define LITTLE_FS_BLOCK_SIZE 8192 #define LITTLE_FS_PAGE_SIZE 128 #define LITTLE_FS_CACHE_SIZE (LITTLE_FS_PAGE_SIZE) #ifdef LFS_NO_MALLOC // Optional statically allocated read buffer. // Must be cache_size. // By default lfs_malloc is used to allocate this buffer. static uint8_t readBuffer[LITTLE_FS_CACHE_SIZE] = ; static uint8_t progBuffer[LITTLE_FS_CACHE_SIZE] = ; static uint8_t lookaheadBuffer[LITTLE_FS_PAGE_SIZE] = ; #endif static int FlashToLittleFsRet(bool res) < int ret = LFS_ERR_OK; if (false == res) < ret = LFS_ERR_CORRUPT; >return ret; > static int user_provided_block_device_prog(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) < int ret = LFS_ERR_CORRUPT; bool res = false; LOG_NOTICE(LITTLE_FS, "Write,Block:%u,OffSet:%u,Size:%u", block, off, size); uint32_t phy_address = 0; phy_address = block * LITTLE_FS_BLOCK_SIZE + off; res = sw_nor_flash_write(LITTLE_FS_NOR_FLASH_NUM, phy_address, (uint8_t*) buffer, size); ret = FlashToLittleFsRet(res); return ret; >static int user_provided_block_device_read(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) < int ret = 0; LOG_DEBUG(LITTLE_FS, "Read,Block:%u,OffSet:%u,Size:%u", block, off, size); uint32_t phy_address = 0; phy_address = block * LITTLE_FS_BLOCK_SIZE + off; bool res = sw_nor_flash_read(LITTLE_FS_NOR_FLASH_NUM, phy_address, (uint8_t*) buffer, (uint32_t) size); ret = FlashToLittleFsRet(res); return ret; >static int user_provided_block_device_erase(const struct lfs_config* c, lfs_block_t block) < int ret = LFS_ERR_CORRUPT; LOG_WARNING(LITTLE_FS, "EraseBlock:%u", block); uint32_t phy_address = block * LITTLE_FS_BLOCK_SIZE; bool res = sw_nor_flash_erase_mem(LITTLE_FS_NOR_FLASH_NUM, phy_address, LITTLE_FS_BLOCK_SIZE); ret = FlashToLittleFsRet(res); return ret; >static int user_provided_block_device_sync(const struct lfs_config* c) < int ret = LFS_ERR_OK; LOG_INFO(LITTLE_FS, "Sync"); return ret; >const LittleFsConfig_t LittleFsConfig[] = < < .num = 1, .valid = true, .name = "LittleFs1", .cfg = < // block device operations .read = user_provided_block_device_read, .prog = user_provided_block_device_prog, .erase = user_provided_block_device_erase, .sync = user_provided_block_device_sync, #ifdef LFS_NO_MALLOC .read_buffer = readBuffer, .prog_buffer = progBuffer, .lookahead_buffer = lookaheadBuffer, #endif // block device configuration .read_size = LITTLE_FS_PAGE_SIZE, .prog_size = LITTLE_FS_PAGE_SIZE, .cache_size = LITTLE_FS_CACHE_SIZE, .lookahead_size = LITTLE_FS_PAGE_SIZE, .block_cycles = 4, .block_size = LITTLE_FS_BLOCK_SIZE, .block_count = 4, >, >, >; S největší pravděpodobností budete chtít zobrazit obsah složek. To lze provést takto.
bool little_fs_list(uint8_t num, const char* const path) < bool res = false; LOG_INFO(LITTLE_FS, "%u,path:[%s]", num, path); const table_col_t cols[] = < < 5, "N" >, < 17, "name" >, < 9, "size" >, < 5, "type" >, < 5, "type" >, >; LittleFsHandle_t *Node = LittleFsGetNode(num); if(Node) < uint32_t cnt = 0; lfs_dir_t dir = < 0 >; int err = lfs_dir_open(&Node->lfs, &dir, path); res = LittleFsRetToRes(err); if(err) < table_header(&(curWriterPtr->stream), cols, ARRAY_SIZE(cols)); struct lfs_info FileInfo = < 0 >; bool loop = true; while(loop) < int ret = lfs_dir_read(&Node->lfs, &dir, &FileInfo); if(ret < 0) < LOG_ERROR(LITTLE_FS, "ReadDirErr"); loop = false; break; >else < LOG_DEBUG(LITTLE_FS, "ReadOk %s", LittleFsFileInfoToStr(&FileInfo)); cnt++; >if(0 == ret) < loop = false; break; >char temp[150] = < 0 >; strcpy(temp, TSEP); snprintf(temp, sizeof(temp), "%s %3u " TSEP, temp, cnt); snprintf(temp, sizeof(temp), "%s %15s " TSEP, temp, FileInfo.name); snprintf(temp, sizeof(temp), "%s %7u " TSEP, temp, FileInfo.size); snprintf(temp, sizeof(temp), "%s %3u " TSEP, temp, FileInfo.type); snprintf(temp, sizeof(temp), "%s %3s " TSEP, temp, LittleFsTypeToStr(FileInfo.type)); cli_printf("%s"CRLF, temp); > table_row_bottom(&(curWriterPtr->stream), cols, ARRAY_SIZE(cols)); err = lfs_dir_close(&Node->lfs, &dir); if(err) < res = false; >> > return res; > Obsah kořenového adresáře můžete vypsat přímo do konzole.

Spuštění NVRAM
Souborový systém běží. Můžeme zapisovat a číst pojmenovaná pole do energeticky nezávislé paměti Flash mikrokontroléru. Nádhera! To ale není vše. Nyní musíme nějak interpretovat uložená data. Musíme přidat NVRAM. Proč potřebujeme NVRAM? Účel NVRAM je následující:
1 – zapsat výchozí hodnoty, pokud nebyly v paměti souborového systému při spuštění zařízení.
2 – specifikujte, jak interpretovat binární datové pole umístěné v souborovém systému do reálné fyzické proměnné.
Základní myšlenkou je vytvořit binární soubor s příponou * pro každou položku NVRAM..nvram (nebo *Název souboru NVRAM má jednotnou strukturu. Například soubor ID_123.nvram je položka NVRAM s indexem 123. Podle ID čísla se rozlišuje samostatná softwarová komponenta. NVRAM analyzuje, co je zapsáno uvnitř binárního souboru. Zde je malá nápověda. V podstatě se jedná o vyhledávací tabulku, která vám pomůže pochopit, jak rozpoznat, co čtete ze souboru LittleFs.
ID
datový typ
Jmenování
Ford Sync 3 nahrazuje starší systémy MyFord Touch Sync 2 ve vozidlech z roku 2016 a novějších. Dobrou zprávou je, že pokud vlastníte vůz z let 2011 až 2015, je velká šance, že budete moci upgradovat na nový systém Sync 3. Pokud chcete upgradovat svůj starší model, existují určité rozdíly, které byste měli být si vědom. Ponoříme se hlouběji do těchto rozdílů, abyste lépe porozuměli tomu, jak aktualizace funguje a proč je Sync 3 nejlepší volbou pro systém infotainmentu na středové konzole.

Sync 2 vs Sync 3
Telefonní spojení
Není žádným překvapením, že Sync 3 bude podporovat některé z nejnovějších vylepšení v konektivitě smartphonů.
Za prvé, Sync 2 a Sync 3 mají jedno společné: připojení Bluetooth.
Ať už používáte Sync 2 nebo Sync 3, budete moci připojit telefon k autorádiu přes Bluetooth. Bohužel je známo, že Sync 2 má po určitém počtu let závady Bluetooth. Když k tomu dojde, všimnete si, že Sync 2 začne přerušovat hovory a nemusí přehrávat hudbu přes Bluetooth. V tuto chvíli by vaší nejlepší možností bylo upgradovat na Sync 3 místo výměny za repasovaný modul Sync 2.
Za druhéSync 2 je omezena na vestavěné navigační služby.
Pokud je tato funkce povolena ve vašem vozidle vybaveném Sync 2, budou navigační mapy načteny z karty SD umístěné v rozbočovači středové konzoly. Se Sync 3 můžete používat různé zdroje navigace, od vestavěných navigačních map (pokud je vaše jednotka vybavena) až po Apple CarPlay a Android Auto.
SYNC 3
SYNC 2
Hardwarové rozdíly mezi Sync 2 a Sync 3
SYNC 2 APIM

Zadní strana modulu Ford Sync 2 APIM
Toto je SYNC 2 APIM. Můžete říct, že je to Sync 2, protože má obdélníkový tvar a malá žebra chladiče. Zařízení Sync 2 se dodávají v několika variantách, některá se dvěma porty USB, některá pouze s jedním. Všechna zařízení Sync 2 budou mít 54pinový konektor.
Co byste měli vědět o Sync 2
APIM Sync 2 používá externí modul GPS, běžně nazývaný GPSM. Tento modul lze nalézt ve většině amerických vozidel 2011+, ale chybí u mnoha globálních vozidel. To znamená, že i když nemusíte přidávat anténu GPS jako u Sync 3, možná budete muset GPSM dodatečně vybavit, pokud vaše vozidlo není podporováno.
Ve všech APIM Sync 2 můžete povolit navigaci. Pokud váš modul nemá aktivovanou navigaci, lze ji aktivovat naprogramováním ve FORScan. Poté, co povolíte mapy v Sync 2, musíte mít SD kartu s mapami, abyste mohli používat navigační funkce.
Obrazovky Sync 2 a Sync 3 NENÍ zaměnitelné. Sync 2 používá odporový displej (vzpomeňte si, jaké byly dotykové telefony před iPhonem), zatímco Sync 3 používá kapacitní displej (jako iPhone).
Sync 2 NEPODPORUJE Apple CarPlay ani Android AutoPokud tyto funkce nutně potřebujete, měli byste mít Sync 3.
Všechna vozidla vybavená Sync 2 lze upgradovat na Sync 3, stačí si pořídit obrazovku Sync 3, APIM, rozbočovač a adaptér rozbočovače a trochu programování.
SYNC 3 APIM

Zadní strana modulu Ford Sync 2 APIM
Toto je Sync 3 APIM. Je to Sync 3 poznáte podle nepravoúhlého tvaru, velkých žebrování chladiče a dvou modrých konektorů na levé straně. Sync 3 APIM se v průběhu let změnily, takže pokračujte ve čtení a dozvíte se více.
Co byste měli vědět o Sync 3
CarPlay není ve výchozím nastavení na vozidlech z roku 2016 povoleno. Pokud CarPlay ve vašem autě nefunguje, budete muset aktualizovat synchronizaci a upgradovat na rozbočovač USB, který je kompatibilní s Apple Carplay.
APIM Sync 3 nemá vestavěnou GPS anténu, musíte použít externí anténu GPS na navigačních i nenavigačních zařízeních.
SYNC 3 Nenavigační zařízení také vyžadují externí anténu GPSa také k synchronizaci hodin s časem GPS a poskytnutí podrobné polohy záchranným službám po nehodě.
Sync 3 Non-Navigation & Navigation bloky jsou zcela odlišné modulya neexistuje žádný skutečný způsob, jak poznat rozdíl pouhým pohledem na ně. Používají stejný typ základní desky, ale používají zcela odlišné dceřiné desky, které mají buď 8 GB paměti na nenavigačním modulu, nebo 32 GB na navigačním modulu mapy USA. Evropa: 16 GB / 64 GB s Navi.
Pokud má váš navigační modul Sync 3 verzi softwaru 3.3 nebo starší, můžete jej aktualizovat, abyste získali novější mapy.