我的最終目標(biāo)是在樹莓派上運行GC4653這個攝像頭,但是沒接觸過linux內(nèi)核和驅(qū)動這些所以先用ov5647這個攝像頭調(diào)試下看看。
使用ov5647
因為不是默認(rèn)的攝像頭,所以要先改一下設(shè)置,在sudo nano /boot/firmware/config.txt
的后面增加一行dtoverlay=ov5647
,然后把camera_auto_detect
改成0,保存然后重啟這樣會加載新的配置,這時候 ls /dev/video*
應(yīng)該會多出來幾個video設(shè)備了。
用
rpicam-hello -t 0
調(diào)用攝像頭,應(yīng)該就可以看到畫面了。(其實直接什么都不改也行。。。。)這時候用
dmesg | grep ov5647
查看可以看到有相關(guān)的初始化設(shè)備樹和KO文件
關(guān)于設(shè)備樹和ko我的理解是這樣的,需要先更新設(shè)備樹,讓linux知道我們要連一個什么樣的設(shè)備,這個設(shè)備需要用要什么東西i2c、gpio什么的。這個用來描述設(shè)備的就是設(shè)備樹文件,通常是dts和dtsi組成,編譯后得到dtso(其實就是deviceTreeSource和deviceTreeInclude,dtso對應(yīng).o文件)然后加載ko文件,ko文件是這個設(shè)備的驅(qū)動,通常是.c文件編譯得到的。
設(shè)備樹在make的時候可以選擇,如果是y的話就會編到image里面,但是這樣新增設(shè)備驅(qū)動就會比較復(fù)雜,所以選m的話就會單獨變成dtso,然后用voerlay的方式讓系統(tǒng)加載。這也是剛剛在config.txt里面所做的事情
查看此時的設(shè)備樹和ko文件
sudo find / -name "ov5647*"
查找所有和ov5647相關(guān)的文件
lsmod
查看在運行的module驅(qū)動編譯
下載內(nèi)核工程
從這里下載樹莓派的內(nèi)核工程,我不想搞交叉編譯了,所以直接拷到了樹莓派的桌面上。然后執(zhí)行
KERNEL=kernel8
sudo make bcm2712_defconfig
先生成.config文件,然后sudo make -j8
,這個要搞半個小時左右吧。。
注:要先安裝一些依賴
apt install tmux build-essential bc bison flex libssl-dev make libc6-dev libncurses5-dev
apt安裝太慢的話可以加參數(shù)上代理,-o Acquire::http::proxy="http://192.168.1.7:23457"
KERNEL=kernel8
ko編譯
ko文件是用特定的.c文件編譯的,我們這里寫一個hello world測試,新建一個hello.c寫下面這些
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int __init hello_init(void)
{
printk(KERN_ALERT "Hello world\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "GoodBye! Hello world\n");
}
module_init(hello_init);
module_exit(hello_exit);
然后統(tǒng)計目錄新建Makefile,寫這些
ifeq ($(KERNELRELEASE),)
KDIR ?= ./linux
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions *.ko *.symvers *.order
.PHONY: clean
else
obj-m := hello.o
endif
然后make,這樣會生成一個hello.ko,makefile里面的KDIR路徑要填內(nèi)核工程的路徑,然后sudo insmod hello.ko
就可以安裝這個ko文件,用dmesg
就會看到打印的hello了,sudo rmmod hello
也會看到相應(yīng)的打印。
測試I2C通信
先用rpicam-hello -t 0
把設(shè)備跑起來,然后用i2ctransfer -f -y 6 w2@0x36 0x38 0x08 r2
讀取0x3808寄存器,因為是16位地址,所以不能直接用i2cdump讀取。
交叉編譯
不知道為什么樹莓派多次reboot以后會進不去系統(tǒng),所以補充下WSL來交叉編譯的過程。
- 交叉編譯工具https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
- 安裝依賴
apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
然后吧交叉編譯的工具添加到路徑里,用make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2712_defconfig
生成配置,用make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
生成
測試驅(qū)動
可以用樹莓派自帶的rpicam-apps來測試,我用的rpicam-hello -t 0 --framerate 120
這個,默認(rèn)是跑5秒左右,-t 0可以讓他一直跑,-framerate可以讓他提高幀率,不然默認(rèn)幀率一直是30左右,可以在標(biāo)題欄左上角看到幀率
也可以用rpicam-vid --level 4.2 --framerate 120 --width 1920 --height 270 --save-pts timestamp.pts -o video.264 -t 10000 --denoise cdn_off
來測試。