hiro99ma blog

何か技術的なこと

arm: Cortex-Mの割り込み

2024/09/05

ARM9系はあまり触っていなかったが、あちらは高速IRQというものがあった。
Cortex-M3はその系列からやり方が変わった。 どう変わったか説明できるほど詳しくないが、ARM9 や 11 を触っていた人は違うことに注意しようというだけだ。

説明しているサイトなどは多いので、個人的に印象深いところだけメモに残そう。

Vector Table

Cortex-M33 では Security Extension の有無でベクタテーブルが違う。

Cortex-M33 Vector table

ncs だと “NS” の有無というやつだ。

“Exception Number” と “IRQ Number” があるが、CMSIS では IRQ Number だけを使う(シンプルにするため)と書いてあった(Exception typesのNote)。

Hard Fault

発生して一番困るのが Hard Fault だと思っている。

DuckDuckGo

私もしばしば遭遇している。

hiro99ma blog: [nrf51]スケジューラを使ってGPIOハンドラからSPI転送するとHardFaultになった

何か間違っていることは分かるのだが、何かが足りなくて発生したのか、そもそもそういうことができないのか、みたいなところで悩んで時間がかかる。
上の私の例だと、割り込みハンドラから SPI 転送しようとしたら発生していた。 提供されている SPI 転送のドライバの中で割込禁止しようとしているが、ドライバを呼び出そうとしたのが割り込みハンドラの中だったので Hard Fault になったということらしい。 API の説明に「割り込みハンドラの中からは呼び出せません」とか書いてあれば気付いたのかもしれないが、たぶん記述はなかったのだろう。

割り込みハンドラの中であれこれやるのはよくないのだが、やれるけどよくないのか、そもそもやれないのかは結構違うと思う。 ボタンを押したら SPI 転送するだけのちょろっとしたプログラムだったらいいやん、と思ってしまう。 まあ、提供されたドライバではなく自分でレジスタをたたけばよいのだが。。。

ちなみに ncs の場合はこんな感じでログが出るようだ。

how to decipher HARD FAULT / MPU FAULT on zephyr running on nrf52832

ncs というよりも Zephyr kernel になるのかな。

SysTick

OS を載せるとだいたいなにがしかのタイマーがいるので、そういうときに SysTick を使うと思う。

が、Zephyr はタイミングのためのタイマーを使わないタイプ(tickless)だそうだ。 OS がスレッドのディスパッチなどのために tick を使わないというだけで、タイマーを持たないというわけではない。

では ncs では SysTick のところはどうなっているかというと、ここかな。 SysTick がないタイプもあるのでCONFIG_CPU_CORTEX_M_HAS_SYSTICKと、システムクロックを使う気があり(CONFIG_SYS_CLOCK_EXISTS)かつ SysTick 割込みも使う(CONFIG_CORTEX_M_SYSTICK_INSTALL_ISR)場合とそうでない場合で仕込むハンドラが違う。

ということは、nRF53 はどうなってるんだ?
nRF Kconfig GUI だと出てこないので build/zephyr/.config を見てみる。

CONFIG_CPU_CORTEX_M_HAS_SYSTICK=y
CONFIG_SYS_CLOCK_EXISTS=y

CONFIG_CORTEX_M_SYSTICK_INSTALL_ISRは出てこなかったので、z_arm_exc_spurious がテーブルには登録されているはず。
z_arm_exc_spurious が何者かはわからんが、mapファイル上ではz_arm_usage_faultz_arm_hard_faultと同じアドレスだったので、SysTick を有効にした途端に fatalエラー扱いになるんだろう。

< Top page