バグの説明
現在、MCU: NXP MIMXRT1061 CVL5A を搭載した開発ボードで Zephyr7.0 を実行しようとしています。サンプルをコンパイルしました: \samples\basic\blinky ですが、正しく実行できませんでした。最初は、Zephyr が正しく起動しない原因は XIP 形式の問題だと思っていましたが、SWD を使用してデバッグしたところ、正しく起動することがわかりました。ただし、呼び出し時: /zephyr/arch/arm/core/aarch32/prep_c.c: z_bss_zero(); 関数 Zephyr が失敗しました
コンパイルプロセス
私が使用しているボードは mimxrt1060_evk です。1061 は 1060 をベースにしているため、理論的には問題ありません。
- west build -p auto -b mimxrt1060_evk .\samples\basic\blinky\
- ウェストフラッシュ
デバッグプロセス
最初のデバッグは z_interrupt_stacks で中断されました
z_arm_reset () at C:/Users/zhihao3x/work/zephyrproject/zephyr/arch/arm/core/aarch32/cortex_m\reset.S:105
105 msr BASEPRI, r0
(gdb) n
134 ldr r0, =z_interrupt_stacks
(gdb) n
135 ldr r1, =CONFIG_ISR_STACK_SIZE + MPU_GUARD_ALIGN_AND_SIZE
(gdb) n
136 adds r0, r0, r1
(gdb) n
137 msr PSP, r0
(gdb)
138 mrs r0, CONTROL
(gdb)
139 movs r1, #2
(gdb)
140 orrs r0, r1 /* CONTROL_SPSEL_Msk */
(gdb)
141 msr CONTROL, r0
(gdb)
147 isb
(gdb)
154 bl z_arm_prep_c
(gdb)
134 ldr r0, =z_interrupt_stacks
(gdb)
Program received signal SIGTRAP, Trace/breakpoint trap.
(gdb)
その後、シングルステップ デバッグを使用したところ、Zephyr が z_bss_zero に到達したことがわかりました。
(gdb)
z_arm_floating_point_init ()
at C:/Users/zhihao3x/work/zephyrproject/modules/hal/cmsis/CMSIS/Core/Include/cmsis_gcc.h:1003
1003 __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
(gdb)
163 __set_CONTROL(__get_CONTROL() & (~(CONTROL_FPCA_Msk)));
(gdb)
0x6000305c in __set_CONTROL (control=3758157056)
at C:/Users/zhihao3x/work/zephyrproject/modules/hal/cmsis/CMSIS/Core/Include/cmsis_gcc.h:1003
1003 __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
(gdb)
1004 __ISB();
(gdb)
__ISB () at C:/Users/zhihao3x/work/zephyrproject/modules/hal/cmsis/CMSIS/Core/Include/cmsis_gcc.h:260
260 __ASM volatile ("isb 0xF":::"memory");
(gdb)
z_arm_prep_c () at C:/Users/zhihao3x/work/zephyrproject/zephyr/arch/arm/core/aarch32/prep_c.c:183
183 z_bss_zero();
(gdb) n
Program received signal SIGTRAP, Trace/breakpoint trap.
0x62652dc0 in ?? ()
最終的に memset 関数で問題を特定しました。この関数が呼び出されると、無限ループに陥り、プログラムがクラッシュします。
z_arm_prep_c () at C:/Users/zhihao3x/work/zephyrproject/zephyr/arch/arm/core/aarch32/prep_c.c:183
183 z_bss_zero();
(gdb)
z_bss_zero () at C:/Users/zhihao3x/work/zephyrproject/zephyr/kernel/init.c:89
89 (void)memset(__bss_start, 0, __bss_end - __bss_start);
(gdb)
memset (buf=0x80000030 <z_idle_threads>, c=c@entry=0, n=428)
at C:/Users/zhihao3x/work/zephyrproject/zephyr/lib/libc/minimal/source/string/string.c:355
(gdb)
Program received signal SIGTRAP, Trace/breakpoint trap.
0x63f5fbf8 in ?? ()
後で memset 関数をデバッグしようとしたところ、ループ中に dest アドレスが変更されないことがわかりました。非常に奇妙です。gdb の問題なのか、zephyr の問題なのかは特定していません。アドレスは、インクリメント前は 0x80000030、インクリメント後は 0x80000031 で、次のサイクルが繰り返されると 0x80000030 に戻ります。
357 unsigned char c_byte = (unsigned char)c;
(gdb)
389 while (n > 0) {
(gdb)
390 *(d_byte++) = c_byte;
392 n--;
(gdb) p d_byte
$1 = (unsigned char *) 0x80000030 <z_idle_threads> "\b"
z_bss_zero 関数を変更してみました
(void)memset(__bss_start, 0, __bss_end - __bss_start);
サイズ丈を変更しました
(void)memset(__bss_start, 0, 3);
しかし、gdbでデバッグしていると、memset内のwhileループが止まらずに3回超えてしまい、無限ループに陥ってしまいました。これら 2 行のコードの後のインクリメントされたコードに問題があると推測します。なぜなら、gdb print コマンドを使用してインクリメントごとに変数の値を出力すると、変数の値が変化しないからです。
*(d_byte++) = c_byte;
n--;
もう 1 つの奇妙な点は、gdb を使用してデバッグすると、ポインターがあることがわかります。Gdb はこちら側にブレークすることはありませんが、このコードをスキップして実行します。コンパイラが私にそれをしているとは思えません。コードは最適化されていますか?
詳細
next を使用して z_bss_zero を実行すると、gdb は 0xdeadbeee の不確定なアドレスにブレークします。おそらく、メモリの初期化時に Zephyr がスタックを破壊したのでしょう。
(gdb)
z_arm_prep_c () at C:/Users/zhihao3x/work/zephyrproject/zephyr/arch/arm/core/aarch32/prep_c.c:183
183 z_bss_zero();
(gdb) n
Program received signal SIGTRAP, Trace/breakpoint trap.
0xdeadbeee in ?? ()
同時に、Jlink デバッガーもエラー ログを出力します。
ERROR: Cannot read register 15 (R15) while CPU is running
Reading all registers
ERROR: Cannot read register 0 (R0) while CPU is running
ERROR: Cannot read register 1 (R1) while CPU is running
ERROR: Cannot read register 2 (R2) while CPU is running
ERROR: Cannot read register 3 (R3) while CPU is running
ERROR: Cannot read register 4 (R4) while CPU is running
ERROR: Cannot read register 5 (R5) while CPU is running
ERROR: Cannot read register 6 (R6) while CPU is running
ERROR: Cannot read register 7 (R7) while CPU is running
ERROR: Cannot read register 8 (R8) while CPU is running
ERROR: Cannot read register 9 (R9) while CPU is running
ERROR: Cannot read register 10 (R10) while CPU is running
ERROR: Cannot read register 11 (R11) while CPU is running
ERROR: Cannot read register 12 (R12) while CPU is running
ERROR: Cannot read register 13 (R13) while CPU is running
ERROR: Cannot read register 14 (R14) while CPU is running
ERROR: Cannot read register 15 (R15) while CPU is running
ERROR: Cannot read register 16 (XPSR) while CPU is running
ERROR: Cannot read register 17 (MSP) while CPU is running
ERROR: Cannot read register 18 (PSP) while CPU is running
ERROR: Cannot read register 24 (PRIMASK) while CPU is running
ERROR: Cannot read register 25 (BASEPRI) while CPU is running
ERROR: Cannot read register 26 (FAULTMASK) while CPU is running
ERROR: Cannot read register 27 (CONTROL) while CPU is running
ERROR: Cannot read register 32 (FPSCR) while CPU is running
ERROR: Cannot read register 33 (FPS0) while CPU is running
ERROR: Cannot read register 34 (FPS1) while CPU is running
ERROR: Cannot read register 35 (FPS2) while CPU is running
ERROR: Cannot read register 36 (FPS3) while CPU is running
ERROR: Cannot read register 37 (FPS4) while CPU is running
ERROR: Cannot read register 38 (FPS5) while CPU is running
ERROR: Cannot read register 39 (FPS6) while CPU is running
ERROR: Cannot read register 40 (FPS7) while CPU is running
ERROR: Cannot read register 41 (FPS8) while CPU is running
ERROR: Cannot read register 42 (FPS9) while CPU is running
ERROR: Cannot read register 43 (FPS10) while CPU is running
ERROR: Cannot read register 44 (FPS11) while CPU is running
ERROR: Cannot read register 45 (FPS12) while CPU is running
ERROR: Cannot read register 46 (FPS13) while CPU is running
ERROR: Cannot read register 47 (FPS14) while CPU is running
ERROR: Cannot read register 48 (FPS15) while CPU is running
ERROR: Cannot read register 49 (FPS16) while CPU is running
ERROR: Cannot read register 50 (FPS17) while CPU is running
ERROR: Cannot read register 51 (FPS18) while CPU is running
ERROR: Cannot read register 52 (FPS19) while CPU is running
ERROR: Cannot read register 53 (FPS20) while CPU is running
ERROR: Cannot read register 54 (FPS21) while CPU is running
ERROR: Cannot read register 55 (FPS22) while CPU is running
ERROR: Cannot read register 56 (FPS23) while CPU is running
ERROR: Cannot read register 57 (FPS24) while CPU is running
ERROR: Cannot read register 58 (FPS25) while CPU is running
ERROR: Cannot read register 59 (FPS26) while CPU is running
ERROR: Cannot read register 60 (FPS27) while CPU is running
ERROR: Cannot read register 61 (FPS28) while CPU is running
ERROR: Cannot read register 62 (FPS29) while CPU is running
ERROR: Cannot read register 63 (FPS30) while CPU is running
ERROR: Cannot read register 64 (FPS31) while CPU is running
ERROR: Cannot read register 33 (FPS0) while CPU is running
ERROR: Cannot read register 34 (FPS1) while CPU is running
ERROR: Cannot read register 35 (FPS2) while CPU is running
ERROR: Cannot read register 36 (FPS3) while CPU is running
ERROR: Cannot read register 37 (FPS4) while CPU is running
ERROR: Cannot read register 38 (FPS5) while CPU is running
ERROR: Cannot read register 39 (FPS6) while CPU is running
ERROR: Cannot read register 40 (FPS7) while CPU is running
ERROR: Cannot read register 41 (FPS8) while CPU is running
ERROR: Cannot read register 42 (FPS9) while CPU is running
ERROR: Cannot read register 43 (FPS10) while CPU is running
ERROR: Cannot read register 44 (FPS11) while CPU is running
ERROR: Cannot read register 45 (FPS12) while CPU is running
ERROR: Cannot read register 46 (FPS13) while CPU is running
ERROR: Cannot read register 47 (FPS14) while CPU is running
ERROR: Cannot read register 48 (FPS15) while CPU is running
ERROR: Cannot read register 49 (FPS16) while CPU is running
ERROR: Cannot read register 50 (FPS17) while CPU is running
ERROR: Cannot read register 51 (FPS18) while CPU is running
ERROR: Cannot read register 52 (FPS19) while CPU is running
ERROR: Cannot read register 53 (FPS20) while CPU is running
ERROR: Cannot read register 54 (FPS21) while CPU is running
ERROR: Cannot read register 55 (FPS22) while CPU is running
ERROR: Cannot read register 56 (FPS23) while CPU is running
ERROR: Cannot read register 57 (FPS24) while CPU is running
ERROR: Cannot read register 58 (FPS25) while CPU is running
ERROR: Cannot read register 59 (FPS26) while CPU is running
ERROR: Cannot read register 60 (FPS27) while CPU is running
ERROR: Cannot read register 61 (FPS28) while CPU is running
ERROR: Cannot read register 62 (FPS29) while CPU is running
ERROR: Cannot read register 63 (FPS30) while CPU is running
ERROR: Cannot read register 64 (FPS31) while CPU is running
Removing breakpoint @ address 0x60003068, Size = 2
WARNING: Failed to read memory @ address 0xDEADBEEE
Jlink出力
以下は、Jlink が出力する MCU 情報です。このバージョンが Zephyr でサポートされているかどうかはわかりません
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 2331
SWO raw output listening port: 2332
Terminal I/O port: 2333
Accept remote connection: localhost only
Generate logfile: off
Verify download: off
Init regs on start: off
Silent mode: on
Single run mode: on
Target connection timeout: 5000 ms
------J-Link related settings------
J-Link Host interface: USB
J-Link script: none
J-Link settings file: none
------Target related settings------
Target device: MIMXRT1062xxx6A
Target interface: SWD
Target interface speed: auto
Target endian: little
私は 7 日間懸命に努力しましたが、まだこの問題を解決できません。Zephyr のバージョンを切り替えてみたり、プラットフォーム IO を使用して elf ファイルと bin ファイルを生成したりしましたが、いずれも効果がありませんでした。私を助けてください。どうもありがとうございました。