8.15
使用arm-none-linux-gnueabi-gcc交叉编译qt源码和opencv源码,生成的可执行文件到开发板运行会出现bus error错误
于是决定使用5.4.0的arm-linux-g++编译opencv源码和qt4.7.1源码。因为使用4.3.2的arm-linux-g++版本太低,虽然编译qt不会出错,但编译opencv会出错。
下面开始烧的是qte5.7的根文件系统 (超级终端的用户名显示为青色)
cd /lib,再 strings libstdc++.so.6 |grep GLIBCXX 查看libstdc++的版本
可以看到只到了GLIBCXX_3.4.10,所以需要更高版本的libstdc++.so.6
查看虚拟机/usr/lib32下的版本,如下,把libstdc++.so.6和其链接的库(右键查看)都复制到lib,上面的错误没有 了,却出现了illegal instruction,查了一下原因是qt4.7编译时设置的问题,不能设置优化
关于illegal instruction的一些心得
重新编译器qt4.7
更改configure文件,CFG_ENDIAN=Q_LITTLE_ENDIAN (小端,默认是 auto )
还是不行。。。。

由于编译Qt的arm-linux-gcc版本与编译内核与文件系统的版本不一致
ls -l /lib/libc.so.6
echo $LD_LIBRARY_PATH 可以查看动态链接库的环境变量
qt的开源社区
8.16
现在只剩下一个问题需要解决,libc.so的版本过低,需要2.19,而网盘上的qte4.7系统的版本只有2.8,所以决定自己编译一个新内核的qte系统
特别注意: libc.so.6不能随便更改,否则系统许多命令都不能运行
zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息
又试了一次开发板烧录qte5.7的根文件系统,把opencv和qt4-7的链接库都复制到lib后,虽然没有报关于链接库的错误了,但还是报了非法指令illegal instruction的错误。
光盘里有提供了qt5.7的例程,去看一下是里面的kit是怎么设置的,还有把可执行文件复制到开发板上(5.7系统)运行,看是否有报非法指令的错误。
arm-none-linux-gnueabi交叉工具链与arm-linux-gcc 有区别吗
一般来说 arm-linux-gcc 是 arm-none-linux-gnueabi 的一个软链接。
可用 ls -l 命令查看链接对象
光盘提供的qt5例程下载到开发板执行还是显示Illegal instruction 的错误
回去看了一下技术文档,qt5.7的运行系统是ubuntu16.04!!!
终于用arm-linux-gcc 4.3.2编译成功了opencv2
(opencv3不能使用arm-linux-gcc 4.3.2 编译,版本太低,会报错)
使用cmake-gui 去掉with eigen with tiff 去掉openCL这几项 ,configure,generate,关掉cmake-gui,用gedit打开CmakeCache.txt,
CMAKE_EXE_LINKER_FLAGS,加上-lpthread -lrt
打开终端,make,make install完成
虽然之前也是这么操作,但却 一直编译出错。或许问题出在下面这里,这个路径有的博客是按下面这样设置,有的是**/usr/local/arm/4.3.2/**,之前我一直是按照前者设置,这次按后者设置,就编译成功了。。。
不是上面的原因,我又按这个设置编译了一次还是成功了。。。未解之谜
qt creator中build 工程时出现
warning: …/…/lib/libopencv_core.so, needed by /usr/local/arm/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
这个问题是因为交叉编译器没有找到这个库(网上是这么说的)。我将libopencv_core.so,这个库拷贝到了交叉编译器的lib中就没有警告了。
无法打开摄像头
编译opencv时cmake-gui没有with_V4L的选型,是因为Operating System写成arm-linux,应该是Linux才支持V4L,改正后再编译一次,出现了很多报错,如当前的glic库并不适合交叉编译,意思就是的把这些库全都交叉编译,再用来交叉编译opencv的源码,很复杂,直接放弃。
直接调用V4L2的库来读取相机图像,通过拔插u***相机的前后对比,得到了相机的设备号是/dev/video2
int fd;
fd = open("/dev/video2", O_RDWR); // 注意查看摄像头设备名
if (-1 == fd)
{
perror("open /dev/video2");
}
/* 查询打开的设备是否属于摄像头:设备video不一定是摄像头*/
struct v4l2_capability cap;
int ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
if (-1 == ret)
{
perror("ioctl VIDIOC_QUERYCAP");
//close(fd);
}
if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
{
/* 如果为摄像头设备则打印摄像头驱动名字 */
printf("Driver Name: %sn", cap.driver);
}
else
{
printf("open file is not videon");
//close(fd);
}
/* 查询摄像头可捕捉的图片类型,VIDIOC_ENUM_FMT: 枚举摄像头帧格式 */
struct v4l2_fmtdesc fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 指定需要枚举的类型
for (int i = 0; ; i++) // 有可能摄像头支持的图片格式不止一种
{
fmt.index = i;
ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt);
if (-1 == ret) // 获取所有格式完成
{
break;
}
/* 打印摄像头图片格式 */
printf("Picture Format: %sn", fmt.description);
/* 查询该图像格式所支持的分辨率 */
struct v4l2_frmsizeenum frmsize;
frmsize.pixel_format = fmt.pixelformat;
for (int j = 0; ; j++) // 该格式支持分辨率不止一种
{
frmsize.index = j;
ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
if (-1 == ret) // 获取所有图片分辨率完成
{
break;
}
/* 打印图片分辨率 */
printf("width: %d height: %dn",
frmsize.discrete.width,frmsize.discrete.height);
}
}
成功获取了相机的设备信息接下来就是采集图像
V4L2采集图像基本流程
按照上面这篇博客的程序成功获取了相机的图像,但运行一会系统就会奔溃重启,报错
Unable to handle kernel paging request at virtual address 806a7add之类的,主要是内存访问的问题,于是按照下面这篇文章重新修改了一些部分。
uchar *buffer; //buffers 指针记录缓冲帧
将原始数据缓存改成下面这个形式
struct buffer
{
void * start;
unsigned int length;
} * buffers;
USB摄像头(V4L2接口)的图片采集
还是一直报内存错误,然后就是重启,增加队列数到30就持续运行了1000多帧,但开启图像处理, 用时增加从25ms到186ms, 再进行几十帧就崩溃重启了。
而且存在一个问题就是明明帧率有20,但qt显示却很卡,一两秒刷新一次!!!但我刚成功获取图像时并不卡。
我应该在虚拟机上先把代码调通了,再移植到板子上,主要的代码是V4L2, Linux系统共有的。
8.15
使用arm-none-linux-gnueabi-gcc交叉编译qt源码和opencv源码,生成的可执行文件到开发板运行会出现bus error错误
于是决定使用5.4.0的arm-linux-g++编译opencv源码和qt4.7.1源码。因为使用4.3.2的arm-linux-g++版本太低,虽然编译qt不会出错,但编译opencv会出错。
下面开始烧的是qte5.7的根文件系统 (超级终端的用户名显示为青色)
cd /lib,再 strings libstdc++.so.6 |grep GLIBCXX 查看libstdc++的版本
可以看到只到了GLIBCXX_3.4.10,所以需要更高版本的libstdc++.so.6
查看虚拟机/usr/lib32下的版本,如下,把libstdc++.so.6和其链接的库(右键查看)都复制到lib,上面的错误没有 了,却出现了illegal instruction,查了一下原因是qt4.7编译时设置的问题,不能设置优化
关于illegal instruction的一些心得
重新编译器qt4.7
更改configure文件,CFG_ENDIAN=Q_LITTLE_ENDIAN (小端,默认是 auto )
还是不行。。。。

由于编译Qt的arm-linux-gcc版本与编译内核与文件系统的版本不一致
ls -l /lib/libc.so.6
echo $LD_LIBRARY_PATH 可以查看动态链接库的环境变量
qt的开源社区
8.16
现在只剩下一个问题需要解决,libc.so的版本过低,需要2.19,而网盘上的qte4.7系统的版本只有2.8,所以决定自己编译一个新内核的qte系统
特别注意: libc.so.6不能随便更改,否则系统许多命令都不能运行
zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息
又试了一次开发板烧录qte5.7的根文件系统,把opencv和qt4-7的链接库都复制到lib后,虽然没有报关于链接库的错误了,但还是报了非法指令illegal instruction的错误。
光盘里有提供了qt5.7的例程,去看一下是里面的kit是怎么设置的,还有把可执行文件复制到开发板上(5.7系统)运行,看是否有报非法指令的错误。
arm-none-linux-gnueabi交叉工具链与arm-linux-gcc 有区别吗
一般来说 arm-linux-gcc 是 arm-none-linux-gnueabi 的一个软链接。
可用 ls -l 命令查看链接对象
光盘提供的qt5例程下载到开发板执行还是显示Illegal instruction 的错误
回去看了一下技术文档,qt5.7的运行系统是ubuntu16.04!!!
终于用arm-linux-gcc 4.3.2编译成功了opencv2
(opencv3不能使用arm-linux-gcc 4.3.2 编译,版本太低,会报错)
使用cmake-gui 去掉with eigen with tiff 去掉openCL这几项 ,configure,generate,关掉cmake-gui,用gedit打开CmakeCache.txt,
CMAKE_EXE_LINKER_FLAGS,加上-lpthread -lrt
打开终端,make,make install完成
虽然之前也是这么操作,但却 一直编译出错。或许问题出在下面这里,这个路径有的博客是按下面这样设置,有的是**/usr/local/arm/4.3.2/**,之前我一直是按照前者设置,这次按后者设置,就编译成功了。。。
不是上面的原因,我又按这个设置编译了一次还是成功了。。。未解之谜
qt creator中build 工程时出现
warning: …/…/lib/libopencv_core.so, needed by /usr/local/arm/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
这个问题是因为交叉编译器没有找到这个库(网上是这么说的)。我将libopencv_core.so,这个库拷贝到了交叉编译器的lib中就没有警告了。
无法打开摄像头
编译opencv时cmake-gui没有with_V4L的选型,是因为Operating System写成arm-linux,应该是Linux才支持V4L,改正后再编译一次,出现了很多报错,如当前的glic库并不适合交叉编译,意思就是的把这些库全都交叉编译,再用来交叉编译opencv的源码,很复杂,直接放弃。
直接调用V4L2的库来读取相机图像,通过拔插u***相机的前后对比,得到了相机的设备号是/dev/video2
int fd;
fd = open("/dev/video2", O_RDWR); // 注意查看摄像头设备名
if (-1 == fd)
{
perror("open /dev/video2");
}
/* 查询打开的设备是否属于摄像头:设备video不一定是摄像头*/
struct v4l2_capability cap;
int ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
if (-1 == ret)
{
perror("ioctl VIDIOC_QUERYCAP");
//close(fd);
}
if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
{
/* 如果为摄像头设备则打印摄像头驱动名字 */
printf("Driver Name: %sn", cap.driver);
}
else
{
printf("open file is not videon");
//close(fd);
}
/* 查询摄像头可捕捉的图片类型,VIDIOC_ENUM_FMT: 枚举摄像头帧格式 */
struct v4l2_fmtdesc fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 指定需要枚举的类型
for (int i = 0; ; i++) // 有可能摄像头支持的图片格式不止一种
{
fmt.index = i;
ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt);
if (-1 == ret) // 获取所有格式完成
{
break;
}
/* 打印摄像头图片格式 */
printf("Picture Format: %sn", fmt.description);
/* 查询该图像格式所支持的分辨率 */
struct v4l2_frmsizeenum frmsize;
frmsize.pixel_format = fmt.pixelformat;
for (int j = 0; ; j++) // 该格式支持分辨率不止一种
{
frmsize.index = j;
ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
if (-1 == ret) // 获取所有图片分辨率完成
{
break;
}
/* 打印图片分辨率 */
printf("width: %d height: %dn",
frmsize.discrete.width,frmsize.discrete.height);
}
}
成功获取了相机的设备信息接下来就是采集图像
V4L2采集图像基本流程
按照上面这篇博客的程序成功获取了相机的图像,但运行一会系统就会奔溃重启,报错
Unable to handle kernel paging request at virtual address 806a7add之类的,主要是内存访问的问题,于是按照下面这篇文章重新修改了一些部分。
uchar *buffer; //buffers 指针记录缓冲帧
将原始数据缓存改成下面这个形式
struct buffer
{
void * start;
unsigned int length;
} * buffers;
USB摄像头(V4L2接口)的图片采集
还是一直报内存错误,然后就是重启,增加队列数到30就持续运行了1000多帧,但开启图像处理, 用时增加从25ms到186ms, 再进行几十帧就崩溃重启了。
而且存在一个问题就是明明帧率有20,但qt显示却很卡,一两秒刷新一次!!!但我刚成功获取图像时并不卡。
我应该在虚拟机上先把代码调通了,再移植到板子上,主要的代码是V4L2, Linux系统共有的。
举报