嵌入式作业(四)
GDB调试
1.1 GDB简介
- GDB : GNU Debugger,GDB可以运行在UNIX、Linux甚至Microsoft Windows。它可以调试C、C++、Objective-C、Pascal、Ada等语言编写的程序
- 使用GDB我们可以:
1.设置断点使程序停住
2.监视或修改程序中变量的值
3.跟踪代码执行过程
1.2 常用GDB命令
- file 装入想要调试的可执行文件。
- kill 终止正在调试的程序。
- next 执行一行源代码但不进入函数内部。
- list 列出产生执行文件的源代码的一部分。
- step 执行一行源代码而且进入函数内部。
- break 在代码里设断点,这将使程序执行到这里时被挂起。
1.根据行号设置断点:(gdb) break linenum
2.根据函数名设置断点: (gdb) break funcname - print 查看变量的值。
- make 使你能不退出gdb就可以重新产生可执行文件。
- shell 使你能不离开gdb就执行UNIX shell命令。
- Finish 终止当前函数并输出返回值。
- ctrl+c:退出输入
1.3 GDB调试实例
1.创建一个任意c程序:lianxi.c
lianxi.c代码如下(ppt上的代码)
#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);
}
2.设置断点
- 命令行输入 gdb + 可执行文件名 进入调试模式
- 命令行输入 l(list),显示代码行数(一次只能显示10行)
- 命令行输入b (break)设置断点,分别用通过行数,通过函数名设置
3.开始调试 - 运行(run)
- 查看iNum数据类型(whatis)、iNum的值(print)
- 继续执行并查看iNum的值
- 开始单步调试(next)
这样就可以看出函数是在哪一步出错
比如练习程序中,可以看出,倒数第三行时,iNum=10,以见是while条件出错,将while(iNum>10)改为while(iNum>=10).
以下是修改后的程序:
Opencv
2.1 ubantu16.04安装opencv-3.4.1
安装过过程过于繁琐,见博客
ubantu16.04安装opencv-3.4.1
2.2 编写一个打开图片进行特效显示的代码
1.在opencv-3.4.1下新建文件夹mytest
cd opencv-3.4.1
2.创建cpp文件
test源码见以下链接:2.3 Linux下编程
源码
3.g++编译
g++ text.cpp -o test `pkg-config --cflags --libs opencv
4.执行文件
sudo ./test
这里图片名应为lena.jpg(可以通过修改程序改名)
gcc编译器:gcc +文件名+ -o+输出文件流名称 +` 支持包
2.2 编写一个打开摄像头显示处理视频的程序代码
参考代码1
#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;
Q1:如果要求打开你硬盘上一个视频文件来播放,请问第4行代码如何修改?
A1:将括号里的0改为—>“路径+视频名”(如“Downloads/1111.avi”)
Q2:在第5行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
A2:Mat有两部分组成
头部:存储方式、图像大小等信息,头部的大小是一个常量(constant)
数据块:图像像素的值(按行顺序存储)
Q3:此代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
A3:添加一行可以停止程序的代码,break,当输入一个字符对它进行判定。
参考代码2
/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return;
}
//获得cap的分辨率
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;//记录键盘按键
char startOrStop = 1;//0 开始录制视频; 1 结束录制视频
char flag = 0;//正在录制标志 0-不在录制; 1-正在录制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格开始录制、暂停录制 可以来回切换
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
return 0;
}
总结
3.1 关于1.3 GDB调试过程中的错误
错误:
第一次调试时出现了这个问题,意思是没有printf.c这个文件
错误原因:
参考ppt中,单步调试使用的是step,上面解释过step的含义是:执行一行源代码而且进入函数内部。
printf也是一个函数,而在这个文件夹中并没有printf.c,所以出现了这个错误
这里把step改为next就可以了
3.2 关于2.2中最后一步gcc的实现
Q: gcc test1.cpp -o test1 pkg-config --cflags --libs opencv
这条编译命令,它是如何获得opencv头文件、链接lib库文件的路径的?
A:这一步主要是pkg-config完成了这些工作
pkg-config是一个linux下的命令,用于获得某一个库/模块的所有编译相关的信息。
部分命令如下:
其中,这里用到的–cflags 和–libs
--cflags output all pre-processor and compiler//输出全部的预处理与编译
--libs output all linker flags //输出链接库