Raspberry Pi Zero向けのデバイスドライバを作る(本編)
デバイスドライバ作成
はじめに
この記事は前回の続きになります。
gari30.hatenablog.com
仕事が忙しく、あまり作業時間が取れない状況でしたが、
やっとこさ出来上がったので、ここにまとめておきます。
ターゲットデバイスはRaspberry Pi Zero WHになります。
参考にさせていただいたサイト様
(前回同様)RaspberryPi2上でデバイスドライバを作成する記事です。
リンクのページから連載されています。
組み込みLinuxデバイスドライバの作り方 (1) - Qiita
(前回同様)RaspbianとRaspbian Kernelについて説明がある記事です。
大変参考になりました。
Raspberry Pi でドライバ開発したい(基礎編) | なたで日記
出来たもの
詰まったところメモ
1. 環境変数設定スクリプト
参考にさせていただいたサイト様に記載のこちらのサイト を参考に、
クロスコンパイル環境の環境変数設定シェルスクリプトを作成しました。
deviceDriver/env.sh at master · Kyokko-OB-Team/deviceDriver · GitHub
. ./env.sh
のように、ドット(.)コマンドを使うと、
source ./env.sh
と同じ効果があるとのことを初めて知りました。
ドットコマンドを使うと、現在のコマンド実行環境で実行してくれるようです。
3. __aeabi_uldivmod 未定義エラー
ERROR: "__aeabi_uldivmod" [/home/xxxx/deviceDriver/hc-sr04/hc-sr04.ko] undefined!
kernel module内で浮動小数点を使用するとこのエラーが出るらしい。
distance = ((falling_timestamp - rising_timestamp) / 58) * 1000;
Cキャストをするようにした。
distance = ((unsigned int)(falling_timestamp - rising_timestamp) / 58) * 1000;
4. 認識されないコマンドラインオプション '-fstack-protector-strong'
arm-linux-gnueabihf-gcc: エラー: unrecognized command line option ‘-fstack-protector-strong’
raspberry pi toolchainのgccのバージョンが古いことで発生するらしい。
使用しているコンパイラのバージョンはこれ。
$ /mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc -v 組み込み spec を使用しています。 COLLECT_GCC=/mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc COLLECT_LTO_WRAPPER=/mnt/4tb/raspberrypi_kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../libexec/gcc/arm-linux-gnueabihf/4.8.3/lto-wrapper ターゲット: arm-linux-gnueabihf configure 設定: /home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/src/gcc-linaro-4.8-2014.03/configure --build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/install --with-sysroot=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --disable-multilib --enable-multiarch --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-isl=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-libelf=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gold --with-local-prefix=/home/zhehe01/work/bzr/pi-build/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long --with-float=hard スレッドモデル: posix gcc バージョン 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03)
回避策をggるとgccをアップデートしろ、と言われるが
raspberry pi用のクロスコンパイラはこれが最新版なのでアップデートできない。
csdnのこのページを参考に、kernelのMakefileを変更してエラーがでなくなった。
動作確認
カーネルモジュールをロードして、
テストアプリを実行して、
カーネルモールをアンロードして、
dmesg
でログを確認
$ sudo insmod ./hc-sr04/hc-sr04.ko $ sudo ./test_hc-sr04/test_hc-sr04 ./test_hc-sr04/test_hc-sr04 ver.0.1 exec measure distance. exec get distance. distance: 6310000mm $ dmesg (省略) [ 223.047133] hc_sr04: loading out-of-tree module taints kernel. [ 223.058371] hc_sr04 init. ver.0.1. [ 418.259926] hc_sr04 module exit.
特にエラーが出ないのでOK
デバイスドライバの動作環境をまとめる
デバイスドライバを動作させるカーネルセットも保存しておきたいので、
動作環境をまとめておきます。
// kernelディレクトリに移動 $ cd linux/ // 一時コピー先ディレクトリ作成 $ mkdir -p device_tree/overlays // デバイスツリーファイル群をコピー $ cp ./arch/arm/boot/dts/*.dtb ./device_tree/. $ cp ./arch/arm/boot/dts/overlays/*.dtb* ./device_tree/overlays/. // デバイスツリーファイル群をアーカイブにする $ cd device_tree/ $ tar -cvzf ../dtb.tar.gz * // モジュールファイルをビルド $ sudo make ARCH=arm INSTALL_MOD_PATH=./modules/ modules_install // モジュールファイル群をアーカイブにする $ cd modules/ $ tar -cvjf ../modules.tar.bz2 *
Raspberry Piで展開
まとめた動作環境ファイルをRaspberry Pi上にコピーしてから以下の様に
ファイルを展開する。
// カーネルイメージのバックアップ $ sudo cp /boot/kernel.img /boot/kernel-bk.img // カーネルイメージを更新 $ sudo cp ./kernel.img /boot/. // デバイスツリーファイルを展開 // 所有者を変更できません。とエラーが出るので、--no-same-ownerオプションをつける $ sudo tar --no-same-owner -xzvf ./dtb.tar.gz -C /boot/ // モジュールファイルを展開 $ sudo tar -xvjf ./modules.tar.bz2 -C / // 再起動して起動確認 $ sync $ sudo shutdown -r now
起動確認
まとめたデバイスドライバの動作環境をRaspberry Pi上で展開して
作成したカーネルモジュールとテストアプリでの動作確認をした。
OKだったので完璧!
以上