MIMXRT1180-EVK LittleFS サンプルは、DCache が無効になっていない限り、外部フラッシュで失敗します。 こんにちは、 Zephyr LittleFS サンプル ( https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/subsys/fs/littlefs ) を実行しようとしています。CM33コアを使用して外部フラッシュ(W25Q128JWSIQ)に書き込んでいますが、問題が発生しています。 サンプルをデフォルト設定で実行しようとすると、約90%の確率で失敗します。フラッシュメモリを消去してファイルシステムを再構築するオプションをオンにすると、ほぼ毎回失敗するようです。 失敗するタイミングは様々ですが、ログは通常次のような内容になります。 ネタバレ (ハイライトして読む) *** Zephyr OSビルドv4.3.0-6239-g28cd602a81eaを起動しています*** littlefs上のファイルを読み書きするためのサンプルプログラム w25q128jw@0 の 0xe20000 にある領域 3、1966080 バイト [00:00:00.022,000] main: フラッシュ領域を消去しています... 0 [00:00:00.028,000] littlefs: LittleFS バージョン 2.11、ディスクバージョン 2.1 [00:00:00.037,000] littlefs: w25q128jw@0:0xe20000 の FS は 480 個の 0x1000 バイトのブロックで、512 サイクルです [00:00:00.047,000] littlefs: パーティションサイズ: rd 16 ; pr 16 ; ca 64 ; la 32 [00:00:00.055,000] littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1386:{0x0, 0x1} のディレクトリペアが破損しています [00:00:00.066,000] littlefs: マウントできません (LFS -84); フォーマット[00:00:00.118,000] littlefs: /lfs がマウントされました /lfs マウント: 0 /lfs: bsize = 16 ; frsize = 4096 ; blocks = 480 ; bfree = 478 ディレクトリ /lfs を一覧表示しています... [00:00:00.150,000] littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:2109:スーパーブロック0x0は書き込み不能になりました [00:00:00.161,000] fs: ファイルオープンエラー (-5) [00:00:00.167,000] main: 失敗: /lfs/boot_count を開けません: -5 [00:00:00.174,000] littlefs: /lfs がマウントされていません /lfs アンマウント: 0 *** Zephyr OSビルドv4.3.0-6239-g28cd602a81eaを起動しています***w25q128jw@0 の littlefsArea 3 の 0xe20000 にある 1966080 バイトのファイルを読み書きするサンプル プログラム[00:00:00.022,000] main: フラッシュ領域を消去しています... 0[00:00:00.028,000] littlefs: LittleFS バージョン 2.11、ディスク バージョン 2.1[00:00:00.037,000] littlefs: w25q128jw@0:0xe20000 の FS は 480 個の 0x1000 バイトのブロックで構成され、512 サイクル[00:00:00.047,000] があります。 littlefs: パーティションサイズ: rd 16 ; pr 16 ; ca 64 ; la 32[00:00:00.055,000] littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1386:{0x0, 0x1}[00:00:00.066,000] でディレクトリペアが破損しています littlefs: マウントできません (LFS -84); フォーマット中[00:00:00.118,000] littlefs: /lfs マウント済み/lfs マウント: 0/lfs: bsize = 16 ; frsize = 4096 ; blocks = 480 ; bfree = 478ディレクトリ /lfs を一覧表示中...[00:00:00.150,000] littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:2109:スーパーブロック 0x0 が書き込み不能になりました[00:00:00.161,000] fs: ファイルオープンエラー (-5)[00:00:00.167,000] main: 失敗: /lfs/boot_count を開けません: -5[00:00:00.174,000] littlefs: /lfs アンマウント /lfs アンマウント: 0 ある時点で「スーパーブロック0x0が書き込み不能になりました」というエラーが発生し、サンプルが失敗します。 Kconfigオプション「CONFIG_DCACHE=n」でDCacheを無効にするとサンプルが確実に動作することがわかったので、これはキャッシュの問題だと考えています。 ネタバレ (ハイライトして読む) *** Zephyr OSビルドv4.3.0-6239-g28cd602a81eaを起動しています*** littlefs上のファイルを読み書きするためのサンプルプログラム w25q128jw@0 の 0xe20000 にある領域 3、1966080 バイト [00:00:00.060,000] main: フラッシュ領域を消去しています... 0 [00:00:00.069,000] littlefs: LittleFS バージョン 2.11、ディスクバージョン 2.1 [00:00:00.127,000] littlefs: w25q128jw@0:0xe20000 の FS は 480 個の 0x1000 バイトのブロックで、512 サイクルです [00:00:00.139,000] littlefs: パーティションサイズ: rd 16 ; pr 16 ; ca 64 ; la 32 [00:00:00.151,000] littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1386:{0x0, 0x1} のディレクトリペアが破損しています [00:00:00.164,000] littlefs: マウントできません (LFS -84); フォーマット[00:00:00.235,000] littlefs: /lfs がマウントされました /lfs マウント: 0 /lfs: bsize = 16 ; frsize = 4096 ; blocks = 480 ; bfree = 478 ディレクトリ /lfs を一覧表示しています... /lfs/boot_count 読み取り回数:0 (バイト数: 0) /lfs/boot_count に新しいブートカウント 1 を書き込みます: [wr:1] [00:00:00.297,000] main: テストファイル: /lfs/pattern.bin が見つかりません。作成してください。 ------ ファイル: /lfs/pattern.bin ------ 01 55 55 55 55 55 55 55 02 55 55 55 55 55 55 55 03 55 55 55 55 55 55 55 04 55 55 55 55 55 55 55 05 55 55 55 55 55 55 55 06 55 55 55 55 55 55 55 07 55 55 55 55 55 55 55 08 55 55 55 55 55 55 55 09 55 55 55 55 55 55 55 0a 55 55 55 55 55 55 55 0b 55 55 55 55 55 55 55 0c 55 55 55 55 55 55 55 0d 55 55 55 55 55 55 55 0e 55 55 55 55 55 55 55 0/55 55 55 55 55 55 55 10 55 55 55 55 55 55 55 11 55 55 55 55 55 55 55 12 55 55 55 55 55 55 55 13 55 55 55 55 55 55 55 14 55 55 55 55 55 55 55 15 55 55 55 55 55 55 55 16 55 55 55 55 55 55 55 17 55 55 55 55 55 55 55 18 55 55 55 55 55 55 55 19 55 55 55 55 55 55 55 1a 55 55 55 55 55 55 55 1b 55 55 55 55 55 55 55 1c 55 55 55 55 55 55 55 1d 55 55 55 55 55 55 55 1e 55 55 55 55 55 55 55 1f 55 55 55 55 55 55 55 20 55 55 55 55 55 55 55 21 55 55 55 55 55 55 55 22 55 55 55 55 55 55 55 23 55 55 55 55 55 55 55 24 55 55 55 55 55 55 55 25 55 55 55 55 55 55 55 26 55 55 55 55 55 55 55 27 55 55 55 55 55 55 55 28 55 55 55 55 55 55 55 29 55 55 55 55 55 55 55 2a 55 55 55 55 55 55 55 2b 55 55 55 55 55 55 55 2c 55 55 55 55 55 55 55 2d 55 55 55 55 55 55 55 2e 55 55 55 55 55 55 55 2f 55 55 55 55 55 55 55 30 55 55 55 55 55 55 55 31 55 55 55 55 55 55 55 32 55 55 55 55 55 55 55 33 55 55 55 55 55 55 55 34 55 55 55 55 55 55 55 35 55 55 55 55 55 55 55 36 55 55 55 55 55 55 55 37 55 55 55 55 55 55 55 38 55 55 55 55 55 55 55 39 55 55 55 55 55 55 55 3a 55 55 55 55 55 55 55 3b 55 55 55 55 55 55 55 3c 55 55 55 55 55 55 55 3d 55 55 55 55 55 55 55 3e 55 55 55 55 55 55 55 3f 55 55 55 55 55 55 55 40 55 55 55 55 55 55 55 41 55 55 55 55 55 55 55 42 55 55 55 55 55 55 55 43 55 55 55 55 55 55 55 44 55 55 55 55 55 55 55 45 55 aa [00:00:00.659,000] littlefs: /lfs がマウントされていません /lfs アンマウント: 0 *** Zephyr OSビルドv4.3.0-6239-g28cd602a81eaを起動しています***w25q128jw@0 の littlefsArea 3 の 0xe20000 にある 1966080 バイトのファイルを読み書きするサンプル プログラム[00:00:00.060,000] main: フラッシュ領域を消去しています... 0[00:00:00.069,000] littlefs: LittleFS バージョン 2.11、ディスク バージョン 2.1[00:00:00.127,000] littlefs: w25q128jw@0:0xe20000 の FS は 480 個の 0x1000 バイトのブロックで構成され、512 サイクル[00:00:00.139,000] があります。 littlefs: パーティションサイズ: rd 16 ; pr 16 ; ca 64 ; la 32[00:00:00.151,000] littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1386:{0x0, 0x1}[00:00:00.164,000] でディレクトリペアが破損しています littlefs: マウントできません (LFS -84); フォーマット中[00:00:00.235,000] littlefs: /lfs マウント済み/lfs マウント: 0/lfs: bsize = 16 ; frsize = 4096 ; blocks = 480 ; bfree = 478 ディレクトリ /lfs を一覧表示中 .../lfs/boot_count 読み取り回数:0 (バイト数: 0)/lfs/boot_count 新しいブートカウントを書き込む 1: [wr:1][00:00:00.297,000] main: テストファイル: /lfs/pattern.bin が見つかりません。作成してください!------ファイル: /lfs/pattern.bin ------01 55 55 55 55 55 55 55 02 55 55 55 55 55 55 5503 55 55 55 55 55 55 55 04 55 55 55 55 55 55 55 5505 55 55 55 55 55 55 55 06 55 55 55 55 55 55 5507 55 55 55 55 55 55 55 08 55 55 55 55 55 55 55 5509 55 55 55 55 55 55 55 0a 55 55 55 55 55 55 550b 55 55 55 55 55 55 55 55 0c 55 55 55 55 55 55 55 550d 55 55 55 55 55 55 55 55 0e 55 55 55 55 55 55 55 550f 55 55 55 55 55 55 55 10 55 55 55 55 55 55 5511 55 55 55 55 55 55 55 12 55 55 55 55 55 55 55 5513 55 55 55 55 55 55 55 14 55 55 55 55 55 55 5515 55 55 55 55 55 55 55 16 55 55 55 55 55 55 55 17 55 55 55 55 55 55 55 18 55 55 55 55 55 55 55 55 19 55 55 55 55 55 55 55 1a 55 55 55 55 55 55 55 1b 55 55 55 55 55 55 55 1c 55 55 55 55 55 55 55 1d 55 55 55 55 55 55 55 1e 55 55 55 55 55 55 55 55 1f 55 55 55 55 55 55 55 20 55 55 55 55 55 55 55 21 55 55 55 55 55 55 55 22 55 55 55 55 55 55 55 23 55 55 55 55 55 55 55 24 55 55 55 55 55 55 55 25 55 55 55 55 55 55 55 26 55 55 55 55 55 55 55 27 55 55 55 55 55 55 55 28 55 55 55 55 55 55 55 29 55 55 55 55 55 55 55 2a 55 55 55 55 55 55 552b 55 55 55 55 55 55 55 2c 55 55 55 55 55 55 552d 55 55 55 55 55 55 55 2e 55 55 55 55 55 55 552f 55 55 55 55 55 55 55 30 55 55 55 55 55 55 5531 55 55 55 55 55 55 55 32 55 55 55 55 55 55 5533 55 55 55 55 55 55 55 34 55 55 55 55 55 55 5535 55 55 55 55 55 55 55 36 55 55 55 55 55 55 5537 55 55 55 55 55 55 55 38 55 55 55 55 55 55 5539 55 55 55 55 55 55 55 3a 55 55 55 55 55 55 553b 55 55 55 55 55 55 55 3c 55 55 55 55 55 55 553d 55 55 55 55 55 55 55 3e 55 55 55 55 55 55 553f 55 55 55 55 55 55 55 40 55 55 55 55 55 55 5541 55 55 55 55 55 55 55 42 55 55 55 55 55 55 5543 55 55 55 55 55 55 55 44 55 55 55 55 55 55 5545 55 aa[00:00:00.659,000] littlefs: /lfs アンマウント /lfs アンマウント: 0 しかし、DCache を有効にしたまま、フラッシュの変更 (書き込みと消去、ドライバレベルではなくサンプルレベル) のたびに "sys_cache_data_flush_and_invd_all()" を使用して DCache をフラッシュおよび無効化し、割り込みを "irq_lock()" でロックしても、やはり動作しません。 DCacheを無効にすることは一時的な回避策としては有効ですが、本番システムには理想的ではありません。動作させるために何か見落としている点があるのでしょうか? MCUXpresso SDKに付属しているフラッシュメモリにアクセスするサンプルは正常に動作するため、おそらくZephyrまたはその設定に問題があると考えられます。 フラッシュにアクセスする他のZephyrサンプルでも同様の挙動が見られ、DCacheを無効にした場合のみ安定したアクセスが可能になりますが、それらについては徹底的なテストは行っていません。 技術情報: ボード:NXP MIMXRT1180-EVK(CM33コア)をマイクロUSB経由でWindows PCからパススルーしてUbuntu VMに接続 OS: Zephyr v4.3.0-6239-g28cd602a81ea IDE: Ubuntu上のVS Code用MCUXpresso 26.3.72(Zephyr開発者ソフトウェアキット4.3付き) プロジェクトKconfig: ネタバレ (ハイライトして読む) # # 著作権 (c) 2019 Peter Bigot Consulting, LLC # # SPDX-License-Identifier: Apache-2.0 # # オプションでファイルシステムの再作成を強制する CONFIG_APP_WIPE_STORAGE=y CONFIG_DEBUG=y CONFIG_NO_OPTIMIZATIONS=y CONFIG_LOG=y CONFIG_PRINTK=y CONFIG_SHELL=y CONFIG_LOG_DEFAULT_LEVEL=3 CONFIG_LOG_BACKEND_UART=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_UART_CONSOLE=y CONFIG_FILE_SYSTEM=y CONFIG_FILE_SYSTEM_LITTLEFS=y CONFIG_MAIN_STACK_SIZE=4096 CONFIG_FLASH=y CONFIG_FLASH_MAP=y # フラッシュメモリを確実に動作させるために必要な回避策 CONFIG_DCACHE=n ## Copyright (c) 2019 Peter Bigot Consulting, LLC## SPDX-License-Identifier: Apache-2.0##オプションでファイルシステムの再作成を強制します CONFIG_APP_WIPE_STORAGE=yCONFIG_DEBUG=yCONFIG_NO_OPTIMIZATIONS=yCONFIG_LOG=yCONFIG_PRINTK=yCONFIG_SHELL=yCONFIG_LOG_DEFAULT_LEVEL=3CONFIG_LOG_BACKEND_UART=yCONFIG_LOG_MODE_IMMEDIATE=yCONFIG_UART_CONSOLE=yCONFIG_FILE_SYSTEM=yCONFIG_FILE_SYSTEM_LITTLEFS=yCONFIG_MAIN_STACK_SIZE=4096CONFIG_FLASH=yCONFIG_FLASH_MAP=y# フラッシュを確実に動作させるために必要な回避策CONFIG_DCACHE=n どんなご協力でもありがたいです。 よろしくお願いします、 ジェイソン Re: MIMXRT1180-EVK LittleFS sample fails on external flash unless DCache is disabled こんにちは、エドウィンさん。 この問題解決にご協力いただきありがとうございます。しかし、ご提案いただいた解決策がよく理解できません。同じ例はFreeRTOSでも動作し、LWIPスタックやミドルウェアは一切関与していません。Zephyrでは動作せず、FreeRTOSでは動作する、単純なLittleFSフラッシュの読み書きの例です。 重要なバッファデータはキャッシュ不可能なメモリに格納する必要があることは理解していますが、Zephyrが提供するもの以外に、そのようなサブシステムやソフトウェアは存在しません。つまり、Zephyrドライバまたはサブシステム内で問題の原因となっている可能性のあるバッファを特定し、それらをキャッシュ不可能なメモリに移動させることを提案しているのですか? どのバッファーがよくある原因なのか、ご説明いただき、ご経験を共有していただけると幸いです。 よろしくお願いいたします トーマス Re: MIMXRT1180-EVK LittleFS sample fails on external flash unless DCache is disabled こんにちは、 @JasonPD さん。
この問題の原因は間違いなくキャッシュ関連であり、具体的には、以下の記事で説明されている内容です。 「i.MXRT でキャッシュされていないメモリを使用する」
前述のとおり、この問題はLwIPのようなミドルウェアを使用している場合に最も顕著に現れ、Dキャッシュを完全に無効にするのではなく、重要なデータをキャッシュ不可能なメモリ領域に配置することで解決できます。
問題の本質をより深く理解するために、その投稿と参照されているアプリケーションノート( i.MXRT L1キャッシュの使用)を確認し、記事の推奨事項に従ってLwIPミドルウェアが正しく機能するようにしてください。
BR、 エドウィン。 Re: MIMXRT1180-EVK LittleFS sample fails on external flash unless DCache is disabled さらに調べて、フラッシュドライバ「flash_mcux_flexspi_nor.c」を見てみました。その中に、書き込みと消去後に現金が無効化される仕組みが定義ガードによって保護されているのを見つけました。 #ifdef CONFIG_HAS_MCUX_CACHE 現在当社が独占的に使用しているCM33の場合、KConfファイルには次のように記載されています。 config SOC_MIMXRT1189_CM33 HAS_MCUX_XCACHE を選択してください CM7の場合は次のようになります。 config SOC_MIMXRT1189_CM7 HAS_MCUX_CACHE を選択します。 フラッシュドライバの定義ガードを次のように調整しました。 #if defined(CONFIG_HAS_MCUX_CACHE) || defined(CONFIG_HAS_MCUX_XCACHE) この変更により、フラッシュメモリへの書き込みと消去がエラーなく行えるようになりました。XIPとDCacheを再度有効にし、すべてのIRQ無効化を解除しました。今のところはうまくいっているようです。 NXPの視点から見て、この解決策は理にかなっているかどうか、ご意見をいただけますか?フラッシュメモリにアクセスする際、依然としてIRQを無効にする必要がありますか? よろしくお願いいたします トーマス
查看全文