質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1878閲覧

ESP32のファームウェアに個別パラメータ設定をしたい

Tanam

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/08/16 08:02

編集2021/08/16 08:04

前提・実現したいこと

VS2019+PlatormIOでESP32を使ったシステムを作成しています。

FlashROMの余った領域(例えば3F0000番地から256バイト程度)をパラメータ領域として使用することを考えています。
具体的にはプログラムをFLashに書き込んだ後、esptoolを使い装置毎に異なる個別パラメータを書き込んで使用することを考えています。

どなたかご存じの方、アドバイスをいただけないでしょうか ・・ 

発生している問題

 esptoolで書き込んだ場合、FlashROMのセクション単位での書き込みになるようです。
(0x1000番地単位の領域を消去~書き込みを行う)。
そのため一部だけ書き換えるなどを行うと、プログラムがほぼ暴走してしまいます。

 このようなことを実現することは可能なのでしょうか? 

試したこと

(1) 以下のようにsectiondef.csvを作成しました。
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x130000,
app1, app, ota_1, 0x150000,0x140000,
spiffs, data, spiffs, 0x290000,0x160000,
eeprom, data, 0x99, 0x3f0000,0x10000,

(2) またplatformio.iniに以下の定義を追加。
board_build.partitions = sectiondef.csv

(3) ソースコードには以下の定義を追加(テスト用として1024バイト)。
typedef struct {
char dat[ 1024 ] = { 0x00, 0x01, 0x02, ... };
} ESPPARAMS;
const PROGMEM ESPPARAMS espParams;

(4) ソースコードのsetup関数内には以下の処理を追加。

char *p = ( char * )&espParams; Serial.printf( "=> %x (%d)\r\n", p, sizeof( ESPPARAMS ) ); Serial.printf( "=> %x \r\n", p[ 0 ] ); Serial.printf( "=> %x \r\n", p[ 1 ] ); Serial.printf( "=> %x \r\n", p[ 2 ] ); Serial.printf( "=> %x \r\n", p[ 3 ] );

実行結果

このプログラムを実行すると以下のような実行結果になりました。

 => 3f400b60 (1024)
=> 0
=> 1
=> 2
=> 3

esptoolを使ってESP32の内容を読み出すと、該当データは 0x10b60番地からに存在していました。
試しに10b60番地を指定してパラメータを書き込むと、0x10000番地から0x10b5f番地までが消去(=0xff)されるので、プログラムが暴走してしまいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

例えば3F0000番地から256バイト程度

ならそこに書き込んで、番地指定でプログラムから読み出せばよいのではないですか?
なんでわざわざプログラムを壊しながら書くのでしょう?

Platform IOということはArduino環境なんでしょうか。Platform IOで使えるかは知りませんが、Arduino IDEならspiffsにファイルを流し込むツールなんてのもあるようですので(私自身は使ったことはありません)、とくにこだわりがあるのでなければそういのでもよいのでは。


ちょっと真面目に調べました。
ESP32-WROOM-02のSPIフラッシュからの読み出しにはspi_flash_readというAPI関数が使えるようです。
パーティションテーブルを

text

1# Name, Type, SubType, Offset, Size, Flags 2nvs, data, nvs, 0x9000, 0x5000, 3otadata, data, ota, 0xe000, 0x2000, 4app0, app, ota_0, 0x10000, 0x140000, 5app1, app, ota_1, 0x150000,0x140000, 6eeprom, data, 0x99, 0x290000,0x1000 7spiffs, data, spiffs, 0x291000,0x16F000,

esptoolで0x290000から

de ad be ef 00 00....あとしばらく00

を書き込んで、

Arduino

1void setup() 2{ 3 char data[1024]; 4 spi_flash_read(0x290000,data,1024); 5 Serial.begin(115200); 6 for (int i = 0; i < 1024; i++) { 7 printf("%02x ",data[i]); 8 if((i%16)==15){ 9 printf("\n"); 10 } 11 } 12} 13void loop(){}

を走らせると

de ad be ef 00 00 00 00 00 00 00 00 00 00 00 00 以下略

という表示が得られました。

やりたかったのはこういうことでいいんですよね?

投稿2021/08/16 12:22

編集2021/08/17 14:46
thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tanam

2021/08/16 23:46

・メモリーコントローラによってFlashの物理アドレスとプログラム実行時のアドレス配置が異なる。 ・ブート時にFlashからメモリ転送され、実行時にcsvファイルで定義されているものしか転送されていないように見える ・3F0000番地を単純にプログラム実行時にアクセスすると、CPUがハングしてしまう。 ・また同様にメモリーコントローラにて、ここに割り当てられているだろうと思い、そこにアクセスしても異なる値しか読めない、またはCPUハングなどになってしまう。 ・spiffsのツールは知ってましたが、お客様のところでArduinoIDEを実行させるわけにはいかないため、使いたくない。 ・・ このような理由で悪戦苦闘しているわけで、自分でできる限りのことを調べて、試して、それでも実現できなかったための書き込みであることご理解ください。
thkana

2021/08/17 14:49

私(に限らず回答者)は、あなたがやったことについて「質問に書かれていること」しか知りえません。 理解しておくべきことがあるのなら、先に書いておいてください。
guest

0

ベストアンサー

0x1000番地単位の消去となるなら、その設定パラメータ用の独立した0x1000のエリアを用意しておいて、そのエリアにパラメータ書き込みを行えばいいということになります

当然、プログラムコードではその番地に向けてアクセスする必要があります

投稿2021/08/16 10:48

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tanam

2021/08/16 23:52

ありがとうございます。 結局そうするしかないかなと。ただし目標となる領域は3f400b60番地に割り当てられていて、0x1000番地の切りの良いところでなく、Fash上のその直前には何等かのデータが入っていたため、0x2000分以上の領域を確保して、プログラム実行時には何番地に割り当てられるかなどを試行錯誤して実現するしかなさそうな気がします。 ややこしいですね。
y_waiwai

2021/08/17 00:14

まあ、かんたんにするなら、変数を集めた構造体を定義しておいて、そのポインタを介してその変数にアクセスするようにしときます。 んで、そのポインタに、その切りのいい領域のアドレス入れとけばいいです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問