Linux环境配置编译orange,orangepi zero2编译环境搭建及传感器测试
一、编译环境搭建及版本镜像编译
我这里使用的是官方手册上提供的linux SDK,包括uboot、linux内核及根文件系统均是orangePI官方的代码包,但在使用的一开始,我就遇到一个让人比较郁闷的事,就是官方的代码包来源只有两个路径,一个是GitHub,另外一个就是百度网盘,我在编译服务器上clone GitHub上的代码时,发现那个速度真是太慢了,只有20~30KB,而且代码包又这么大,这得下到猴年马月啊,然后放弃又到百度网盘上下载,发现网盘下载的速度同样慢的不行,也只有40~50KB,即使使用了每天的免费提速,也还是这个问题,我刚开始还以为是网速的问题,后来发现网盘下载其他文件时速度是可以上来的,加速有1M左右,平常有200~400KB,也没有之前的这么慢,不知是何问题,干脆也放弃了网盘下载,看看有没有其他的办法。
偶然想到国内的一个代码托管平台可以导入GitHub的项目,然后在这个平台上clone,这样速度是不是就快了,然后就将官方的GitHub项目导入到此代码平台,然后在编译服务器上clone项目的orangepi-build,发现速度果然就上来了,甚至可以达到2~3MB,一会就把build下载下来了,这样做有一个问题是你要同时改编译脚本里的其他代码下载地址,有官方的GitHub地址改为你的库地址,比如这边要改boot、linux内核及交叉编译工具链的地址,我在将这些地址逐一修改后,在编译中代码的下载速度都很多块,基本上没占用太多的时间,大部分时间都还是使用在了代码编译上。

下面按照官方的手册依次看一下我的boot、内核、根文件系统及版本镜像的编译和制作,想说UBoot的编译,在改了代码源以后,基本很顺利的就把uboot编出来了,下面是编译结束后的结果:
Uboot编译结果:

 Uboot编译结果
可以看到编译uboot还是比较快的,只用了大概4分钟的时间,下面是编译出的u-boot deb 包:

下面是编译linux内核,官方的内核使用的是4.9的版本,编译时直接安装官方的说明即可,我这边Linux内核编译结果如下,可以看出花了差不多70min还是比较费时间的,也与我的编译服务器性能不是很强有关系:

 Linux 内核编译结果
接下来是编译Rootfs根文件系统,我这边选了ubuntu20.04带桌面环境的根文件系统,想看看大概需要多长的时间,时间编译结果如下,可以看到大概花了45min,也是比较耗时间的。

根文件系统编译结果
编译生成的rootfs 压缩包:

最后就是整个版本镜像的编译了,同样按照官方的说明进行编译,最后编译的结果如下,这个的时间用的不是很长,只有大概17min左右。

版本镜像:

版本镜像
为了测试编译服务器的性能及整个代码库是否有问题,我编译了ubuntu20.04的带桌面环境的大版本,在修改了库的链接地址后,版本镜像顺利的编了出来,总体来说,整个编译过程还是比较顺利的,也证明我的编译环境是没有问题的,接下来就是编写我手头的几个传感器的驱动程序,并将它们编译到版本中在单板上测试运行了。
二、ADXL345三轴加速度传感器驱动编写
adxl345是adi的一款三轴加速度传感器,具有分辨率高、反应灵敏、功耗低及尺寸小的优点,是一款很好用的三轴加速度传感器,非常适合一些需要测量各个方向加速度的场景。
在编写传感器的驱动时,为了不影响内核的代码结构,与内核代码分离开来,我在最外层的目录上建立了一个kmodule目录,用来存放驱动的源码及编译出来的ko,编译成ko既可以在系统启动后单独加载,不需要与内核的镜像做在一起,升级方便,又在编译时可以单独编译,不需要和整个内核一起编译,这样极大的方便了驱动的更新。
在编写源码前,可以先把编译脚本的框架写一下,ko的编译脚本还是比较简单的,主要注意的有源码当前的路径和内核源码的路径要指向正确,同时在编译ko前要完整的编译一次内核,这样才能保证内核的一些配置生效,另外编译参数arch和交叉编译工具链也要传递正确,否则编译过程中可能会出现未知的错误。

在Makefile写好后,就可以编写驱动的源码了,编写时可以使用内核成熟规范的驱动架构,然后再在这个框架里边填写上自己传感器具体得驱动实现细节,包括匹配设备树的compatible字段及probe接口,文件操作接口open、read、write、ioctrl等。


做完这些工作后,就可以编译ko了,编译的时候可能会报工具链找不到的问题,这时只要将工具链的路径加到环境变量里边就行了,下面是源码及编译出的ko文件。

ko编译出来以后,还需要做的一步工作就是修改内核的设备树文件dts,orangepi zero2使用的设备树文件是sun50i-h616-orangepi-zero2.dts及其包含的dtsi文件,我们只需要修改与单板相关的dts文件即可。

打开dts文件后,找到spi所在的的节点,发现已经存在一个spi_board1了,这个应该是设备/dev/spi1.1所对应的设备树节点,我们把这个注释掉,然后仿照添加一个spi_adxl345的设备节点,将其作为adxl345驱动匹配的设备树节点。

设备树修改好后,编译整个内核,编译好后,使用apt purge -y linux-image-legacy-sun50iw9卸载旧的内核,使用dpkg -i linux-image-legacy-sun50iw9_2.1.0_arm64.deb安装编译好的内核,然后重启单板,单板启动后,使用cat /proc/devices-tree/查看spi下的spi_adxl345节点是否存在,发现还是原来旧的节点,新的节点并没有加上,然后又看了一下output/deb下的镜像包,发现有一个linux-dtb-legacy-sun50iw9_2.1.0_arm64.deb包以dtb命名,是不是dtb没有做进uimage中而是单独打包了,查了一下官方的手册,也没有对这个包的使用做说明,然后我就使用apt purge -y linux-dtb-legacy-sun50iw9卸载了旧的dtb包,使用dpkg -i linux-dtb-legacy-sun50iw9_2.1.0_arm64.deb安装了新的deb包,重启单板,再次使用cat命令查看了一下设备树节点,发现依然没有性加的节点,不知是何原因。

没有设备树节点,先来测试一下驱动是否能成功的insmod上,刚开始在旧的内核上insmod ADXL345.ko时,回报外部ko与内核不匹配的问题,使用服务器和ko在一起编的内核升级上去后,这个问题就会消失,可以成功的加载起来,打印adxl345 init start!及adxl345 init end!,但可能没有匹配到设备树中的节点,probe中的打印并没有打印出来,/dev/下的adxl345设备也没有创建出来,设备树这个问题后续在研究一下。
既然自己改的设备树用不起来,那就用一下官方自己的设备/dev/spi1.1及测试工具spidev_test吧,按照官方的说明,下载源码wiringOP,编译代码包及测试例程,然后使用命令./spidev_test -v -D /dev/spidev1.1先测试一下功能是否正常。

官方的测试命令spidev_test是正常的,而且这个命令支持的参数比较多,不仅可以设置spi时钟速率、每个Word的字节数,还可以设置时钟相位及采样模式、延时等,这样就可以随时调整spi总线的参数,这对测试来说很方便了,同时,他也可以使用-p来传递你要发送的单个或多个字节,既支持字符串也支持十六进制数,例如./spidev_test -v -D /dev/spidev1.1 -s 50 -d 100 -b 8 -H 1 -O 1 -p \\x01\\x02 -S 1, 后边自己编写用户态的程序完全可以参照这个测试程序来改编。
下面是使用逻辑分析仪器采集到的测试数据的时序图,channel0-channel3分别是使能、时钟、数据输出及数据输入的采样数据。



为了方便测试,我在spidev_test中加了一个-V参数来单独传递十六进制数,当发送0时,得到的结果及时序图如下:


另外adxl345还支持i2c总线,同时我手头的其他几个传感器也都支持i2c总线,有GY-30光强传感器、HMC5883L地磁传感器、及SHT20温度传感器,刚好看到单板也预留了i2c总线的接口,就将这几个传感器逐个接到i2c总线上测试了一下,先使用i2cdetect扫了一个器件的地址,都成功的获取到了。
第一个是adxl345的地址扫描结果,地址是0x53,逻辑分析仪时序图如下:



第二个是光强传感器CY-30的地址扫描结果及时序图,地址是0x23.



0x1e的是HMC5883L地磁传感器的地址,时序图如下。



最后一个是sht20温湿度传感器的地址扫描结果,为0x40,时序图如下:



以上这个传感器现在只是简单的做了一下测试,后续有时间在单独对这些传感器编写一下驱动,以读取出传感器测量出的实际数据,并做一些应用。
更多推荐


所有评论(0)