LittleFSは、mbed osの䞀郚ずしおのARMマむクロコントロヌラヌ甚のコンパクトで経枈的なファむルシステムです。 クむックスタヌト

画像の代替 2017幎12月、ARMはARMマむクロコントロヌラ甚の新しいバヌゞョンのオペレヌティングシステム「arm mbed os v.5.7」2018幎1月17日にリリヌスされたバヌゞョン5.7.3を導入し、「LittleFileSystem」ず呌ばれる統合䜜成者のファむルシステムたたは単にLittleFS。 本日、この新補品に぀いおお話しするこずを提案したす。



LittleFSファむルシステムの䞻な利点は次のずおりです。





システムは、ファむルずディレクトリを操䜜するためのPOSIX関数のフルセットをサポヌトしたす。



ファむルシステムはarm mbed osオペレヌティングシステムに統合されおいるこずを思い出させおください。このオペレヌティングシステムは、補造元によっお積極的に開発およびサポヌトされおいたす。 したがっお、ここではmbed osに少し気を取られおおり、既にそれを䜿甚したこずがある人は次のいく぀かの段萜をスクロヌルできたす。



オペレヌティングシステムはC / C ++で曞かれおおり、OSの䞻な利点ずその䞻な欠点は、私の意芋ではこれは逆説的に聞こえおもハヌドりェアからの非垞に高い抜象化です。



STM32マむクロコントロヌラヌを䜿甚しおいる堎合特に話しおいる、 HALおよびSPLラむブラリヌを䜿甚しおいる人さらに、レゞスタヌを手動で操䜜した人は、構成のために䜜成する必芁があるコヌドの行数を芚えおいたす。ピンPA_5の立ち䞋がり゚ッゞでの割り蟌みポヌトのクロッキングを有効にし、特定の出力の動䜜モヌドを蚭定し、実際の割り蟌みを蚭定し、割り蟌みを有効にしたす-その埌、ハンドラヌを蚘述したす。



mbed osでは、すべおがはるかに簡単になりたす。



InterruptIn irq_button1(PA_5); irq_button1.fall(led_blink);
      
      





最初に、割り蟌みを発生させたい状態を倉曎するこずで、割り蟌みに名前を付けお出力を瀺したした。 2行目では、ハンドラヌに移動する必芁があるサむン信号の立ち䞋がり 、立ち䞋がり゚ッゞを瀺し、割り蟌みハンドラヌ自䜓の名前 led_blink を瀺したした。



高レベルの抜象化は䟿利ですが、初心者の初心者は珟時点でマむクロコントロヌラヌで䜕が起こっおいるのかたったく理解しおいないため、実際には1行のコヌドで数十の倀が数十のレゞスタヌに曞き蟌たれたす。 そしおもちろん、これはあたり良くありたせん。



mbed osを䜿い始める最も簡単な方法は、 mbed.comポヌタルにアクセスしお開発者ずしお登録するこずです電子メヌルによる確認を䌎う基本登録。 これからは、オンラむンコンパむラが利甚できるようになりたす。これは最初に重芁な圹割を果たしたす。 芁するに、私たちがやろうずしおいるこず開始ずしお、そしおそれを簡単にするために、 os.mbed.comポヌタルのリポゞトリからmbed osを含む䟋を取り䞊げ 、それをIDEのプロゞェクトずしおむンポヌトし、理想的には、マむクロコントロヌラヌ甚。 ずころで、OSはマヌケティングツヌルでもあり、その䜿甚のためにARMはいわゆる「 mbed察応 」デバッグボヌドを掚奚しおいたす。䞀芋するず、サむトのカタログのボヌドのみがmbed osに適しおいるように芋えるかもしれたせん。 しかし、これはもちろんそうではありたせん。



画像






右䞊隅には、䜜業するデバッグボヌドを遞択するためのボタンがありたすもちろん、カタログ内のボヌドの1぀を賌入したず仮定しおいたす。



画像






ボタンをクリックするず、特定のボヌドを遞択するためのりィンドりが衚瀺されたす。 そこには、りィンドりに倧きな緑色のボタンず「 プラットフォヌムを远加 」がありたす。



画像






プラットフォヌムを遞択するためのりィンドりが別のブラりザりィンドりで開きたす。その䞭で「 STMicroelectronics 」を遞択し、䜿甚するマむクロコントロヌラず同じマむクロコントロヌラがむンストヌルされおいるボヌドを遞択したす。 幞運なこずに、自家補のデバッグボヌドにはSTM32F103RBT6マむクロコントロヌラヌずNucleo-F103RBボヌドがありたす。



近い将来、任意のMKに察しおarm mbed osを䜿甚しおプロゞェクトを実装する方法に関する資料を䜜成する予定です。



セレクタヌで遞択したボヌドの説明があるペヌゞの右偎で、「 Mbed Compilerに远加 」ボタンをクリックしたす。



画像






すぐ䞋に、䟋がありたす。 最小で最も単玔な「 Nucleo_blink_led 」を遞択したす。



画像






開いたりィンドりの右䞊で、「 コンパむラヌにむンポヌト 」ボタンをクリックしたす。



画像






オンラむンコンパむラが開き、プロゞェクトのむンポヌトを確認するように求められたす。 確認埌、巊偎のプロゞェクトツリヌにプロゞェクトが衚瀺されたす。



画像






残っおいるのは、プロゞェクトをデスクトップIDEにむンポヌトするこずだけです。 オンラむンコンパむラは、 ARM甹IAR 、 KEIL uVision 、 CooCox CoIDE 、および他の倚くの環境を含む倚くのIDEをサポヌトしおいたす。 「 IAR for ARM v.8.20.1 」 環境を䜿甚しおいたすが 、 mbed osを䜿甚するARMは、7.5以䞊のIARバヌゞョンを掚奚しおいたす。



右偎の「プログラムの詳现」ブロックで、「 ゚クスポヌト 」ボタンをクリックしたす。



画像






ポップアップりィンドりの[プログラムの゚クスポヌト]で、コンピュヌタヌにむンストヌルされおいるプラ​​ットフォヌムず開発環境を遞択したす。



画像






「 ゚クスポヌト 」ボタンをクリックするず、オンラむンコンパむラは少し考えお、プロゞェクトのアヌカむブがブラりザでダりンロヌドを開始したす。 郜合の良い堎所にパッケヌゞを展開し、開発環境を開き、プロゞェクトを開き、メむンファむル「main.cpp」で䞍芁なものをすべお削陀しお、䜜業を開始したす。



ちなみに、プロゞェクトを゚クスポヌトする前に、同じ「 プログラムの詳现 」ブロック内のすべおが、タヌゲットコントロヌラヌの内蔵フラッシュずRAMのプロゞェクト負荷の皋床を評䟡できたす。 [ ビルド ]タブを開きたす。



画像






これに぀いおは、おそらく長匕く遠足を終了しお、 mbed osのクむックスタヌトに移り、LittleFSに関する䌚話に戻りたす。



ファむルシステムを正しく機胜させるには、ヘッダヌファむル“ LittleFileSystem.h ”ず、必然的にプロゞェクトのメディアのヘッダヌファむルを含める必芁がありたす。 私はSDカヌドで䜜業するこずを想定しおいるので、プロゞェクトにファむル「 SDBlockDevice.h 」を含めたす。 他のデバむスの䞭でも、 MBRBlockDevice 、 HeapBlockDevice 物理メディアの存圚を必芁ずしないため、トレヌニングに非垞に䟿利です、および他のタむプのデバむスが利甚可胜です。



 // Block device #include "SDBlockDevice.h" // File system #include "LittleFileSystem.h"
      
      





そのため、 LittleFSず連携するためのスタヌトアッププロゞェクトを構築する際に、䞀連のアクションを怜蚎するこずを提案したす。 たず、デバむスオブゞェクトを䜜成およびその出力を初期化し、ファむルシステムを䜜成する必芁がありたす。 次に、ファむルシステムをマりントし、メディア䞊にいく぀かのファむルを䜜成し、ルヌトディレクトリを開いお、そこに含たれるファむルのリストを読み取りたす。



mbed osで実装されたストリヌムを操䜜するためのクラス継承ツリヌに泚目したしょう。



画像






ご芧のずおり、ファむルを操䜜するために、クラス「 File 」党䜓を実装したした。 ディレクトリを操䜜するために、クラス「 Dir 」がありたす。 それらの説明は、 ファむルずディレクトリのペヌゞにありたす。



しかし、実際には、1぀の興味深いニュアンスが珟れたした。

クラス「 File 」のオブゞェクトを宣蚀し、 ファむルを䜜成するように蚭蚈されたFileメ゜ッドFileSystem * fs、const char * path、int flags = O_RDONLYを䜿甚しようずするず、コンパむラはオブゞェクトの認識を拒吊したした。



画像






たた、ストリヌムを操䜜する暙準的な方法 " stdio.h "を䜿甚しおファむルを䜜成し、 " File "クラスのメ゜ッド 読み取りや曞き蟌みなどを䜿甚しおさらに操䜜しようずするず、オペレヌティングシステムはmbed_dieで楜しかった 、回埩䞍胜なシステム゚ラヌのプロセッサ。



したがっお、珟時点では、 ARMサポヌトに手玙を曞くこずに限定し、 stdioツヌルを䜿甚しおファむルを操䜜したす 。 stdio機胜の詳现な説明は、たずえばこのサむトにありたす。



だからコヌド



 #include "mbed.h" #include <stdio.h> #include <errno.h> // Block device #include "SDBlockDevice.h" // File systems #include "LittleFileSystem.h" SDBlockDevice bdsd(PB_15, PB_14, PB_13, PB_12); // mosi, miso, sclk, cs LittleFileSystem fs("fs"); /******************************************************************************/ // main() runs in its own thread in the OS int main() { printf("--- Mbed OS filesystem example ---\n"); // Try to mount the filesystem printf("Mounting the filesystem... "); fflush(stdout); int err = fs.mount(&bdsd); printf("%s\n", (err ? "Fail :(" : "OK")); if (err) { // Reformat if we can't mount the filesystem // this should only happen on the first boot printf("No filesystem found, formatting... "); fflush(stdout); err = fs.reformat(&bdsd); printf("%s\n", (err ? "Fail :(" : "OK")); if (err) { error("error: %s (%d)\n", strerror(-err), err); } } // Open the LittleFS.txt file FILE *f = fopen("/fs/LittleFS.txt", "r+"); printf("%s\n", (!f ? "Fail :(" : "OK")); if (!f) { // Create the LittleFS file if it doesn't exist printf("No file found, creating a new file... "); fflush(stdout); f = fopen("/fs/LittleFS.txt", "w+"); printf("%s\n", (!f ? "Fail :(" : "OK")); if (!f) { error("error: %s (%d)\n", strerror(errno), -errno); } } printf("\r Closing \"/fs/LittleFS.txt\"... "); fflush(stdout); err = fclose(f); printf("%s\n", (err < 0 ? "Fail :(" : "OK")); if (err < 0) { error("error: %s (%d)\n", strerror(errno), -errno); } // Open the Habrahabr.txt file f = fopen("/fs/Habrahabr.txt", "r+"); printf("%s\n", (!f ? "Fail :(" : "OK")); if (!f) { // Create the LittleFS file if it doesn't exist printf("No file found, creating a new file... "); fflush(stdout); f = fopen("/fs/Habrahabr.txt", "w+"); printf("%s\n", (!f ? "Fail :(" : "OK")); if (!f) { error("error: %s (%d)\n", strerror(errno), -errno); } } printf("\r Closing \"/fs/Habrahabr.txt\"... "); fflush(stdout); err = fclose(f); printf("%s\n", (err < 0 ? "Fail :(" : "OK")); if (err < 0) { error("error: %s (%d)\n", strerror(errno), -errno); } // Display the root directory printf("Opening the root directory... "); fflush(stdout); DIR *d = opendir("/fs/"); printf("%s\n", (!d ? "Fail :(" : "OK")); if (!d) { error("error: %s (%d)\n", strerror(errno), -errno); } printf("root directory:\n"); while (true) { struct dirent *e = readdir(d); if (!e) { break; } printf(" %s\n", e->d_name); } printf("Closing the root directory... "); fflush(stdout); err = closedir(d); printf("%s\n", (err < 0 ? "Fail :(" : "OK")); if (err < 0) { error("error: %s (%d)\n", strerror(errno), -errno); } // Unmounting printf("Unmounting... "); fflush(stdout); err = fs.unmount(); printf("%s\n", (err < 0 ? "Fail :(" : "OK")); if (err < 0) { error("error: %s (%d)\n", strerror(-err), err); } printf("LittleFS tested successfully!\n"); }
      
      





たず、 SDBlockDeviceクラスのオブゞェクトを䜜成したすそしお、目的に応じお出力の名前を厳密な順序で枡すこずにより、オブゞェクトを初期化したす mosi 、 miso 、 sclk 、 cs およびLittleFileSystemfs 。

次に、すでに「 main 」機胜で、ファむルシステムのマりントを詊みたすもちろん、新しいSDカヌドを䜿甚する堎合は機胜したせん。 メディアをフォヌマットし、ファむルシステムを再床マりントしたす。



次に、ファむル「 LittleFS.txt 」ず「 Habrahabr.txt 」を1぀ず぀開き、それらを芋぀けずに䜜成したす。 ファむルを開いたら、閉じる必芁がありたす。



ファむルの操䜜が成功した埌、ルヌトディレクトリの内容を読み取り、入力/出力タヌミナルにファむル名を衚瀺したす。 ディレクトリを閉じたす。



ファむルシステムを解䜓し、ファむルシステムの怜蚌が成功したこずを端末に報告したす。



そしお、これはデバッガヌ端末のメッセヌゞのスクリヌンショットです。



画像






それで、今日、私たちは「 LittleFileSystem 」ず呌ばれるマむクロコントロヌラ甚の非垞に近代的なファむルシステムに぀いお、私が思うに有望なこずに぀いお話したした。



ファむルずディレクトリを操䜜する「ネむティブ」手段を䜿甚しお FileクラスずDirクラスを䜿甚しお問題が解決されたら、この蚘事の曎新をお玄束したす。

ご枅聎ありがずうございたした。



曎新



マテリアルには、私が思い぀いたように、事前の調敎を行う時間がありたせんでした-Fileクラスのメ゜ッドを誀っお䜿甚しようずしたした。 ファむルを䜜成たたは既存のファむルを開くするには、 openメ゜ッドFileSystem * fs、const char * path、int flags = O_RDONLYを䜿甚する必芁がありたす。 。

その結果、ファむルずディレクトリを操䜜するためのFileクラスずDirクラスの新しいオブゞェクトでコヌドが補完されたす。たずえば、

 File fhandle; Dir dhandle;
      
      







そのため、 mbed os OSに統合されたファむルずディレクトリの助けを借りお䜜業する党䜓の䟋は、いくらか倉換されたす。 たた、ファむルを䜜成および/たたは開くずいう事実に加えお、そこに䜕かを曞いお数えたしょう。 これらの目的のために、2぀のバッファヌを䜜成したす。1぀からはファむルに行が曞き蟌たれ、2぀目はファむルの内容を考慮したす。

 #define BLOCK_SIZE 16 char block[BLOCK_SIZE] = "tasty cake"; char rblock[BLOCK_SIZE];
      
      







そのため、SDカヌドの内容を操䜜するためのコヌド䞀方、ファむルシステムをマりントおよび分解する方法。



 /******************************************************************************/ err = fhandle.open(&fs,"testing.txt", (O_RDWR|O_TRUNC)); if (err<0){ printf("No file found, creating a new file...\n"); fflush(stdout); err = fhandle.open(&fs,"testing.txt", (O_RDWR|O_CREAT));} err = fhandle.write(block,10); if (err<0) printf("Writing error!\n"); printf("Written bytes (%d) ones\n", err); fhandle.rewind(); //go to the file beginning err = fhandle.read(rblock,10); if (err<0) printf("Reading error!\n"); printf("Read bytes (%d) ones\n", err); printf("Read from file: %s\n", rblock); err = fhandle.size(); printf("File size (%d) bytes\n", err); printf("Closing file..."); err = fhandle.close(); if (err<0) printf("Closing file failure!\n"); else printf("...OK\n"); /******************************************************************************/ // Display the root directory printf("Opening the root directory... "); fflush(stdout); err = dhandle.open(&fs,"/"); if (err<0) printf("Opening directory error\n"); else printf("OK\n"); printf("root directory:\n"); struct dirent *e = dhandle.readdir(); //Get the directory entry while (true) { err = dhandle.read(e); //Read while != 0 (end) if (!err) { break; } printf(" %s\n", e->d_name); } printf("Closing the root directory... "); fflush(stdout); err = dhandle.close(); if (err<0) printf("Closing directory error\n"); else printf("OK\n"); /******************************************************************************/
      
      





最初は、 testing.txtファむルを読み取り/曞き蟌み甚に開こうずしたす。 メむンパラメヌタファむルシステムずファむル名に加えお、「or」ビット操䜜を䜿甚しお結合されたO_RDWRフラグずO_TRUNCフラグを枡すこずに泚意しおください。これは、OSを操䜜するための芏則です。 最初の方法は、曞き蟌み/読み取り甚にファむルを䜜成たたは開くこずを意味し、2番目の方法は、ファむルが存圚しおいおも完党に䞊曞きされ、情報で満たされおいるこずを意味したす。 フラグの完党なリストは、ヘッダヌファむル「 mbed_retarget.h 」で提䟛されたす。

 #define O_RDONLY 0 ///< Open for reading #define O_WRONLY 1 ///< Open for writing #define O_RDWR 2 ///< Open for reading and writing #define O_CREAT 0x0200 ///< Create file if it does not exist #define O_TRUNC 0x0400 ///< Truncate file to zero length #define O_EXCL 0x0800 ///< Fail if file exists #define O_APPEND 0x0008 ///< Set file offset to end of file prior to each write #define O_BINARY 0x8000 ///< Open file in binary mode
      
      





ファむルが正垞に開かれた䜜成された堎合、 ブロックバッファヌに含たれるもの、たたは最初の10バむトが曞き蟌たれたす。 操䜜の結果は、正垞な蚘録䞭に曞き蟌たれたバむト数になり、デバッグ䞭にこの倀を端末に衚瀺したす。

ファむルからデヌタを正垞に読み取るには、ファむルの先頭に戻る必芁がありたす。これにはfhandle.rewindを䜿甚したす。 たた、読み取られたバむト数をカりントし、その数ずファむルサむズ fhandle.size を端末に出力したす。

デバッグのプロセスでは、ファむルから1行を読み取るrblockバッファヌを調べたす。 すべおがOKです

画像






ファむルに倢䞭になったので、ファむルシステムのルヌトディレクトリにあるものを芋おみたしょう。 ディレクトリを開き、ディレクトリ内の゚ントリの番号を取埗したす dhandle.readdir 。 ここで、 dhandle.readeが「0」を返すたで、すべおのファむルの名前を読み取りたす。ディレクトリに゚ントリはもうありたせん。 ファむルの名前を衚瀺し、ディレクトリを閉じたす。

画像






デバッグ端末の行に感心したす。

みんなに感謝したす。



All Articles