树莓派2 B+任务栏(LXPanel)不断闪烁消失(RASPBIAN STRETCH WITH DESKTOP)

长时间不用的一个树莓派2 B+,使用的系统为RASPBIAN STRETCH WITH DESKTOP。在重新加电后,任务栏(LXPanel)不断闪烁消失,貌似启动的时候发生了异常,然后崩溃,重启,循环往复(并不是一直消失不见,而是不断闪烁)。但是查看系统日志,却找不到相关的异常日志。

这种现象,可以通过如下方法解决:

$ sudo apt-get remove --purge lxpanel

$ sudo apt-get install lxpanel

$ sudo apt-get autoremove

$ rm -rf ~/.config/lxpanel/LXDE-pi 

$ sudo reboot

参考链接


树莓派3 B+下次启动强制检查系统分区

树莓派使用的过程中,难免会由于突然断电等原因导致SD卡发生错误。这个时候我们就需要强制让树莓派在下次启动的时候进行磁盘检查。

如果是普通分区,可以卸载后执行fsck命令,但是如果是系统分区,由于一直被占用,因此是没有办法进行磁盘检查的。

网上找了一下,找到了解决办法,可以强制让树莓派在下次系统启动的时候,强制检查系统分区。具体的方式如下:

$ sudo touch /forcefsck

$ sudo reboot

参考链接


Checking sdcard for errors, unmount problem

树莓派3 B+设置静态IP

最近需要为一台`树莓派3 B+`设置静态`IP`地址,结果尝试了半天总是不成功。

网上搜索了一下,找到解决方法。

修改`/etc/dhcpcd.conf`文件

$ sudo vim /etc/dhcpcd.conf

在文件的尾部增加如下内容:

interface eth0

static ip_address=192.168.0.10/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

interface wlan0

static ip_address=192.168.0.200/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

上面的配置文件中,`eth0`是有线的配置, `wlan0`是无线配置
`ip_address`就是静态`IP`, 后面要接`/24`
`routers`是网关
`domain_name_servers`是`DNS`

参考链接


设置树莓派3 B+的静态IP

如何安装树莓派摄像头模块

树莓派摄像头模块(Pi Cam)发售于2013年5月。其第一个发布版本配备了500万像素的传感器,通过排线链接树莓派上的CSI接口。而Pi Cam的第二个发布版本——也被叫做Pi NoIR中,配备了相同的传感器,但没有红外线过滤装置。因此第二版的摄像头模块就像安全监控摄像机一样,可以观测到近红外线的波长(700 - 1000 nm),不过当然同时也就牺牲了一定的显色性。

本文将会展示如何在树莓派上安装摄像头模块。 我们将使用第一版摄像头模块来演示。在安装完摄像头模块之后,你将会使用三个应用程序来访问这个模块:raspistill, raspiyuv 和raspivid。其中前两个应用用来捕捉图像,第三个应用来捕捉视频。raspistill 工具生成标准的图片文件,例如 .jpg 图像,而 raspiyuv 可以通过摄像头生成未处理的 raw 图像文件。

安装树莓派摄像头模块

按照以下步骤来将树莓派摄像头模块连接搭配树莓派:

  1. 找到 CSI 接口(CSI接口在以太网接口旁边),掀起深色胶带。
  2. 拉起 CSI 接口挡板。
  3. 拿起你的摄像头模块,将贴在镜头上的塑料保护膜撕掉。确保黄色部分的PCB(有字的一面)是安装完美的(可以轻轻按一下黄色的部分来保证安装完美)。
  4. 将排线插入CSI接口。记住,有蓝色胶带的一面应该面向以太网接口方向。同样,这时也确认一下排线安装好了之后,将挡板拉下。

130426pxvuxrqtnpppxx17

好了,现在你的 Pi Cam 已经准备就绪,可以拍摄照片或视频了。

在树莓派上启用摄像头模块

在安装完摄像头模块之后,首先要确认你已经升级了树莓派系统并应用了最新的固件。可以输入以下命令来操作:

$ sudo apt-get update
$ sudo apt-get upgrade 

运行树莓派配置工具来激活摄像头模块:

$ sudo raspi-config 

移动光标至菜单中的 "Enable Camera(启用摄像头)",将其设为Enable(启用状态)。完成之后重启树莓派。

130440dguwh6gwk1vk9jgv

130442rn19igalrfo1rmg5

130443uq0hldn4sfvc0nhs

安装完摄像头模块后的完成照:

130454br44z4dnp2c3zcyr

通过摄像头模块拍照

在重启完树莓派后,我们就可以使用Pi Cam了。要用它来拍摄照片的话,可以从命令行运行raspistill:

$ raspistill -o keychain.jpg -t 2000 

这句命令将在 2000ms 后拍摄一张照片,然后保存为 keychain.jpg。下面就是一张由 Pi Cam 拍摄的我的小熊公仔钥匙链。

130456h516ypyamyo5mst6

raspiyuv 工具用法差不多,只不过拍摄得到的是一张未处理过的raw图像。

通过摄像头模块拍视频

想要用摄像头模块拍一段视频的话,可以从命令行运行 raspivid 工具。下面这句命令会按照默认配置(长度5秒,分辨率1920x1080,比特率 17Mbps)拍摄一段视频。

$ raspivid -o mykeychain.h264

如果你想改变拍摄时长,只要通过 "-t" 选项来设置你想要的长度就行了(单位是毫秒)。

$ raspivid -o mykeychain.h264 -t 10000

使用 "-w" 和 "-h" 选项将分辨率降为 1280x720...

$ raspivid -o mykeychain.h264 -t 10000 -w 1280 -h 720

raspivid 的输出是一段未压缩的 H.264 视频流,而且这段视频不含声音。为了能被通常的视频播放器所播放,这个 raw 的 H.264 视频还需要转换。可以使用 gpac 包中所带有的 MP4Box 应用。

在 Raspbian 上安装 gpac,输入命令:

$ sudo apt-get install -y gpac 

然后将这段 raw 的 H.264 格式的视频流转换为每秒30帧的 .mp4 格式视频:

$ MP4Box -fps 30 -add keychain.h264 keychain.mp4 

视频长度为10秒,使用默认分辨率以及比特率。

如果想要获取 raspistill, raspiyuv 和 raspivid 的完整命令行选项,不加任何选项直接运行以上命令即可。

参考链接


如何安装树莓派摄像头模块

Ubuntu 16.04上使用crosstool-ng建立树莓派2B的编译环境

环境准备


$ sudo apt-get -y update
$ sudo apt-get install -y bison flex texinfo gawk automake subversion
$ sudo apt-get install -y gperf help2man make libtool libncurses5-dev 
$ sudo apt-get install -y gcj-jdk python-dev g++
$ sudo apt-get install libtool-bin

编译crosstool-ng


$ git clone https://github.com/crosstool-ng/crosstool-ng.git
$ cd crosstool-ng
$ ./bootstrap
$ ./configure --prefix=/opt/crosstool-ng
$ make
$ sudo make install

然后加环境变量 export PATH=$PATH:/opt/crosstool-ng/bin

配置编译选项


$ mkdir toolchain
$ cd toolchain
$ ct-ng armv7-rpi2-linux-gnueabihf

如果想自己配置调整某些参数,则执行

$ ct-ng menuconfig

最后执行

$ ct-ng build

默认情况下,生成的编译工具在当前用户目录下的x-tools目录下,如果需要调整这个目录,可以参考
Mac OSX下执行crosstool-ng提示“Your file system ‘xxxx’ is *not* case-sensitive!”

编译树莓派源代码


Ubuntu 16.04 (x64)树莓派B+(Raspberry Pi  B+)源代码编译

参考链接


自己编译给树莓派的交叉编译工具

Mac OSX EI Capitan(10.11.5)上使用crosstool-ng 1.22.0 建立树莓派2B的编译环境

背景介绍


树莓派自带的编译工具是基于Linux的,在Mac OSX上是无法正常使用的,因此比较简单的方法就是使用crosstool-ng来建立交叉编译环境。

配置编译环境


1.安装HomeBrew,方便各种工具的安装

参考让Mac也能拥有apt-get类似的功能——Brew

2.使用HomeBrew安装crosstool-ng

$ sudo brew install crosstool-ng

3.链接Mac OSX上的installginstallMac OSX上没有ginstall

$ sudo ln -s /usr/local/bin/ginstall /usr/bin/install

如果不执行命令,则会报错

/Volumes/RPi-EABI/.build/tools/bin/install: line 2: exec: ginstall: not found

4.使用HomeBrew安装expat

$ sudo brew install expat

不执行此命令,我的电脑会出现crosstool-ng在配置expat的时候失败,但是两者使用的版本并不相同,另外貌似出错后,重试即可,不需要安装expat,但是稳妥起见,还是安装好了。
5.创建大小写区分的磁盘分区文件,并挂载(如果你系统创建的时候,系统分区以及区分大小写,则不必此项操作)

参考Mac OSX下执行crosstool-ng提示“Your file system ‘xxxx’  is *not* case-sensitive!”

6.在刚刚创建并挂载的大小写区分的磁盘上执行配置命令

$ ct-ng armv7-rpi2-linux-gnueabihf

7.修改刚刚命令生成在当前目录下的配置文件

$ sudo vim .config

找到

CT_WANTS_STATIC_LINK=y
CT_CC_GCC_STATIC_LIBSTDCXX=y

禁止使用静态链接(Mac OSX下,无法提供对于libc的静态链接,只能动态链接)

CT_WANTS_STATIC_LINK=n # set disabled
CT_CC_GCC_STATIC_LIBSTDCXX=n # set disabled or comment out

8.执行构建命令

$ ct-ng build

构建中遇到的问题


如果构建出错,可以使用

$ ct-ng build.1

后面的数字代表几个并行的任务,单个任务可以更方便的查看出错的信息,多任务并发会导致日志打印的非常混乱。

在构建(ct-ng build)的时候遇到任何问题,都应该查看当前构建目录下的build.log文件,这个文件中详细记录了构建的过程信息,详细的出错信息等。
由于crosstool-ng在构建过程中需要去服务器上下载源代码,难免出现文件下载不完整的情况,这种情况下,可以从build.log文件中看到如下的内容:

[FILE ]    tar: Retrying...
[FILE ]    tar: Damaged tar archive
[FILE ]    tar: Retrying...
[FILE ]    tar: Damaged tar archive
[FILE ]    tar: Retrying...
[FILE ]    tar: Damaged tar archive
[FILE ]    tar: Retrying...
[FILE ]    tar: Truncated tar archive
[FILE ]    tar: Error exit delayed from previous errors.

则说明下载的源代码出现了问题。最容易出现这个问题的是gcc.以gcc-5.2.0为例子,修正的方法如下:

$ cd .build

$ cd tarballs

$ rm -rf gcc-5.2.0.tar.bz2

$ cd ..

$ cd src

$ rm -rf .gcc-5.2.0.extracting

$ rm -rf gcc-5.2.0

简单解释一下代码,tarballs存储了从服务器上下载的全部源代码的压缩包,解压缩出现问题,因此必须删除,让crosstool-ng去重新下载,扩展名为.extracting文件为crosstool-ng的标记文件,用来标识这个包是不是已经被解压缩过,一旦这个文件存在crosstool-ng就认为对应的工具已经就绪了,就不会处理这个工具了,最后删除的是工具源代码的目录。

如果提示安装binutils的时候失败,如下所示:

[INFO ]  Installing binutils for host
[ERROR]    /Volumes/raspberry/rpi-linux/.build/src/binutils-2.25.1/gold/gold-threads.cc:288:13: error: expected expression
[ERROR]    make[5]: *** [gold-threads.o] Error 1
[ERROR]    make[4]: *** [all-recursive] Error 1
[ERROR]    make[3]: *** [all] Error 2
[ERROR]    make[2]: *** [all-gold] Error 2
[ERROR]    make[1]: *** [all] Error 2
[ERROR]   
[ERROR]  >>
[ERROR]  >>  Build failed in step 'Installing binutils for host'
[ERROR]  >>        called in step '(top-level)'
[ERROR]  >>
[ERROR]  >>  Error happened in: CT_DoExecLog[scripts/functions@216]
[ERROR]  >>        called from: do_binutils_backend[scripts/build/binutils/binutils.sh@240]
[ERROR]  >>        called from: do_binutils_for_host[scripts/build/binutils/binutils.sh@105]
[ERROR]  >>        called from: main[scripts/crosstool-NG.sh@646]
[ERROR]  >>
[ERROR]  >>  For more info on this error, look at the file: 'build.log'
[ERROR]  >>  There is a list of known issues, some with workarounds, in:
[ERROR]  >>      '/usr/local/Cellar/crosstool-ng/1.22.0/share/doc/crosstool-ng/crosstool-ng-1.22.0/B - Known issues.txt'
[ERROR]   
[ERROR]  (elapsed: 36:53.00)
[36:54] / make: *** [build] Error 1

查看build.log可以看到如下的内容:

[ERROR]    /Volumes/raspberry/rpi-linux/.build/src/binutils-2.25.1/gold/gold-threads.cc:288:13: error: expected expression
[ALL  ]        : once_(PTHREAD_ONCE_INIT)
[ALL  ]                ^
[ALL  ]    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/pthread.h:203:27: note: expanded from macro 'PTHREAD_ONCE_INIT'
[ALL  ]    #define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}}
[ALL  ]                              ^
[ALL  ]    1 error generated.
[ERROR]    make[5]: *** [gold-threads.o] Error 1
[ALL  ]    make[5]: *** Waiting for unfinished jobs....

这个BUG的原因是由于GCC的版本问题导致的,低于4.7版本的GCC无法理解这个语法,尽管Mac Osx已经使用最新的LLVM,但是遗憾的是,最新的LLVM并没有支持这个语法。解决方法如下:

$ vim /Volumes/raspberry/rpi-linux/.build/src/binutils-2.25.1/gold/gold-threads.cc

找到如下代码

// Class Once_initialize.  This exists to hold a pthread_once_t
// structure for Once.

class Once_initialize
{
 public:
  Once_initialize()
    : once_(PTHREAD_ONCE_INIT)
  { }

  // Return a pointer to the pthread_once_t variable.
  pthread_once_t*
  once_control()
  { return &this->once_; }

 private:
  pthread_once_t once_;
};

修改为:

// Class Once_initialize.  This exists to hold a pthread_once_t
// structure for Once.

class Once_initialize
{
 public:
  Once_initialize()
  {once_.__sig = _PTHREAD_ONCE_SIG_init; once_.__opaque[0] = 0;}

  // Return a pointer to the pthread_once_t variable.
  pthread_once_t*
  once_control()
  { return &this->once_; }

 private:
  pthread_once_t once_;
};

如果出现了"fatal error: bracket nesting level exceeded maximum of 256",如下所示:

[ERROR]    /Volumes/raspberry/rpi-linux/.build/src/gcc-5.2.0/gcc/config/arm/neon.md:3463:10917: fatal error: bracket nesting level exceeded maximum of 256
[ALL  ]    /Volumes/raspberry/rpi-linux/.build/src/gcc-5.2.0/gcc/config/arm/neon.md:3463:10917: note: use -fbracket-depth=N to increase maximum nesting level
[ALL  ]    47 warnings and 1 error generated.
[ERROR]    make[2]: *** [insn-attrtab.o] Error 1
[ALL  ]    make[2]: *** Waiting for unfinished jobs....
[ALL  ]    42 warnings generated.
[ALL  ]    18 warnings generated.
[ALL  ]    rm gcc.pod
[ERROR]    make[1]: *** [all-gcc] Error 2

则修改方法如下:

$ ct-ng menuconfig

在出现的界面中选择"Paths and misc options"项目
Crosstool-NG-PathAndMiscOptions

在第二级界面中不断下拉,找到"Extra host compiler flags",增加"-fbracket-depth=512",这个选项。

Crosstool-NG-PathAndMiscOptions-ExtraHostCompilerFlags

然后重新执行

$ ct-ng build

如果出现错误:

[ALL  ]    /var/folders/h8/_f6dzm814rn1pjrgxgfvcn900000gn/T//ccU8Jut6.s: Assembler messages:
[ALL  ]    /var/folders/h8/_f6dzm814rn1pjrgxgfvcn900000gn/T//ccU8Jut6.s:81: Error: invalid constant (af) after fixup
[ALL  ]    /var/folders/h8/_f6dzm814rn1pjrgxgfvcn900000gn/T//ccU8Jut6.s:163: Error: invalid constant (ff) after fixup
[ERROR]    make[3]: *** [/Volumes/raspberry/rpi-linux/.build/armv7-rpi2-linux-gnueabihf/build/build-libc-startfiles/csu/libc-start.o] Error 1

这个是由于LLVM目前的版本还无法正确的理解部分GCC的汇编部分的写法,导致编译失败,而这部分的语法一般都是用在优化的时候出现错误,因此我们需要禁用这部分的优化,使用"Paths and misc options"->"Extra host compiler flags"增加 "-fno-unroll-loops"。如下图:
Crosstool-NG-PathAndMiscOptions-ExtraHostCompilerFlags-NoUnrollloops
如果出现如下错误:

[ERROR]    make[3]: *** [iconvdata/others] Error 2
[ERROR]    make[2]: *** [all] Error 2
[ALL  ]    make[4]: *** No rule to make target `/Volumes/raspberry/rpi-linux/.build/armv7-rpi2-linux-gnueabihf/build/build-libc-final/iconvdata/MIK.so', needed by `others'.  Stop.
[ERROR]    make[3]: *** [iconvdata/others] Error 2
[ERROR]    make[2]: *** [all] Error 2
[ERROR]  
[ERROR]  >>
[ERROR]  >>  Build failed in step 'Installing C library'
[ERROR]  >>        called in step '(top-level)'

这个问题是由于编译的时候,同时打开的文件数量超过了256导致的,修复方式为在shell中增大同时打开的文件数量限制到1024

$ ulimit -n 1024

然后在同一个shell中继续执行

$ ct-ng build

如果出现如下错误,则直接忽略即可:

[INFO ]  Installing final gcc compiler
[ERROR]    clang: error: unsupported option '-print-multi-os-directory'
[ERROR]    clang: error: no input files

至于其他问题,貌似重试一下就可以解决了。

编译树莓派源代码


Ubuntu 16.04 (x64)树莓派B+(Raspberry Pi  B+)源代码编译

参考链接


Ubuntu 16.04 (x64)树莓派B+(Raspberry Pi B+)源代码编译

树莓派上的操作


1.升级到最新版内核保证与下载的内核源码版本一致

$ sudo rpi-update

2.升级完整后重启

$ sudo reboot

3.查看内核版本

$ uname -r

4.把最新版本的内核配置保存到.config中,以备以后编译内核使用

$ sudo modprobe configs

文件被存储到了/proc/config.gz中。

目前最新版本是4.4.12,因此下面的编译都是针对4.4.y这个分支进行的。

Debian/Ubuntu下编译


1.获取内核源代码

$ cd ~

$ mkdir rpi

$ cd rpi

2,以下步骤时间很长,可以在睡觉前执行,并且可能需要重试几次才行,建议同时开三个Shell一起执行。

# core.symlinks=true  软连接处理,否则会出现各种找不到文件的问题

$ git -c core.symlinks=true clone https://github.com/raspberrypi/firmware.git rpi-firmware

$ git -c core.symlinks=true clone https://github.com/raspberrypi/linux.git rpi-linux

$ git -c core.symlinks=true clone https://github.com/raspberrypi/tools.git rpi-tools

3.给予整个rpi-tools目录执行权限,默认可能没有执行权限

$ chmod +x -R rpi-tools

4.整个的rpi-linux的文件夹的所有者更改为当前用户,否则存在一定程度的编译问题,特别是代码从其他系统上拷贝过来的情况

$ sudo chown -R `whoami` rpi-linux/

5.设置编译器的路径

$ export PATH=$PATH:~/rpi/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

6.配置编译类型

$ cd rpi-linux/

# 检出分支
$ git checkout rpi-4.4.y

$ KERNEL=kernel

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig

如果提示是否增加新的驱动支持,默认全部选择否(输入大写的字母N,小写字母无效),否则会导致无法编译通过。

7.开始正式编译内核,最后的数字改成比你的CPU核心数量+1以提交多线程编译效率。

$ make clean

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j5

8.编译错误修正,如果提示如下错误

  DTC     arch/arm/boot/dts/bcm2708-rpi-b.dtb
In file included from arch/arm/boot/dts/bcm2708.dtsi:1:0,
                 from arch/arm/boot/dts/bcm2708-rpi-b.dts:3:
arch/arm/boot/dts/bcm2708_common.dtsi:1:39: fatal error: dt-bindings/clock/bcm2835.h: 没有那个文件或目录
 #include "dt-bindings/clock/bcm2835.h"
                                       ^
compilation terminated.
scripts/Makefile.lib:293: recipe for target 'arch/arm/boot/dts/bcm2708-rpi-b.dtb' failed
make[1]: *** [arch/arm/boot/dts/bcm2708-rpi-b.dtb] Error 1
arch/arm/Makefile:340: recipe for target 'dtbs' failed
make: *** [dtbs] Error 2

这个现象的原因是 git 在检出代码的时候,没有正确处理软连接,我们只需要重新处理一次即可。如下:

# 软连接处理,否则会出现各种找不到文件的问题

$ git config core.symlinks true

$ git reset --hard

9.查看生成的内核镜像文件

$ cd rpi-linux/arch/arm/boot

生成的zImage就是我们需要的kernel.img

10.编译modules

$ cd ../..

$ mkdir modules

$ cd rpi-linux

$ make modules_install ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=../modules -j5
安装编译好的内核

Ubuntu下面,SD卡会自动挂载,默认挂载到了/media/目录下面,如果是使用NOOBS安装的话,系统目录是固定的,执行如下命令拷贝到目标SD卡上面

$ mv /media/`whoami`/boot/kernel.img /media/`whoami`/boot/kernel_old.img

$ cp rpi-linux/arch/arm/boot/zImage /media/`whoami`/boot/kernel.img

$ mv /media/`whoami`/boot/bootcode.bin /media/`whoami`/boot/bootcode_old.bin

$ mv /media/`whoami`/boot/fixup.dat /media/`whoami`/boot/fixup_old.dat

$ mv /media/`whoami`/boot/fixup_cd.dat /media/`whoami`/boot/fixup_cd_old.dat

$ mv /media/`whoami`/boot/start.elf /media/`whoami`/boot/start_old.elf

$ cd rpi-firmware/boot

$ cp bootcode.bin fixup.dat fixup_cd.dat start.elf /media/`whoami`/boot/

参考链接


树莓派(Raspberry Pi)2B编译安装Robopeak USB屏幕驱动

树莓派安装的系统是Linux raspberrypi 4.1.19+,以下的命令都是通过SSH在树莓派的系统上直接执行的。

1.编译树莓派内核

参照Ubuntu 16.04 (x64)树莓派B+(Raspberry Pi B+)源代码编译

2.安装git

pi@raspberrypi ~ $ sudo apt-get install git

3.安装编译工具

pi@raspberrypi ~ $ sudo apt-get install build-essential
pi@raspberrypi ~ $ sudo apt-get install autoconf

pi@raspberrypi ~ $ sudo apt-get install bc

pi@raspberrypi ~ $ sudo apt-get install gcc-4.8 g++-4.8

# 首先要让系统知道我们安装了多个版本的g++
# 命令最后的 20和50是优先级,如果使用auto选择模式,系统将默认使用优先级高的
pi@raspberrypi ~ $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20

pi@raspberrypi ~ $ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50

pi@raspberrypi ~ $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20

pi@raspberrypi ~ $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50

pi@raspberrypi ~ $ sudo update-alternatives --config gcc

pi@raspberrypi ~ $ sudo update-alternatives --config g++

我们在编译树莓派内核的时候,使用的gcc的版本是4.8.3版本(rpi-tools目录下),但是遗憾的是,树莓派自带的gcc的版本却是4.6.3,用这个版本的gcc编译出来的内核驱动可能会直接崩溃的,我们最好手工指定使用的gcc跟我们编译内核的时候的版本一致。换句话说,如果哪天我们编译内核的gcc再次升级,那么我们也需要手工在树莓派内部指定相同版本。

4.拷贝刚刚编译树莓派内核的源代码到当前的树莓派系统磁盘

从树莓派上拔下SD卡,插入到编译内核的Ubuntu 16.04 (x64)系统上,拷贝源代码

$ sudo cp -r rpi-linux /media/`whoami`/root/usr/src

$ sudo chmod 777 -R /media/`whoami`/root/usr/src

5.建立内核模块库目录的链接

重新插上SD卡,并且启动进入树莓派系统

pi@raspberrypi ~ $ sudo ln -s /usr/src/rpi-linux /lib/modules/$(uname -r)/build

6.检测源代码目录下是否存在Module.symvers

pi@raspberrypi ~ $ cd /lib/modules/$(uname -r)/build

pi@raspberrypi /lib/modules/4.4.12+/build $  ls -l | grep Module.symvers

这个文件在我们编译内核之后应该是存在的,如果不存在,需要重新编译内核。
没有Module.symvers或用错了Module.symvers都可能会造成你加载模块时报Exec format error.

7.将当前正在使用的系统的内核配置作为编译内核时候的配置

pi@raspberrypi /lib/modules/4.4.12+/build $ sudo modprobe configs

pi@raspberrypi /lib/modules/4.4.12+/build $ sudo touch .config

pi@raspberrypi /lib/modules/4.4.12+/build $ sudo chmod 777 .config

pi@raspberrypi /lib/modules/4.4.12+/build $ sudo gzip -dc /proc/config.gz > /lib/modules/$(uname -r)/build/.config

8.生成编译内核所需要的文件

pi@raspberrypi ~ $ cd /lib/modules/$(uname -r)/build

pi@raspberrypi /lib/modules/4.4.12+/build $  sudo make modules_prepare

9.修改驱动程序的默认版本号与本系统相同

pi@raspberrypi ~ $ sudo vim /lib/modules/$(uname -r)/build/include/generated/utsrelease.h

修改里面的内容为使用uname -r命令显示的内容,此系统版本显示为4.4.12+,修改后的内容如下:

#define UTS_RELEASE "4.4.12+"

如果不进行上述的修改,会导致编译出来的内核文件在加载的时候提示disagrees about version of symbol module_layout,而无法成功加载驱动。

10.下载驱动程序源代码

pi@raspberrypi ~ $ cd ~

pi@raspberrypi ~ $ git clone https://github.com/robopeak/rpusbdisp.git

11.切换到驱动程序的源代码目录

pi@raspberrypi ~ $ cd ~/rpusbdisp/drivers/linux-driver

12.编译源代码

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ make clean

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ make CFLAGS=-g

编译完成后使用

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ modinfo rp_usbdisplay.ko

查看是不是与使用

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ uname -r

显示的完全相同,如果不完全相同,则需要继续进行上面的调整。

13.安装编译好的驱动

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ sudo cp rp_usbdisplay.ko /lib/modules/`uname -r`/kernel/drivers/video/

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ sudo depmod

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ sudo modprobe rp_usbdisplay

执行完成后,会在/dev目录下面生成fb1这个文件。

$ ls /dev/fb*
/dev/fb0  /dev/fb1

执行

$ cat /dev/fb0 > /dev/fb1

如果出现花屏,则驱动一切正常。

此处存在一个大坑。如果按照说明文档把驱动拷贝到

$ cp rp_usbdisplay.ko /lib/modules/`uname -r`/

或者直接运行,

pi@raspberrypi ~/rpusbdisp/drivers/linux-driver $ sudo ./run.sh

则运行时候报错:

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.140347] Internal error: Oops: 5 [#1] ARM

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.231738] Process modprobe (pid: 2850, stack limit = 0xd4cde188)

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.237909] Stack: (0xd4cdfe80 to 0xd4ce0000)

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.242269] fe80: bf1f8acc 00007fff bf1f8ac0 c007abe4 00000000 de593000 00000000 bf1f8acc

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.250441] fea0: 00000000 bf1f8acc bf1f8cb8 bf1f8c7c bf1f8010 bf1f8bb8 20000013 ffffffff

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.258611] fec0: 00000000 c056cda8 d4cdfeec 00000000 00000000 00000000 00000000 00000000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.266782] fee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.274952] ff00: 00000000 00000000 de593000 000071eb 00000000 b6ede1eb de59a1eb d4cde000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.283125] ff20: b6ec5948 00000000 d4cdffa4 d4cdff38 c007db58 c007bc20 00000000 de593000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.291296] ff40: 000071eb de5973ac de597224 de5997c4 00002cb8 000035c8 00000000 00000000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.299467] ff60: 00000000 00001e24 00000025 00000026 0000001a 0000001e 00000010 00000000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.307637] ff80: 00000000 00040000 80458c38 00000080 c000f748 d4cde000 00000000 d4cdffa8

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.315808] ffa0: c000f580 c007da88 00000000 00040000 b6ed7000 000071eb b6ec5948 b6ed7000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.323979] ffc0: 00000000 00040000 80458c38 00000080 80458d90 000071eb b6ec5948 00000000

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.332151] ffe0: 00000000 be9ba2fc b6ebcfb4 b6e27534 60000010 b6ed7000 1bffa861 1bffac61

Message from syslogd@raspberrypi at Aug 30 17:08:33 ...
 kernel:[   93.356275] Code: e51bc088 e15c0007 e2477008 0a000009 (e5973014) 
Segmentation fault

这个问题是由于驱动存放的目录不正确导致的。

14.将RoboPeakMini USB显示器驱动程序的内核模块设定为自动启动

pi@raspberrypi ~ $ sudo vim /etc/modules

然后在文件尾部增加一行rp_usbdisplay

参考链接