質問: spresense sdk チュートリアルの、[17. ローダブルELFチュートリアル]を利用して プログラムの自動アップデートができればと思い、以下のテストをしました。 hello worldサンプルを使用して最初にビルドした nuttx.spk を spresense へ書き込み その後同じ環境で、そのサンプルソースを追加修正した複数パターンのELFファイルを作成し flashへ格納後、spresense上で "nsh>/mnt/spif/hello" として動作させようとすると、 ELFファイルによっては "command not found" となり実行できないものがあります。 nuttx.spk は一度作成して書き込んだ後は、ローダブルELFだけを作成して入れ替えれば良いと 思っていたのですが、ビルド時に何か他の設定が必要なのでしょうか? ヒントを頂ける方がいましたらよろしくお願いします。 環境:Windows10, SDK2.0.1, NUTTX8.2, VSCode1.50.0 **以下のプログラムを作成してテストしました (hello_main.c だけ修正してビルド):** ``` プログラム1 :hello world の表示して終了 nuttx.spk(163040 byte) : ELFファイル(4192 byte) プログラム2 :hello world の表示とmainでLEDの点滅10回して終了 nuttx.spk(163360 byte) : ELFファイル(8684 byte) プログラム3 :hello world の表示とmain, taskA, taskBでLEDの点滅10回して終了 nuttx.spk(163360 byte) : ELFファイル(11048 byte) ``` **起動テスト結果:** ``` プログラム1の nuttx.spk 使用時は、プログラム1が動作 2,3はエラー プログラム2の nuttx.spk 使用時は、プログラム1、2が動作 3はエラー プログラム3の nuttx.spk 使用時は、プログラム1、2、3が動作 ```
回答: nuttxのローダブルELFの仕組みをみてみましたが、ビルド時に sdk/apps/symtab_apps.c にシンボルテーブルを自動生成して、実行時にそのテーブルを参照してシンボル解決を行っているようです。組み合わせによってエラーになるのはおそらくそのアプリがシンボルテーブルに存在しない関数を使用しているためだと思います。 open/read/write/ioctl/closeのようにアプリから頻繁に使用するPOSIX関数や、それ以外にもアプリから使用する可能性のある関数については、それらがシンボルテーブルに含まれている状態でnuttx.spkを作成しておく必要があります。 言い換えると、シンボルテーブルに登録されている関数を使ったアプリ(ELF)であれば、ELFファイルを入れ替えても実行可能になると思います。