ローリングコンバットピッチなう!

AIとか仮想化とかペーパークラフトとか

raspberry pi 2 model B+とraspbian busterでI2Cを使用する(raspbianでI2Cが使えない場合の対処)

raspi-configだけでI2Cが有効にならない

最近、ラズパイのGPIOとかを触り始めました。
手元にラズパイマガジン2015年秋号があり、当時合わせて購入したブレッドボードだの、LEDだのセンサーだのの部品セットがあるのですが、Lチカすらやらずに放置していたのですが、最近機械学習とかで試すネタが涸渇して(あるにはあるのですが..)、ふと思い立って基本のLチカから試し始めました。

うちの会社は本来なら今週開催されているはずだった東京オリンピックに合わせて今週が夏休み。まとまった時間が取れるので、各センサー等にピンヘッダのハンダ付けとかやって準備。
I2C接続のキャラクター液晶ACM1602NIを、ラズパイマガジン見ながらセットアップ。

f:id:RC30-popo:20200805085639j:plain
raspberry pi2 MODEL B+とACM1602NI

こんな感じで繋いで、ラズパイマガジン出版元の日経BP社のサイトからDLしたサンプルプログラムを起動するも無情な「I/O Error」の表示。
配線を何度も確認しましたが、問題は無さそう。

ソフト問題っぽいなとあたりをつけてググると下記のサイトを発見。

blog.ashija.net

カーネルバージョンが上がるとダメで、4.4なら大丈夫なのでダウングレードしろと。

今使っているOSはこんな感じでraspbianはbuster、カーネルは5.4になっています。

pi@raspberrypi:~ $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.4.51-v7+ #1332 SMP Tue Aug 4 18:34:21 BST 2020 armv7l GNU/Linux

カーネルバージョン最新のままでも、古いbcm2708ドライバーのロードモジュールを入手して組み込めば良いという情報も書いてあるのですが、自分の環境では上手く動作せず、その間、/etc/modulesとか/boot/config.txtとか色々触っても解決せず。

結局は上記のブログの通り、下記コマンド実行して一旦カーネルのバージョンダウンを実施しました。

$ rpi-update 00a7eac6efc6ba29d94a7460f68215a1dbbdef0b

その状態でuname -aを実行すると。

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.4.47-v7+ #961 SMP Sun Feb 5 20:17:00 GMT 2017 armv7l GNU/Linux

ただしこれだけでは動かず、以下の対処が必要です。
/etc/modules

i2c-dev

これはrpi-configでI2Cをenableにすると追記されるはずですが、要確認。

/boot/config.txt
以下の2行が必要。baudtate=50000はACM1602NIに合わせた設定なので、使うI2Cデバイスの仕様に合わせて調整必要。

dtparam=i2c_arm=on
dtparam=i2c_baudrate=50000

あと、これは必要かどうか判らないのですが、/etc/modprobe.d/にblacklist-i2c-bcm2835.confというファイルを作り、

blacklist i2c-bcm2835

を入れておきます。
逆に同じディレクトリ内のconfファイルのいずれかに、

blacklist i2c-bcm2708

書かれていない事を確認します。

ここまでの対処でサンプルプログラムにエラーが出ずACM1602NIに文字を表示することに成功しました。

カーネルを最新版のままでraspberry pi 2 MODEL B+でI2Cを動かす

一応、カーネルバージョンを4.4まで戻す事でI2Cが使える様になったのですが、どうもすっきりしません。
宅内での実験にしか使わないので、セキュリティとかあまり気にはしていないのですが、やはり最新のカーネルで動かしたい。

ググったり、色々実験したりした結果から考察して以下の対処を行いました。

  1. カーネルバージョンを最新に戻す

    $ sudo rpi-udate

    完了後のバージョンを確認。

    pi@raspberrypi:~ $ cat /etc/os-release
    PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
    NAME="Raspbian GNU/Linux"
    VERSION_ID="10"
    VERSION="10 (buster)"
    VERSION_CODENAME=buster
    ID=raspbian
    ID_LIKE=debian
    HOME_URL="http://www.raspbian.org/"
    SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
    BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
    
    pi@raspberrypi:~ $ uname -a
    Linux raspberrypi 5.4.51-v7+ #1332 SMP Tue Aug 4 18:34:21 BST 2020 armv7l GNU/Linux
    

  2. /etc/modulesにi2c-devとi2c-bcm2708を設定

    以下の様になっていればOK。

    pi@raspberrypi:~ $ cat /etc/modules
    # /etc/modules: kernel modules to load at boot time.
    #
    # This file contains the names of kernel modules that should be loaded
    # at boot time, one per line. Lines beginning with "#" are ignored.
    
    i2c-bcm2708
    i2c-dev
    

  3. /boot/config.txtに以下を設定

    dtparam=i2c_arm=on
    dtoverlay=i2c-bcm2708
    dtparam=i2c_baudrate=50000

  4. /etc/modprobe.d/*.confでi2c-bcm2835をblacklist指定

    ついでにi2c-bcm2708がblacklist指定されていないことを確認。(書かれていたらコメントアウト)

    blacklist i2c-bcm2835

これでrebootします。
reboot後、以下を実行して、i2c_devとi2c_bcm2708が正常にロードされている事を確認。
lsmodでi2c_bcm2708が表示されていても、dmesgにエラー表示が出ていると上手く行っていない可能性大です。

pi@raspberrypi:~ $ lsmod | grep i2c
i2c_dev                16384  0
i2c_bcm2708            16384  0
pi@raspberrypi:~ $ dmesg | grep i2c
[    6.707652] bcm2708_i2c 3f804000.i2c: BSC1 Controller at 0x3f804000 (irq 77) (baudrate 50000)
[    6.712821] i2c /dev entries driver

これで2020/8時点のraspbian buster+最新カーネル(5.4)の組み合わせでI2Cが使える様になりました。

f:id:RC30-popo:20200805092340j:plain
ACM1602NI表示例

補足

raspbian buster+カーネル5.4で参考サイトに書かれている下記を試しましたが、上手く行きませんでした。

Just to repeat the entire process . . . .

Download the old module here.
Copy this file into /boot/overlays.
In /boot/config.txt add the line dtoverlay=i2c1-bcm2708 at the end.

どうやらraspbianのあるカーネルのバージョン以降、i2cドライバーのデフォルトがi2c-bcm2708からi2c-bcm2835というものに変わった事が原因らしいと関連サイトを読む限り判断できるのですが、raspbianが後方互換性を一切持たずにアップグレードされるのも変だなと思い、自分の環境を調べてみると/boot/overlaysの下にi2c-bcm2708.dtboというファイルを見つけました。これは上記のサイトに書いてあるi2c1-bcm2708.dtboとは別のファイルです。おそらくはrpi-updateでDLされたbcm2708用のローダブルモジュールで、出処怪しいi2c1-bcm2708.dtboではなくi2c-bcm2708.dtboをoverlayすれば良いのでは?と思いつきました。
これが/etc/modulesや/boot/config.txtにi2c-bcm2708を追加した理由です。

pi@raspberrypi:~ $ ls -l /boot/overlays | grep i2c
-rwxr-xr-x 1 root root    449  8月  4 18:37 bmp085_i2c-sensor.dtbo
-rwxr-xr-x 1 root root    270  8月  5 09:08 i2c-bcm2708.dtbo
-rwxr-xr-x 1 root root   1055  8月  5 09:08 i2c-gpio.dtbo
-rwxr-xr-x 1 root root   2185  8月  5 09:08 i2c-mux.dtbo
-rwxr-xr-x 1 root root    648  8月  5 09:08 i2c-pwm-pca9685a.dtbo
-rwxr-xr-x 1 root root   5680  8月  5 09:08 i2c-rtc-gpio.dtbo
-rwxr-xr-x 1 root root   5180  8月  5 09:08 i2c-rtc.dtbo
-rwxr-xr-x 1 root root   5336  8月  5 09:08 i2c-sensor.dtbo
-rwxr-xr-x 1 root root   1182  8月  4 18:37 i2c0-bcm2708.dtbo
-rwxr-xr-x 1 root root   1396  8月  5 09:08 i2c0.dtbo
-rwxr-xr-x 1 root root    854  8月  4 18:37 i2c1-bcm2708.dtbo
-rwxr-xr-x 1 root root   1004  8月  5 09:08 i2c1.dtbo
-rwxr-xr-x 1 root root    907  8月  5 09:08 i2c3.dtbo
-rwxr-xr-x 1 root root    907  8月  5 09:08 i2c4.dtbo
-rwxr-xr-x 1 root root    911  8月  5 09:08 i2c5.dtbo
-rwxr-xr-x 1 root root    909  8月  5 09:08 i2c6.dtbo
-rwxr-xr-x 1 root root   1353  8月  5 09:08 sc16is750-i2c.dtbo
-rwxr-xr-x 1 root root   1353  8月  5 09:08 sc16is752-i2c.dtbo