1. MIPI摄像头简介
1.1 MIPI CSI2接口简介
MIPI (Mobile Industry Processor Interface):ARM, Nokia, ST ,TI等公司在2003年成立的一个联盟所定的接口。目的是把手机等移动设备内部的接口如:摄像头、显示屏接口、射频/基带接口等标准化,从而减少手机等移动设备设计的复杂程度和增加设计灵活性。
工作组(Work Group):MIPI联盟下有许多的工作组,不同的工作组负责定义对应设备的标准。其中包括有:Camera工作组、Display工作组、高速多端链接工作组等十几个工作组。
MIPI CSI-2接口是由MIPI联盟下的Camera工作组指定的CSI(Camera Serial Interface)的第2版接口标准。硬件层面:最大支持4个虚拟通道(Lane)传输数据,1个Lane在硬件上体现就是一对差分信号线(见下方原理图),每个Lane的最大通讯速率为2.0Gbps。软件层面:MIPI CSI-2协议栈主要由应用层、协议层、物理层组成,其中协议层又可以分为:像素/字节组包/解包层、底层协议层、通道管理层。
1.2 硬件接口资源介绍
EASY EAI Orin-Nano开发板具有2路MIPI CSI-2接口。每路引出了4个Lane。位置定义如下所示。
EASY EAI Orin-Nano默认搭配IMX415单目摄像头。同时配有一根0.5mm间距的40pin FPC反向线。
反向线:两端的蓝色标识不在同一侧面。
同向线:两端的蓝色标识处于同一侧面。
1.3 接线说明
* 接线必须在断电时进行操作。
* 采用反向线连接IMX415摄像头与Cmaera1接口。(注意:用错线会烧坏摄像头或者核心板,因此在接线时务必要小心。)
* 接线端子卡扣与FPC线的蓝色塑料标识必须位于同一侧。如下图所示。
1.4 查看设备情况
可以通过dmesg命令,检查MIPI-CSI2接口模块是否正常工作。
dmesg | grep "csi2-.phy"
摄像头正常挂载的情况如下所示。可以看到:
在dcphy0接口上有一个sensor型号为:imx415的摄像头,MIPI-CSI2地址为:4-0036;
在dphy0接口上有一个sensor型号为:imx415的摄像头,MIPI-CSI2地址为:5-0036。
当没能出现目标camera节点时,就需要检查FPC排线是否正常连接,请检查排线的连接是否与“1.3接线说明”一致。
1.5 寻找可用的设备节点
rockchip平台,一个MIPI-CSI接口会对应20多个video节点(设备树定了就会生成这么多个),如下图所示。
注意:但CSI0并不一定是对应着video0~24,这个要根据设备树的实际情况对应生成。
而且MIPI-CSI camera对应的节点,会在修改内核设备树的时候固定下来(即:内核配好了MIPI-CSI Camera个数,无论MIPI-CSI摄像头是否有接上,它的video节点情况都是不会根据MIPI-CSI Camera的接入情况而【动态】改变)。
因此,用户需要找到这些节点所对应的描述信息是什么。Linux的v4l2框架会把这些节点的描述信息统一放在/sys/class/video4linux/目录下,如下图所示。
随便进入一个描述,如video22。
通过cat命令,可以用查看这个name的内容是什么。rockchip芯片定义:如果这个name是mainpath或者selfpath。则这个“video22”就是可用节点。
在终端任意目录执行下面这条命令,可以快速扫描所有的节点的“name”描述。
grep "mainpath" /sys/class/video4linux/video*/name
因此,/dev/video22和/dev/video23都是MIPI-CSI0的可用节点。
2. 快速上手
2.1 例程源码下载
到【百度网盘】上下载相关的单例程序:
链接:https://pan.baidu.com/s/1RXHMGpmGSEfFy0rb1VkXSg?pwd=1234
提取码: 1234
比如在windows环境中,就把单例程序下载到:此电脑\D:\BaiduNetdisk (无规定,用户可自主选择),如下图所示。
然后把例程【复制粘贴】到nfs挂载目录中。(不清楚目录如何构建的,可以参考《入门指南/开发环境准备/nfs服务搭建与挂载》)
2.2 例程编译&运行
通过adb shell进入开发板环境,执行下方命令定位到demo目录,并且执行编译操作。
cd /home/orin-nano/Desktop/nfs/02_camera/
./build.sh
编译成功后,相关的demo会生成在Release目录下。
执行下方命令以运行demo,如下所示。
sudo ./Release/test-mipiCam 22 ##需要root权限
注:输入参数22为MIPI-CSI0所对应的video索引,本固件camera1~2默认对应video索引分别为:22、31(若用户按需对设备树进行过修改,这些索引将会有所变化)
执行效果如下所示。
然后把/tmp/photo拷贝到当前目录下的Release内
cp /tmp/photo ./Release/
再通过组合键【Ctrl+Shift+T】创建一个新窗口,定位到nfs服务器的对应位置。
最后使用mplayer工具播放图片,命令如下所示。
mplayer -demuxer rawvideo -rawvideo w=1920:h=1080:format=bgr24 ./Release/photo -loop 0
例程默认分辨率为1920x1080,故w和h的参数对应填入1920和1080。当出现图片异常时,说明分辨率等不太对应于手头的摄像头,所以需要调整mipicamera_init()的分辨率,例如640x480。
3. MIPI摄像头测试案例
示例代码路径为:02_camera/test-mipiCam/main.c。MIPI Camera API的测试案例代码逻辑流程如下所示:
3.1 源码说明
int main()
{
int ret = 0;
if(1 == argc){
printf("\nerr: Missing parameter!\n");
printf("================= [usage] ==================\n");
printf("example:\n");
printf("\t%s <22/31>\n", argv[0]);
printf("--------------------------------------------\n");
return 0;
}
char *pbuf = NULL;
int ret = 0;
int skip = 0;
FILE *fp = NULL;
ret = mipicamera_init(CAMERA_INDEX, CAMERA_WIDTH, CAMERA_HEIGHT, 0);
if (ret) {
printf("error: %s, %d\n", __func__, __LINE__);
goto exit3;
}
pbuf = (char *)malloc(IMAGE_SIZE);
if (!pbuf) {
printf("error: %s, %d\n", __func__, __LINE__);
ret = -1;
goto exit2;
}
//跳过前10帧
skip = 10;
while(skip--) {
ret = mipicamera_getframe(CAMERA_INDEX, pbuf);
if (ret) {
printf("error: %s, %d\n", __func__, __LINE__);
goto exit1;
}
}
/* tips: 可以在Ubuntu下用mplayer播放录制图像
* adb pull /tmp/photo
* mplayer -demuxer rawvideo -rawvideo w=1920:h=1080:format=bgr24 photo -loop 0
*/
fp = fopen("/tmp/photo", "w");
if (!fp) {
printf("error: %s, %d\n", __func__, __LINE__);
ret = -1;
goto exit2;
}
fwrite(pbuf, 1, IMAGE_SIZE, fp);
fclose(fp);
exit1:
free(pbuf);
pbuf = NULL;
exit2:
mipicamera_exit(CAMERA_INDEX);
exit3:
return ret;
}
其中mipicamera_init(),mipicamera_getframe(),mipicamera_exit()是对v4l2接口调用的易用化封装。具体实现于02_camera/commonApi/mipi_camera.c。