嵌入式系统程序调试
练习GDB调试
gdb广泛应用于操作系统中
使用GDB我们可以:
– 设置断点使程序停住
– 监视或修改程序中变量的值
– 跟踪代码执行过程
gdb调试
想要使用gdb,首先在编译文件时需要加上命令(假如我创建的文件为main.c)
gcc -g -o main main.c
gdb段错误调试
创建文件输入下列代码
#include<stdio.h>
#include<string.h>
#define BUFSIZE 256
static char acBuf[BUFSIZE];
static char *pstr;
int main(void)
{
printf("please input a string:");
gets(pstr);
printf("\nyour string is:%s\n",pstr);
}
编译文件时报错,我们用gdb来查看是哪行出错了
通过gdb逐步排查可以看到是第11行错了,我们将pstr修改为acBuf的值
这样程序就能运行成功了,得到了我们想要的结果
gdb调试举例
创建文件main输入下列代码
#include <stdio.h>
void ShowRevertNum(int iNum)
{
while (iNum > 10)
{
printf("%d", iNum % 10);
iNum = iNum / 10;
}
printf("%d\n", iNum);
}
int main(void)
{
int iNum;
printf("Please input a number :");
scanf("%d", &iNum);
printf("After revert : ");
ShowRevertNum(iNum);
}
使用gdb调试
使用 l 可以查看代码的内容和行数
b 15意思是在第15行设置断点
b 函数名意思是在该函数处设置断点
info b 意思是查看所有的断点
run 意思是运行程序
core文件的使用
Linux中,程序崩溃时,一般会产生core文件,记录进程退出前的状态,调试段错误问题,借助于该文件,可快速定位问题
可按如下步骤生成和使用core文件
– Step 1: 让系统产生core文件
• ulimit –c num #设定core文件容量(num为数字,为0
是不产生core文件)
– Step 2: 运行程序,让程序崩溃,从而生成core文件
– Step 3: gdb配合core文件,定位问题
• gdb 程序名 core文件名
• 比如: gdb segDemo core
例子:
利用core文件定位以下出错代码
#include<stdio.h>
int main()
{
int *p=0;
*p=1;
return 0;
}
完成的步骤如下:
可以看出在红圈中显示的是代码的第五行有错
gdb调试和core文件的联合使用能够帮助我们对错误代码准确的定位,特别是代码数量多时,提高我们的效率。
ubutun16.04下安装opencv3.4.11
这里参考了下学姐的教程
https://cungudafa.blog.csdn.net/article/details/84451066
在linux中搜索opencv直接下载即可,也可以在window中下载后直接拖入ubutun中。
1、下载好安装包后将安装包复制到home目录下
2、解压安装包
unzip opencv-3.4.11.zip
然后进入到安装包中(这步很重要,影响后面的安装)
cd opencv-3.4.11
3、安装cmake和依赖库
先sudo su进入root权限,再sudo apt-get update,然后在执行下面命令
sudo apt-get install cmake
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev
4、创建编译文件夹并进入
mkdir my_build_dir
cd my_build_dir
然后输入命令
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
然后输入
sudo make
下载过程漫长,耐心等待
完成后执行命令
sudo make install
opencv的编译就完成了,接下来我们配置编译环境
5、配置编译环境
输入命令,会弹出一个空白文件
sudo gedit /etc/ld.so.conf.d/opencv.conf
在文件中复制下面代码
/usr/local/lib
保存后退出执行命令
sudo ldconfig
配置bash
sudo gedit /etc/bash.bashrc
在文件末尾加入代码
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
保存后执行命令
source /etc/bash.bashrc
然后更新
sudo updatedb
完成后opencv配置完成可以使用了
opencv实战
进入opencv3.4.11中
cd opencv-3.4.11
创建新的目录并进入(用来放图片,编程序)
mkdir mytest
cd mytest
创建文件test.cpp,并输入下列代码
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image = cvLoadImage("lena.jpg");
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2, image->height / 2);
for (int i = 0;i<image->height;i++)
for (int j = 0;j<image->width;j++) {
double dx = (double)(j - center.x) / center.x;
double dy = (double)(i - center.y) / center.y;
double weight = exp((dx*dx + dy*dy)*scale);
uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src;Mat dst;
src = cvarrToMat(image);
cv::imwrite("test.png", src);
cvNamedWindow("test",1); imshow("test", src);
cvWaitKey();
return 0;
}
输入下列命令编译
g++ test.cpp -o test `pkg-config --cflags --libs opencv`
在网上随便下载图片放到mytest目录下
注意:图片名称改为lena.jpg,或者在函数中修改图片的名称
运行命令
./test
得到结果,图片周围的颜色变黑了
编写一个打开摄像头显示处理视频的程序代码
程序代码:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture(0);
while(1)
{
Mat frame;
capture >> frame;
imshow("读取视频帧",frame);
waitKey(30);
}
system("pause");
return 0;
}
安装cheese
sudo apt-get install cheese
如果cheese打开是黑屏的情况就点虚拟机->设置->USB控制器,将USB3.0变成2.0或者将2.0变成3.0
编译代码
gcc test1.cpp -o test1 `pkg-config --cflags --libs opencv`
运行结果,调出了摄像头
总结
1、如果要求打开你硬盘上一个视频文件来播放,请问第7行代码如何修改?
VideoCapture capture(“视频名.mp4”);
2、在第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
Mat是一个类,由两部分数据组成:矩阵头和一个指向所有像素值的矩阵的指针。如果不加waitKey的话,视屏不能显示,会消失,不能删除。
3、此代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
在13行后中加入
if(frame.empty())
{
break;
}
经过这次嵌入式系统程序调试试验,不仅使我对gdb的程序调试有了初步掌握,而且让我对摄像头的调用有了解,原来在虚拟机中还能完成这么多操作,还有许多的应用没有被使用,希望以后多使用,发现更多功能。