71717
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 だけ修正してビルド)：**

```

    プログラム１ ：hello world の表示して終了
                   nuttx.spk(163040 byte) : ELFファイル(4192 byte)
                   
    プログラム２ ：hello world の表示とmainでLEDの点滅10回して終了
                   nuttx.spk(163360 byte) : ELFファイル(8684 byte)
                   
    プログラム３ ：hello world の表示とmain, taskA, taskBでLEDの点滅10回して終了
                   nuttx.spk(163360 byte) : ELFファイル(11048 byte)
    
```

**起動テスト結果：**

```

    プログラム１の nuttx.spk 使用時は、プログラム１が動作　２，３はエラー
    プログラム２の nuttx.spk 使用時は、プログラム１、２が動作　３はエラー
    プログラム３の nuttx.spk 使用時は、プログラム１、２、３が動作
    
```
CC BY-SA 4.0
2020-10-20T07:56:02.840
71346
2020-11-04T08:10:26.910
2020-10-21T01:30:18.000
42312
42312
question
spresense
複数のローダブルELFを切り替えて実行しようとすると、実行できないELFファイルがある。
nuttxのローダブルELFの仕組みをみてみましたが、ビルド時に sdk/apps/symtab_apps.c
にシンボルテーブルを自動生成して、実行時にそのテーブルを参照してシンボル解決を行っているようです。組み合わせによってエラーになるのはおそらくそのアプリがシンボルテーブルに存在しない関数を使用しているためだと思います。

open/read/write/ioctl/closeのようにアプリから頻繁に使用するPOSIX関数や、それ以外にもアプリから使用する可能性のある関数については、それらがシンボルテーブルに含まれている状態でnuttx.spkを作成しておく必要があります。

言い換えると、シンボルテーブルに登録されている関数を使ったアプリ(ELF)であれば、ELFファイルを入れ替えても実行可能になると思います。
CC BY-SA 4.0
2020-11-04T08:10:26.910
71717
2020-11-04T08:10:26.910
31378
71346
answer