RaspberryPiのSoCにはCPU温度センサが内蔵されています。
CPU温度センサのハードウェア仕様と使い方などを調べてみました。
コマンドラインからのCPU温度センサへのアクセス
# cat /sys/class/thermal/thermal_zone0/temp
39000
# vcgencmd measure_temp
temp=39.0'C
Linux Kernel ソースコード
CPU温度センサドライバの最初のコミット「thermal: bcm2835: add thermal driver for bcm2835 SoC」
https://github.com/torvalds/linux/commit/bcb7dd9ef206f7d646ed8dac6fe7772083714253
温度センサのドライバソースコード
https://github.com/torvalds/linux/blob/master/drivers/thermal/broadcom/bcm2835_thermal.c
ソースコードを読むと、BCM2835_TS_TSENSCTL と BCM2835_TS_TSENSSTAT の二つのレジスタを使っていることが分かる。
レジスタ仕様
- Brcm_Android_ICS_Graphics_Stack.tar.gz のヘッダファイルに定義がある。
- https://github.com/msperl/rpi-registers/blob/master/md/Region_TS.md
BCM2835_TS_TSENSCTL 0x7e212000
- 制御に使うレジスタ
- リセットができる。
BCM2835_TS_TSENSSTAT 0x7e212004
- 値取得に使うレジスタ
- センサの10bit AD値が読み出せる。
CPU温度の取得
初期化
- offset と slope を取得
- offset と slopeの値はSoCのdtsiに書いてある。これをkernelのAPI経由で取得する。
- RPi1 : https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/bcm2835.dtsi の cpu_thermal
- RPi2 : https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/bcm2836.dtsi の cpu_thermal
- RPi3 : https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/bcm2837.dtsi の cpu_thermal
- 温度センサにクロックを供給する
- BCM2835_TS_TSENSCTLにデファルト値とレギュレータ有効の設定を書き込み
- BCM2835_TS_TSENSCTLに温度センサをリセットの指示
CPU温度の取得
- BCM2835_TS_TSENSSTATレジスタを読む
- 読み出した値の、BIT10 / BCM2835_TS_TSENSSTAT_VALID が1であること確認
- 読み出した値の、BIT0 から BIT9 を取り出しtempに格納
- offset + slope * temp の計算値がCPU温度、計算値が 20000 なら 20.000°Cとなる。
温度補正値について
RPi1/RPi2 ではoffsetとslopeの値は、407000と-538だが、RPi3ではこれだと5°C低い値になる。
なので、RPi3ではoffsetに5000を足して412000, -538を使う。
参考: https://marc.info/?l=linux-arm-kernel&m=146309555908312
dtsiに書く温度補正値の記述のフォーマットは thermal.txt に書いてある。
https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/thermal/thermal.txt
財団のLinuxカーネル
メインラインでなくでRaspberryPi Foundationのカーネルはどうなっているんだろうと調べたら、処理が違いました。
- GPUで動作するファームウェアにメールボックス経由してコマンドを送信してCPU温度を取得していました。
- https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/thermal/bcm2835-thermal.c
- GPUファームウェアで、温度を監視していたりするのでしょうか?
todo
- ベアメタルな環境でCPU温度センサにアクセスしてみる。
- レジスタの物理アドレスを調べる。