jade: タッチスクリーンは扱えるのか (3)
2025/05/24
はじめに
Blockstream Jade のコードを M5Stack Core2 で動かしたいシリーズ。
今は、ほとんどコードを修正せずに M5Core2 の設定ファイルらしきものを読み込ませたが、 タッチスクリーン関係で HALT しているので調査しているところである。
I2C の二重初期化
ようやく原因が分かった。
touchscreen_task()
の最初に _i2c_init_master() を呼び出しているのだが、
これがどうも 2回目の呼び出しになっているようだ。
1回目は _power_i2c_init() だった。
昨日 の最後に載せた “ESP_ERROR_CHECK failed: esp_err_t 0x103 at 0x40119b9b” はスタックトレースの始まりで出力されたものではなかったのだ。
ESP_ERROR_CHECK()
という名前だったのでエラーが起きたらその行を基点にスタックトレースを出力すると思っていたのだよ。
なんで気付いたかというと、昨日載せたログの先にずらずらと出力があるのだが、そこにこういう出力があったのだ。
�clogX=E (1866) i2c.common: I2C bus id(0) has already been acquired
�clogX(E (1866) i2c.common: acquire bus failed
2回呼び出したりするのはありがちよね、とスルーしていたのだが、ログを追加して確認するとこのときのエラーコードが ESP_ERR_INVALID_STATE
だったのだ。
幸いなことに _power_i2c_init()
で呼び出したときにハンドル値をグローバル変数に保存してあったので、
_i2c_init_master()
内で ESP_ERR_INVALID_STATE
が起きたときはグローバル変数のハンドル値を返す、ということにすると動くようになった。
ただ、操作をしているとしばしばこんな感じで画面が変になる。
タッチして操作すると画面が動くので、HALT しているわけではない。
ログにも何も出てこないので、少なくともエラーがあると認識しているわけではないようだ。
エラー行数のずれ
エラーの行番号がずれたのは inc ファイルを #include
していたことが影響しているのだろうか?
それにしてはログを追加しても行数がその分ずれていたりして正確といえば正確だ。
しばしば clean もしていたのでビルドし忘れということもないだろう。
goto
で TRY-CATCH 的なことをするマクロかとも思っていたのだが、ESP_OK
でなかったら abort()
するという普通のマクロだった。
#include <touchscreen.inc>
しているのにプリプロセッサされた後の行番号にならないのはなぜだろうか?
ESP-IDF のこの定義になると思う。
#define ESP_ERROR_CHECK(x) do { \
esp_err_t err_rc_ = (x); \
if (unlikely(err_rc_ != ESP_OK)) { \
_esp_error_check_failed(err_rc_, __FILE__, __LINE__, \
__ASSERT_FUNC, #x); \
} \
} while(0)
普通に __FILE__
や __LINE__
を使っているだけだ。
gcc で確認したところ、#include
していても元の場所を見ているようだ。
その1
- main.c
#include "err.h"
#include "code.inc"
int main(void)
{
ESP_ERROR_CHECK(error_happen());
return 0;
}
- code.inc
int error_happen(void)
{
return -1;
}
- err.h
#ifndef ERR_H_
#define ERR_H_
#include <stdio.h>
#define ESP_ERROR_CHECK(x) do { \
int err_rc_ = (x); \
if (err_rc_ != 0) { \
printf("ERROR file:%s line:%d err:%d\n", \
__FILE__, __LINE__, x); \
} \
} while(0)
#endif /* ERR_H_ */
- 結果
__LINE__
は呼び出した行番号で __FILE__
も呼び出したファイル名になった。
$ gcc -o tst main.c
$ ./tst
ERROR file:main.c line:6 err:-1
その2
- main.c
#include "code.inc"
int main(void)
{
error_happen();
return 0;
}
- code.inc
#include "err.h"
void error_happen(void)
{
ESP_ERROR_CHECK(-1);
}
- err.h
“その1” と同じなので省略
- 結果
どちらも code.inc 側を指していた。
$ gcc -o tst main.c
$ ./tst
ERROR file:code.inc line:5 err:-1