水比赛专用-蓝牙调试器

这篇具有很好参考价值的文章主要介绍了水比赛专用-蓝牙调试器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


做比赛的时候免不了要做一些页面方面的展示,亦或者一些遥控什么的方面的远程启动,常见的无线通信方式如蓝牙,wifi等是很多大学生竞赛中的常客,因此这里我就把我之前用的很熟的一款蓝牙调试器给分享下,同时也算是做个记录吧!

该调试器是某大佬做的,我只是应用,这里特别感谢这位大佬,提供了这么好用的工具,yyds!,原文链接如下:https://www.jianshu.com/p/1a8262492619

1、蓝牙调试器介绍

此蓝牙调试器为上面提到的大佬一个月开发的,其基于安卓设备,通过安卓设备的蓝牙通信功能实现单片机的无线调试。编写这款软件的目的主要是为了盈利, 嗯,当然是为了广大的单片机开发爱好者,拯救他们于繁琐的调试步骤之中,常用的logo如下:
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言

这个我们要用的时候直接去应用市场下载即可,经过我个人总结,该调试器支持的功能如下所示:

  • 1、普通的串口收发显示
  • 2、类似普通蓝牙调试器的按钮收发
  • 3、支持自定义功能的界面开发,界面支持摇杆,按钮,开关等常见的设备
  • 4、支持对话框等页面

基本就是有的东西都有了,可以当成一些遥控来用了,这里再次感谢作者!

2、功能体验

首先是这个蓝牙连接这里,这里有个老大的bug,这是我对这个软件唯一不满的地方了,这里要打开定位才能用,对于我一个平时不怎么开定位的人来说,真是太难受了!,这里一定要注意,不然不太能搜到设备!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言

下面来看下一个基本的蓝牙调试器应该有的页面普通按钮页面,这里也就是比较常规
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
然后是对话框,对话框也是很基本的功能了
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
好,下面就是重点这个可以自己编辑的页面了,下面是我之前做的一个项目的页面,基本就是托快快来实现这个页面的编辑,然后就是一些绑定数据了,所以在进行这个页面的编辑之前最重要的还是先设置我们的数据

蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
这里作者将数据按照类型来分类,因为他们所占的字节不一样,作者这样设置就可以方便的处理数据了,其中数据包的构成作者在这个下图的数据包结构设置一栏中已经进行了说明,是可以很清楚的看到的。
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
当然就是接收数据包也是需要编辑的,接收数据包也是跟发送数据包一样的布局设置
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
然后这里作者还指出了蓝牙收发一个特点就是这里讲到的延时,蓝牙数据量确实是比较小的,所以发送大量数据自然就会产生一定的延时,这里作者已经提到了,所以这个系统不太适合就是需要迅速反馈的系统的!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
同时作者还提供了一些例程代码,主要是包含轮询,中断还有DMA三种方式进行的收发,源码在我上面贴的作者的链接中可以找到这里不再进行赘述,下面我将用HAL库的方式对他进行移植,以方便我们后续的开发设计!

3、程序移植

首先我们需要定义好用到的串口,串口参数这里保持默认即可!
这里注意:

  • 蓝牙是用AT指令开发的,默认的波特率是9600,可以先用串口助手对波特率进行相应的修改
  • 蓝牙的AT指令类似esp8266的,基本上去淘宝店的资料页都能找到怎么用AT指令进行设置
  • HC-05,HC-06这种的都有一个按键,设置AT指令的时候别忘了按下那个按键

蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
之后是开启DMA,前面已经说过了,要移植肯定是移植DMA的,移植常规轮询方法和中断方法的都没什么意思,所以这里首选DMA,这才是最高效的方案!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
下面我嫩来认识下.h文件,这个文件其实就是每次修改工程要改的东西了,其实挺重要的就是,这里作者提供了宏参数供我们修改,这里的宏参数要和设置的一样,这样才能确保我们通信的正常,因为这个决定了我们每次数据包的大小!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
下面就是数据接收函数了,数据接收函数就是要注意这个接收函数的这里计算数据长度的这个变量!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
数据发送函数,直接使用官方的库函数即可,不用这么啰嗦,因为CUBEMX都帮我们配置好了
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
之后就可以在主函数中调用来实现效果了!

4、实现效果

在初始化中我们需要开启DMA接收这个参数,这样才可以接受DMA的数据,因为DMA开的是循环,所以我们后面就可以不用关注他了
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
这里我们要读取数据,需要定义数据结构体,并周期性的读取数据,官方给的要求是每秒不低于十次,这里可以根据自己的需要进行设置!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言
将程序下载到开发板,并根据我们之前在手机上位机中设置的摇杆,开关灯,移动摇杆开关等,就可以看到数据变化了!
蓝牙调试器,单片机学习记录,stm32,单片机,嵌入式硬件,mcu,c语言

5、源码

注意本源码适用于串口2,需要修改为其他串口请根据我前面提到的方法去修改!

valuepack.h

/*
 * valuepack.c
 *
 *  Created on: Mar 31, 2022
 *      Author: LX
 */


#include "valuepack.h"
#include "dma.h"
#include "usart.h"


//DMA下进行的数据传输

unsigned char bits[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

const unsigned int VALUEPACK_INDEX_RANGE = VALUEPACK_BUFFER_SIZE << 3;
//const unsigned short TXPACK_BYTE_SIZE = ((TX_BOOL_NUM + 7) >> 3) + TX_BYTE_NUM + (TX_SHORT_NUM << 1) + (TX_INT_NUM << 2) + (TX_FLOAT_NUM << 2);
//const unsigned short RXPACK_BYTE_SIZE = ((RX_BOOL_NUM + 7) >> 3) + RX_BYTE_NUM + (RX_SHORT_NUM << 1) + (RX_INT_NUM << 2) + (RX_FLOAT_NUM << 2);
#define TXPACK_BYTE_SIZE ((TX_BOOL_NUM + 7) >> 3) + TX_BYTE_NUM + (TX_SHORT_NUM << 1) + (TX_INT_NUM << 2) + (TX_FLOAT_NUM << 2)
#define RXPACK_BYTE_SIZE ((RX_BOOL_NUM + 7) >> 3) + RX_BYTE_NUM + (RX_SHORT_NUM << 1) + (RX_INT_NUM << 2) + (RX_FLOAT_NUM << 2)

unsigned short rx_pack_length = RXPACK_BYTE_SIZE + 3;

long rxIndex = 0;
long rdIndex = 0;
//发送和接收缓冲区
unsigned char vp_rxbuff[VALUEPACK_BUFFER_SIZE];
unsigned char vp_txbuff[TXPACK_BYTE_SIZE + 3];

//extern UART_HandleTypeDef huart2;
//extern DMA_HandleTypeDef hdma_usart2_rx;
//extern DMA_HandleTypeDef hdma_usart2_tx;


//变量标志
unsigned short this_index = 0;
unsigned short last_index = 0;
unsigned short rdi, rdii, idl, idi;
uint32_t idc;
unsigned int err = 0;
unsigned char sum = 0;
unsigned char isok;

//接收数据包解析
unsigned char readValuePack(RxPack *rx_pack_ptr)
{
	isok = 0;
	this_index = VALUEPACK_BUFFER_SIZE - DMA1_Channel6->CNDTR;
	if (this_index < last_index)
		rxIndex += VALUEPACK_BUFFER_SIZE + this_index - last_index;
	else
		rxIndex += this_index - last_index;
	while (rdIndex < (rxIndex - ((rx_pack_length))))
		rdIndex += rx_pack_length;
	while (rdIndex <= (rxIndex - rx_pack_length))
	{

		rdi = rdIndex % VALUEPACK_BUFFER_SIZE;
		rdii = rdi + 1;
		if (vp_rxbuff[rdi] == PACK_HEAD)
		{
			if (vp_rxbuff[(rdi + RXPACK_BYTE_SIZE + 2) % VALUEPACK_BUFFER_SIZE] == PACK_TAIL)
			{
				//  计算校验和
				sum = 0;
				for (short s = 0; s < RXPACK_BYTE_SIZE; s++)
				{
					rdi++;
					if (rdi >= VALUEPACK_BUFFER_SIZE)
						rdi -= VALUEPACK_BUFFER_SIZE;
					sum += vp_rxbuff[rdi];
				}
				rdi++;
				if (rdi >= VALUEPACK_BUFFER_SIZE)
					rdi -= VALUEPACK_BUFFER_SIZE;
				if (sum == vp_rxbuff[rdi])
				{
//  提取数据包数据 一共有五步, bool byte short int float
// 1. bool
#if RX_BOOL_NUM > 0

					idc = (uint32_t)rx_pack_ptr->bools;
					idl = (RX_BOOL_NUM + 7) >> 3;
					for (idi = 0; idi < idl; idi++)
					{
						if (rdii >= VALUEPACK_BUFFER_SIZE)
							rdii -= VALUEPACK_BUFFER_SIZE;
						(*((unsigned char *)idc)) = vp_rxbuff[rdii];
						rdii++;
						idc++;
					}
#endif
// 2.byte
#if RX_BYTE_NUM > 0
					idc = (uint32_t)(rx_pack_ptr->bytes);
					idl = RX_BYTE_NUM;
					for (idi = 0; idi < idl; idi++)
					{
						if (rdii >= VALUEPACK_BUFFER_SIZE)
							rdii -= VALUEPACK_BUFFER_SIZE;
						(*((unsigned char *)idc)) = vp_rxbuff[rdii];
						rdii++;
						idc++;
					}
#endif
// 3.short
#if RX_SHORT_NUM > 0
					idc = (uint32_t)(rx_pack_ptr->shorts);
					idl = RX_SHORT_NUM << 1;
					for (idi = 0; idi < idl; idi++)
					{
						if (rdii >= VALUEPACK_BUFFER_SIZE)
							rdii -= VALUEPACK_BUFFER_SIZE;
						(*((unsigned char *)idc)) = vp_rxbuff[rdii];
						rdii++;
						idc++;
					}
#endif
// 4.int
#if RX_INT_NUM > 0
					idc = (uint32_t)(&(rx_pack_ptr->integers[0]));
					idl = RX_INT_NUM << 2;
					for (idi = 0; idi < idl; idi++)
					{
						if (rdii >= VALUEPACK_BUFFER_SIZE)
							rdii -= VALUEPACK_BUFFER_SIZE;
						(*((unsigned char *)idc)) = vp_rxbuff[rdii];
						rdii++;
						idc++;
					}
#endif
// 5.float
#if RX_FLOAT_NUM > 0
					idc = (uint32_t)(&(rx_pack_ptr->floats[0]));
					idl = RX_FLOAT_NUM << 2;
					for (idi = 0; idi < idl; idi++)
					{
						if (rdii >= VALUEPACK_BUFFER_SIZE)
							rdii -= VALUEPACK_BUFFER_SIZE;
						(*((unsigned char *)idc)) = vp_rxbuff[rdii];
						rdii++;
						idc++;
					}
#endif
					err = rdii;
					rdIndex += rx_pack_length;
					isok = 1;
				}
				else
				{
					rdIndex++;
					err++;
				}
			}
			else
			{
				rdIndex++;
				err++;
			}
		}
		else
		{
			rdIndex++;
			err++;
		}
	}
	last_index = this_index;
	return isok;
}

void sendBuffer(unsigned char *p, unsigned short length)
{
//	DMA_DeInit(DMA1_Channel4);
//	dma.DMA_DIR = DMA_DIR_PeripheralDST;
//	dma.DMA_M2M = DMA_M2M_Disable;
//	dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//	dma.DMA_PeripheralBaseAddr = (uint32_t) & (USART1->DR);
//	dma.DMA_Priority = DMA_Priority_High;
//	dma.DMA_BufferSize = length;
//	dma.DMA_MemoryBaseAddr = (uint32_t)p;
//	dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
//	dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
//	dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
//	dma.DMA_Mode = DMA_Mode_Normal;
//	DMA_Init(DMA1_Channel4, &dma);
//	DMA_Cmd(DMA1_Channel4, ENABLE);

	HAL_UART_Transmit_DMA(&huart2,p,length);
}
unsigned short loop;
unsigned char valuepack_tx_bit_index;
unsigned char valuepack_tx_index;
void sendValuePack(TxPack *tx_pack_ptr)
{
	int i;
	vp_txbuff[0] = 0xa5;
	sum = 0;
	//  由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理
	valuepack_tx_bit_index = 0;
	valuepack_tx_index = 1;
#if TX_BOOL_NUM > 0
	for (loop = 0; loop < TX_BOOL_NUM; loop++)
	{
		if (tx_pack_ptr->bools[loop])
			vp_txbuff[valuepack_tx_index] |= 0x01 << valuepack_tx_bit_index;
		else
			vp_txbuff[valuepack_tx_index] &= ~(0x01 << valuepack_tx_bit_index);

		valuepack_tx_bit_index++;
		if (valuepack_tx_bit_index >= 8)
		{
			valuepack_tx_bit_index = 0;
			valuepack_tx_index++;
		}
	}
	if (valuepack_tx_bit_index != 0)
		valuepack_tx_index++;
#endif
#if TX_BYTE_NUM > 0

	for (loop = 0; loop < TX_BYTE_NUM; loop++)
	{
		vp_txbuff[valuepack_tx_index] = tx_pack_ptr->bytes[loop];
		valuepack_tx_index++;
	}

#endif
#if TX_SHORT_NUM > 0
	for (loop = 0; loop < TX_SHORT_NUM; loop++)
	{
		vp_txbuff[valuepack_tx_index] = tx_pack_ptr->shorts[loop] & 0xff;
		vp_txbuff[valuepack_tx_index + 1] = tx_pack_ptr->shorts[loop] >> 8;
		valuepack_tx_index += 2;
	}
#endif
#if TX_INT_NUM > 0
	for (loop = 0; loop < TX_INT_NUM; loop++)
	{
		i = tx_pack_ptr->integers[loop];

		vp_txbuff[valuepack_tx_index] = i & 0xff;
		vp_txbuff[valuepack_tx_index + 1] = (i >> 8) & 0xff;
		vp_txbuff[valuepack_tx_index + 2] = (i >> 16) & 0xff;
		vp_txbuff[valuepack_tx_index + 3] = (i >> 24) & 0xff;

		valuepack_tx_index += 4;
	}
#endif
#if TX_FLOAT_NUM > 0
	for (loop = 0; loop < TX_FLOAT_NUM; loop++)
	{
		i = *(int *)(&(tx_pack_ptr->floats[loop]));

		vp_txbuff[valuepack_tx_index] = i & 0xff;
		vp_txbuff[valuepack_tx_index + 1] = (i >> 8) & 0xff;
		vp_txbuff[valuepack_tx_index + 2] = (i >> 16) & 0xff;
		vp_txbuff[valuepack_tx_index + 3] = (i >> 24) & 0xff;

		valuepack_tx_index += 4;
	}
#endif
	for (unsigned short d = 1; d <= TXPACK_BYTE_SIZE; d++)
		sum += vp_txbuff[d];
	vp_txbuff[TXPACK_BYTE_SIZE + 1] = sum;
	vp_txbuff[TXPACK_BYTE_SIZE + 2] = 0x5a;
	sendBuffer(vp_txbuff, TXPACK_BYTE_SIZE + 3);
}

valuepack.h文章来源地址https://www.toymoban.com/news/detail-790539.html

/*
 * valuepack.h
 *
 *  Created on: Mar 31, 2022
 *      Author: LX
 */

#ifndef VALUEPACK_H_
#define VALUEPACK_H_

#include "main.h"

// 本程序通过DMA和USART 进行数据包的接收和发送
// 接收的数据自动写入到buffer中,通过定时调用readValuePack()函数来解析,定时间隔建议在10ms以内。
// 数据发送也采用DMA

// 1.指定接收缓冲区的大小 --------------------------------------------------------------------------------
// 一般需要512字节以上,需要根据实际接收数据的速度和proc函数的频率考虑。
#define VALUEPACK_BUFFER_SIZE 1024

// 2.指定发送到手机的数据包的结构----------在发送时会自动额外在前后加上包头,包尾和校验和数据,因此会多出3个字节
// 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目

#define TX_BOOL_NUM 0
#define TX_BYTE_NUM 0
#define TX_SHORT_NUM 3
#define TX_INT_NUM 0
#define TX_FLOAT_NUM 1

// 3.指定接收数据包的结构-----------------------------------------------------------------------------------
// 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目

#define RX_BOOL_NUM 0
#define RX_BYTE_NUM 4
#define RX_SHORT_NUM 3
#define RX_INT_NUM 0
#define RX_FLOAT_NUM 0

typedef struct
{
#if TX_BOOL_NUM > 0
	unsigned char bools[TX_BOOL_NUM];
#endif

#if TX_BYTE_NUM > 0
	char bytes[TX_BYTE_NUM];
#endif

#if TX_SHORT_NUM > 0
	short shorts[TX_SHORT_NUM];
#endif

#if TX_INT_NUM > 0
	int integers[TX_INT_NUM];
#endif

#if TX_FLOAT_NUM > 0
	float floats[TX_FLOAT_NUM];
#endif
	char space; // 无意义,只为了不让结构体为空,结构体为空会报错。
} TxPack;
typedef struct
{
#if RX_BOOL_NUM > 0
	unsigned char bools[RX_BOOL_NUM];
#endif

#if RX_BYTE_NUM > 0
	char bytes[RX_BYTE_NUM];
#endif

#if RX_SHORT_NUM > 0
	short shorts[RX_SHORT_NUM];
#endif

#if RX_INT_NUM > 0
	int integers[RX_INT_NUM];
#endif

#if RX_FLOAT_NUM > 0
	float floats[RX_FLOAT_NUM];
#endif
	char space; // 无意义,只为了不让结构体为空,结构体为空会报错。
} RxPack;
// 初始化 valuepack 包括一些必要的硬件外设配置

//void initValuePack(int baudrate);

// 需要保证至少每秒执行10次该函数
// 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。
// 接收到数据包时 返回 1 ,否则返回 0
unsigned char readValuePack(RxPack *rx_pack_ptr);
// 发送数据包
void sendValuePack(TxPack *tx_pack_ptr);

#define PACK_HEAD 0xa5
#define PACK_TAIL 0x5a

#endif /* VALUEPACK_H_ */

到了这里,关于水比赛专用-蓝牙调试器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux调试器gdb

    本文已收录至《 Linux知识与编程 》专栏! 作者: ARMCSKGT 演示环境: CentOS 7     ​ 目录 前言 正文 下载gdb 生成可调式文件 进入gdb gdb常用指令 查看代码 l  运行程序 r  断点设置 b  显示信息 info  查看断点 info b  删除断点 d  禁用断点 disable breakpoints  启用断点 enable brea

    2024年02月14日
    浏览(53)
  • Windows高级调试(学习笔记)-第二章-调试器介绍

    2.1.1 Debugger Types调试器类型 User Mode Deduggers(用户态调试器) 实时调试(Living Debugging)、事后调试(Postmortem Debugging) 三个用户态调试器:cdb.exe、nstd.exe及windbg.exe Kernel Mode Debugger(内核态调试器) 可以分析计算机系统 二个内核态调试器:kd.exe及windbg.exe 2.1.2 Debugger Commands调试器命令 buil

    2024年01月18日
    浏览(68)
  • Linux调试器之gdb

    我们前面介绍了几个基本的环境开发工具。例如通过yum我们可以安装和卸载软件、通过vim我们可以写代码、通过gcc和g++我们可以编译代码成可执行程序。但是如何在Linux下调试代码呢?我们并未介绍,本期我们将来介绍最后一个工具 --- 调试器gdb。 程序的发布方式 gdb基本的调

    2024年04月16日
    浏览(67)
  • 调试器是个大骗子!

    我叫GDB,是一个调试器,程序员通过我可以调试他们编写的软件,分析其中的bug。 作为一个调试器,调试分析是我的看家本领,像是给目标进程设置断点,或者让它单步执行,又或是查看进程中的变量、内存数据、CPU的寄存等等操作,我都手到擒来。 你只要输入对应的命令

    2024年02月02日
    浏览(41)
  • Linux | 调试器GDB的详细教程【纯命令行调试】

    学习了【vim】知道了如何 编辑 一个代码文本 学习了【gcc】知道了如何 编译 一个代码文本 学习了【make/Makefile】知道了如何 自动化构建 一个代码文本 但是如何对一段代码去进行调试呢,此时就要使用到 Linux下的调试器gdb 了。对于这个调试器来说,不像是VS中那样的图形化界

    2024年02月02日
    浏览(54)
  • 【Linux】gdb调试器的使用

    文章目录 一、gdb简介 二、调试前的准备 1、生成调试文件 2、启动 gdb  三、gdb 使用方法  1、查看源代码 2、设置 / 查看断点(多种方式设置断点) 方法一 方法二 方法三 3、run  4、删除断点、断点无效 5、逐过程调试(以函数为单位) 6、逐语句调试 7、查看调用链 8、查看变

    2024年02月02日
    浏览(52)
  • 【Linux】——调试器-gdb的使用

    序言: 本期,我将带领大家学习的关于linux下的 调试器gdb 的使用,废话不多说跟着我一起去看看吧!! 目录 前言 (一)背景介绍 1、debug模式和release模式 2、为什么Release不能调试但DeBug可以调试 3、初步见识 1️⃣readelf (二)调试代码 1、命名大全 2、具体演示 0️⃣行号显

    2024年02月07日
    浏览(41)
  • [Linux] Linux代码调试器 -- gdb

    1、程序的发布方式有两种,debug模式和release模式 2、Linux gcc/g++出来的二进制程序,默认是release模式 3、要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 我们先来写一段C语言代码: 这里我们正常再编写一个Makefile文件,用于自动化构建,我们要还是正常的编

    2024年02月05日
    浏览(43)
  • 【Linux】Linux调试器-gdb使用

    程序的发布方式有两种,debug模式和release模式 Linux gcc/g++出来的二进制程序,默认是release模式 要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 退出:  调试命令: list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。 list/l 函数名:列出某

    2024年02月21日
    浏览(49)
  • 【Linux】调试器:gdb 的基本使用

    gdb 全称 GNU symbolic debugger,是 Linux 下常用的程序调试器。 调试器的核心工作,主要是为了定位问题。废话不多说。 gdb 的安装 另外: gcc、g++ 默认形成的版本是 release,不是 debug 版本!所以想要在 Linux 下调试程序,需要在 Makefile 文件 中,添加 -g 选项 指定以 dubug 方式编译程

    2024年02月16日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包