KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 4

2024 电商订单明细数据集(24列,382287条记录)CSV 详情介绍:该数据集为 2024 年电商订单明细,可以关联电商用户画像数据集(16列, 98673条记录)CSV,覆盖食品生鲜 / 3C 电子 / 美妆护肤 / 家居日用 / 服装鞋帽 5 大类、15 个品牌,平均客单价 1717 元、支付宝 + 微信支付占 75%、88% 订单无促销、取消率 5%,适合做 RFM 用户分层、购物篮关联分析、销售预测和促销效果评估。 立即下载

优快云开源夏令营 - 第四周工作总结


本周主要是在回顾“set trace-buffer-size”完成通信的基础上,对于指定参数size的处理,比如指定-1或者unlimited的时候,在KGTP端该如何做解析,以及该如何处理此时的buffer size。同时,根据“开题报告"的进度,中期检查的任务已经完成。对Trace Buffer的实现,做了初步的调研。

1. GDB和KGTP通信实现的回顾

利用GDBRSP,即GDB Remote Serial Protocol,GDB远程串行通信协议。简单来说,用于GDB远程调试发包,但是也支持File I/O和Console,而KGTP正是利用了GDBRSP对于File I/O的支持,完成GDB和KGTP的通信,在接受到GDB发送的Packet后,KGTP进行解析。而通信的介质则是通过debugfs或者其他kernel space和user space进行数据交换的接口进行的。
具体实现,可以参考上一篇博文[1]。

2. GDB的Packet格式

GDB向target发送的Packet必须遵守提前设定的约定,才能被target按照相应的规则解析处理。关于GDB的Packet格式,可以参考[2],这里详细列出了所有的预定义的指令和它们相应的响应数据。如果想进一步了解GDBRSP,可以阅读[3]。由于KGTP对Trace Point最感兴趣,因此我们也最关注Tracepoint Packets,只要有两种,分别以Q和q开头,其中Q表示设置命令,即set,而q表示查询命令,即query,具体看[4]。关于如何开始和停止Trace Experiments,看[5]。GDB对于用户输入的commands,会转换后封装成Packet,通过GDBRSP发给target,因此需要结合着[4]和[5]才能把对某一个命令如何进行包解析搞清楚,比如用户输入”tstart“,则会发送一个”QTStart“的包。

3. KGTP对GDB的Packet的处理实现

有了GDB和KGTP的通信的基础设施,比如DebugFS和GDBRSP,正常的文件读写即可完成GDB和KGTP的数据交换。而为了完成相应的任务,KGTP必须对接收到的GDB的Packet进行解析,而我们又知道了GDB得Packet格式,因此只需要对接收到的数据按照格式做相应的解析即可。

在gtp.c的gtp_write函数,针对接收到的GDB包做了具体的解析,具体代码如下:

static ssize_t
gtp_write(struct file *file, const char __user *buf, size_t size,
	  loff_t *ppos)
{
	char		*rsppkg = NULL;
	int		i, ret;
	unsigned char	csum;
	int		is_reverse;

	if (down_interruptible(>p_rw_lock))
		return -EINTR;

	if (size == 0) {
#ifdef GTP_DEBUG
		printk(GTP_DEBUG "gtp_write: try write 0 size.\n");
#endif
		goto error_out;
	}

	size = min_t(size_t, size, GTP_RW_MAX);
	if (copy_from_user(gtp_rw_buf, buf, size)) {
		size = -EFAULT;
		goto error_out;
	}

	if (gtp_rw_buf[0] == '+' || gtp_rw_buf[0] == '-'
	    || gtp_rw_buf[0] == '\3' || gtp_rw_buf[0] == '\n') {
		if (gtp_rw_buf[0] == '+')
			gtp_rw_size = 0;
		size = 1;
		goto out;
	}

	if (size < 4) {
		size = -EINVAL;
		goto error_out;
	}
	/* Check format and get the rsppkg.  */
	for (i = 0; i < size - 2; i++) {
		if (gtp_rw_buf[i] == '$')
			rsppkg = gtp_rw_buf + i + 1;
		else if (gtp_rw_buf[i] == '#')
			break;
	}
	if (rsppkg && gtp_rw_buf[i] == '#') {
		/* Format is OK.  Check crc.  */
		if (gtp_noack_mode < 1)
			gtp_read_ack = 1;
		size = i + 3;
		gtp_rw_buf[i] = '\0';
	} else {
		printk(KERN_WARNING "gtp_write: format error\n");
		size = -EINVAL;
		goto error_out;
	}

	wake_up_interruptible_nr(>p_rw_wq, 1);

	up(>p_rw_lock);
	if (down_interruptible(>p_rw_lock))
		return -EINTR;

#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_write: %s\n", rsppkg);
#endif

	/* Handle rsppkg and put return to gtp_rw_buf.  */
	gtp_rw_buf[0] = '$';
	gtp_rw_bufp = gtp_rw_buf + 1;
	gtp_rw_size = 0;
	ret = 1;
	is_reverse = 0;
	switch (rsppkg[0]) {
	case '?':
		if (gtp_current_pid == 0)
			snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "S05");
		else
			snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "T05;thread:p%x.%x;",
				 gtp_current_pid, gtp_current_pid);
		gtp_rw_size += strlen(gtp_rw_bufp);
		gtp_rw_bufp += strlen(gtp_rw_bufp);
		break;
	case 'g':
		ret = gtp_gdbrsp_g();
		break;
	case 'm':
		ret = gtp_gdbrsp_m(rsppkg + 1);
		break;
	case 'Q':
#ifdef GTP_RB
		/* This check for "tfind -1" and let GDB into step replay.
		   XXX: just test on X86_64.  */
		if (gtp_replay_step_id) {
			if (strcmp("QTFrame:ffffffff", rsppkg) == 0) {
				ret = 0;
				goto switch_done;
			} else
				gtp_replay_reset();
		}
#endif
		if (rsppkg[1] == 'T')
			ret = gtp_gdbrsp_QT(rsppkg + 2);
		else if (strncmp("QStartNoAckMode", rsppkg, 15) == 0) {
			ret = 0;
			gtp_noack_mode = -1;
		}
		break;
	case 'q':
		if (rsppkg[1] == 'T')
			ret = gtp_gdbrsp_qT(rsppkg + 2);
		else if (rsppkg[1] == 'C') {
			snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "QC%x",
				 gtp_current_pid);
			gtp_rw_size += strlen(gtp_rw_bufp);
			gtp_rw_bufp += strlen(gtp_rw_bufp);
			ret = 1;
		} else if (strncmp("qSupported", rsppkg, 10) == 0) {
#ifdef GTP_RB
			snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX,
				 "QStartNoAckMode+;ConditionalTracepoints+;"
				 "TracepointSource+;DisconnectedTracing+;"
				 "ReverseContinue+;ReverseStep+;"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
				 "EnableDisableTracepoints+;"
#endif
				 "qXfer:traceframe-info:read+;");
#endif
#if defined(GTP_FRAME_SIMPLE) || defined(GTP_FTRACE_RING_BUFFER)
			snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX,
				 "QStartNoAckMode+;ConditionalTracepoints+;"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
				 "EnableDisableTracepoints+;"
#endif
				 "TracepointSource+;DisconnectedTracing+;");
#endif
			gtp_rw_size += strlen(gtp_rw_bufp);
			gtp_rw_bufp += strlen(gtp_rw_bufp);
			ret = 1;
		}
#ifdef GTP_RB
		else if (strncmp("qXfer:traceframe-info:read::",
				   rsppkg, 28) == 0)
			ret = gtp_gdbrsp_qxfer_traceframe_info_read(rsppkg
								    + 28);
#endif
		else if (strncmp("qRcmd,", rsppkg, 6) == 0)
			ret = gtp_gdbrsp_qRcmd(rsppkg + 6);
		else if (strncmp("qAttached", rsppkg, 9) == 0) {
			snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "1");
			gtp_rw_size += 1;
			gtp_rw_bufp += 1;
		}
		break;
	case 'S':
	case 'C':
		ret = -1;
		break;
	case 'b':
		rsppkg[0] = rsppkg[1];
		is_reverse = 1;
	case 's':
	case 'c':
		ret = gtp_gdbrsp_resume (rsppkg[0] == 's', is_reverse);
		break;
	case 'v':
		if (strncmp("vAttach;", rsppkg, 8) == 0) {
#ifdef GTP_RB
			if (gtp_replay_step_id)
				gtp_replay_reset();
#endif
			ret = gtp_gdbrsp_vAttach(rsppkg + 8);
		} else if (strncmp("vKill;", rsppkg, 7) == 0) {
#ifdef GTP_RB
			if (gtp_replay_step_id)
				gtp_replay_reset();
#endif
			/* XXX:  When we add more code to support trace
			   user space program.  We need add more release
			   code to this part.
			   Release tracepoint for this tracepoint.  */
			ret = 0;
		}
		break;
	case 'D':
#ifdef GTP_RB
		if (gtp_replay_step_id)
			gtp_replay_reset();
#endif
		gtp_gdbrsp_D(rsppkg + 1);
		ret = 0;
		break;
	case 'H':
		ret = gtp_gdbrsp_H(rsppkg + 1);
		break;
	case 'Z':
	case 'z':
		if (rsppkg[1] == '0')
			ret = gtp_gdbrsp_breakpoint(rsppkg + 3,
						    (rsppkg[0] == 'Z'));
		break;
	}
switch_done:
	if (ret == 0) {
		snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "OK");
		gtp_rw_bufp += 2;
		gtp_rw_size += 2;
	} else if (ret < 0) {
		snprintf(gtp_rw_bufp, GTP_RW_BUFP_MAX, "E%02x", -ret);
		gtp_rw_bufp += 3;
		gtp_rw_size += 3;
	}

	gtp_rw_bufp[0] = '#';
	csum = 0;
	for (i = 1; i < gtp_rw_size + 1; i++)
		csum += gtp_rw_buf[i];
	gtp_rw_bufp[1] = INT2CHAR(csum >> 4);
	gtp_rw_bufp[2] = INT2CHAR(csum & 0x0f);
	gtp_rw_bufp = gtp_rw_buf;
	gtp_rw_size += 4;

out:
	wake_up_interruptible_nr(>p_rw_wq, 1);
error_out:
	up(>p_rw_lock);
	return size;
}

我们可以看到根据接收到的Packet,分别调用了不同的handler来做处理,这里我们重点关注Tracepoint Packets,关于以QT开头的包,处理代码如下:

static int
gtp_gdbrsp_QT(char *pkg)
{
	int	ret = 1;

#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_gdbrsp_QT: %s\n", pkg);
#endif

	if (strcmp("init", pkg) == 0)
		ret = gtp_gdbrsp_qtinit();
	else if (strcmp("Stop", pkg) == 0)
		ret = gtp_gdbrsp_qtstop();
	else if (strcmp("Start", pkg) == 0)
		ret = gtp_gdbrsp_qtstart();
	else if (strncmp("DP:", pkg, 3) == 0)
		ret = gtp_gdbrsp_qtdp(pkg + 3);
	else if (strncmp("DPsrc:", pkg, 6) == 0)
		ret = gtp_gdbrsp_qtdpsrc(pkg + 6);
	else if (strncmp("Disconnected:", pkg, 13) == 0)
		ret = gtp_gdbrsp_qtdisconnected(pkg + 13);
	else if (strncmp("Buffer:", pkg, 7) == 0)
		ret = gtp_gdbrsp_qtbuffer(pkg + 7);
	else if (strncmp("Frame:", pkg, 6) == 0)
		ret = gtp_gdbrsp_qtframe(pkg + 6);
	else if (strncmp("ro:", pkg, 3) == 0)
		ret = gtp_gdbrsp_qtro(pkg + 3);
	else if (strncmp("DV:", pkg, 3) == 0)
		ret = gtp_gdbrsp_qtdv(pkg + 3);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
	else if (strncmp("Enable:", pkg, 7) == 0)
		ret = gtp_gdbrsp_qtenable_qtdisable(pkg + 7, 1);
	else if (strncmp("Disable:", pkg, 8) == 0)
		ret = gtp_gdbrsp_qtenable_qtdisable(pkg + 8, 0);
#endif

#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_gdbrsp_QT: return %d\n", ret);
#endif

	return ret;
}

而以qT打头的包,处理的接口如下:

static int
gtp_gdbrsp_qT(char *pkg)
{
	int	ret = 1;

#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_gdbrsp_qT: %s\n", pkg);
#endif

	if (strcmp("Status", pkg) == 0)
		ret = gtp_gdbrsp_qtstatus();
	else if (strcmp("fP", pkg) == 0)
		ret = gtp_gdbrsp_qtfp();
	else if (strcmp("sP", pkg) == 0)
		ret = gtp_gdbrsp_qtsp();
	else if (strcmp("fV", pkg) == 0)
		ret = gtp_gdbrsp_qtfsv(1);
	else if (strcmp("sV", pkg) == 0)
		ret = gtp_gdbrsp_qtfsv(0);
	else if (strncmp("V:", pkg, 2) == 0)
		ret = gtp_gdbrsp_qtv(pkg + 2);

	return ret;
<h2>}</h2>

从以上接口可以看到,是一个dispatch的过程,KGTP首先判断接收到的GDB包属于哪一类包,之后分发,而对于一个类型的包,又细分很多子包,最终分发给具体的接口实现,拿上面为例,有如下一个流程:
gtp_write -> gtp_gdbrsp_QT -> gtp_gdbrsp_qtbuffer

通过以上分析,我们已经在Packet层面对GDB和KGTP的通信有了深入的理解。

4. KGTP中set-buffer-size的处理逻辑

有了以上分析,在用户输入了以下指令:

set remote trace buffer-size on
set trace-buffer-size xxx

之后会发生什么呢?

让我们分别测试一下。

(1)set trace-buffer-size 100

Aug 03 11:00:08 localhost.localdomain kernel: gtp_write: QTBuffer:size:64
Aug 03 11:00:08 localhost.localdomain kernel: gtp_gdbrsp_QT: Buffer:size:64
Aug 03 11:00:08 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer
Aug 03 11:00:08 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer:setting buffer size to 100
Aug 03 11:00:08 localhost.localdomain kernel: gtp_gdbrsp_QT: return 0
Aug 03 11:00:08 localhost.localdomain kernel: gtp_read

(2)set trace-buffer-size 1000000

Aug 03 11:00:33 localhost.localdomain kernel: gtp_write: QTBuffer:size:f4240
Aug 03 11:00:33 localhost.localdomain kernel: gtp_gdbrsp_QT: Buffer:size:f4240
Aug 03 11:00:33 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer
Aug 03 11:00:33 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer:setting buffer size to 1000000
Aug 03 11:00:33 localhost.localdomain kernel: gtp_gdbrsp_QT: return 0
Aug 03 11:00:33 localhost.localdomain kernel: gtp_read

(3)set trace-buffer-size -1
Aug 03 11:00:18 localhost.localdomain kernel: gtp_write: QTBuffer:size:-1
Aug 03 11:00:18 localhost.localdomain kernel: gtp_gdbrsp_QT: Buffer:size:-1
Aug 03 11:00:18 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer
Aug 03 11:00:18 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer:setting buffer size to 0
Aug 03 11:00:18 localhost.localdomain kernel: gtp_gdbrsp_QT: return 0
Aug 03 11:00:18 localhost.localdomain kernel: gtp_read

(4)set trace-buffer-size unlimited
Aug 03 11:00:44 localhost.localdomain kernel: gtp_write: QTBuffer:size:-1
Aug 03 11:00:44 localhost.localdomain kernel: gtp_gdbrsp_QT: Buffer:size:-1
Aug 03 11:00:44 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer
Aug 03 11:00:44 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer:setting buffer size to 0
Aug 03 11:00:44 localhost.localdomain kernel: gtp_gdbrsp_QT: return 0
Aug 03 11:00:44 localhost.localdomain kernel: gtp_read

可以看到,This packet directs the target to make the trace buffer be of size size if possible. A value of -1 tells the target to use whatever size it prefers.

也就是说,-1和unlimited等价,GDB告诉target可以使用自己认为合适的size,而给一个合理范围的正整数n,则会要求target使用的buffer size为n,单位是byte。

因此,当我们接到GDB发来的size为-1的包时,可以直接忽略掉,而收到normal size的包时,需要跟当前使用的buffer size作对比,然后做相应处理。

5. KGTP中set-buffer-size的具体实现

目前KGTP的set-buffer-size分支,已经实现了对size处理的逻辑,参考[6],具体代码如下:

static int
gtp_gdbrsp_qtbuffer(char *pkg)
{
#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_gdbrsp_qtbuffer\n");
#endif

    // Handle QTBuffer:circular:value
	if (strncmp("circular:", pkg, 9) == 0) {
		ULONGEST setting;

		pkg += 9;
		if (pkg[0] == '\0')
			return -EINVAL;
		hex2ulongest(pkg, &setting);

#ifdef GTP_FTRACE_RING_BUFFER
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)) \
    || defined(GTP_SELF_RING_BUFFER)
		gtp_circular = (int)setting;
		if (gtp_frame)
			ring_buffer_change_overwrite(gtp_frame, (int)setting);
#else
		if (gtp_circular != (int)setting)
			gtp_circular_is_changed = 1;
#endif
#endif
		gtp_circular = (int)setting;

		return 0;
	}
    // Handle QTBuffer:size:size 
    else if (strncmp("size:", pkg, 5) == 0) {

		ULONGEST size;
        int unlimited_or_not;

        pkg += 5;

		if (pkg[0] == '\0')
			return -EINVAL;

        // The size may equal to -1, so compare the pkg with "-1"
        if((strncmp("-1", pkg, 2) == 0) && (*(pkg + 2) == '\0')) {
            unlimited_or_not = 1;
        }

        if(unlimited_or_not == 1) {
            // The user wants KGTP to choose the right size
            // So we just ignore the request

#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_gdbrsp_qtbuffer:keep buffer size as the user tells KGTP to use unlimited size");
#endif

            return 0;
        }

        // User wants to change the buffer size
        hex2ulongest(pkg, &size);

#ifdef GTP_DEBUG
	printk(GTP_DEBUG "gtp_gdbrsp_qtbuffer:setting buffer size to %ld\n", size);
#endif

        // Handle the new ringbuffer size blow
        // gtp_set_trace_buffer_size(size);

        return 0;
    }

	return 1;
}

让我们测试一下:

(1)set trace-buffer-size -1
Aug 03 12:37:28 localhost.localdomain kernel: gtp_write: QTBuffer:size:-1
Aug 03 12:37:28 localhost.localdomain kernel: gtp_gdbrsp_QT: Buffer:size:-1
Aug 03 12:37:28 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer
Aug 03 12:37:28 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer:keep buffer size as the user tells KGTP to use unlimited size
Aug 03 12:37:28 localhost.localdomain kernel: gtp_gdbrsp_QT: return 0
Aug 03 12:37:28 localhost.localdomain kernel: gtp_read

(2)set trace-buffer-size unlimited
Aug 03 12:37:57 localhost.localdomain kernel: gtp_write: QTBuffer:size:-1
Aug 03 12:37:57 localhost.localdomain kernel: gtp_gdbrsp_QT: Buffer:size:-1
Aug 03 12:37:57 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer
Aug 03 12:37:57 localhost.localdomain kernel: gtp_gdbrsp_qtbuffer:keep buffer size as the user tells KGTP to use unlimited size
Aug 03 12:37:57 localhost.localdomain kernel: gtp_gdbrsp_QT: return 0
Aug 03 12:37:57 localhost.localdomain kernel: gtp_read

Bingo!目前已经正确地实现了对size的解析处理,接下来的工作是继续调研KGTP trace buffer的实现,并根据size大小做出调整。

6. 参考链接

[1] http://blog.youkuaiyun.com/calmdownba/article/details/38174759
[2] https://sourceware.org/gdb/current/onlinedocs/gdb/Packets.html#Packets
[3] https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Protocol.html#Remote-Protocol
[4] https://sourceware.org/gdb/current/onlinedocs/gdb/Tracepoint-Packets.html
[5] https://sourceware.org/gdb/current/onlinedocs/gdb/Starting-and-Stopping-Trace-Experiments.html
[6] https://code.youkuaiyun.com/Calmdownba/kgtp/tree/set-buffer-size




Picture of ssh key 立即下载

相关推荐

政府科技管理者在推动区域科技成果转化过程中,如何系统性地识别和分析创新资源的配置瓶颈?.docx

政府科技管理者在推动区域科技成果转化过程中,如何系统性地识别和分析创新资源的配置瓶颈?

gdb 远程调试协议_从头开始实现gdb远程调试协议存根5

gdb 远程调试协议系列:(Series:) Implement GDB Remote Debug Protocol stub from scratch (1) 从零开始实现GDB远程调试协议存根(1)Implement GDB Remote Debug Protocol stub from scratch (2) 从零开始实现GDB远程调试协议存根(2)Implement GDB Remote ...

weixin_26644585的博客 846

政府科技管理者如何提升区域科技成果转化项目的评价与筛选效率?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Android性能优化 -- Systrace工具

Systrace简介     一般来说,我们的机器以60帧/秒显示时,用户会感觉机器很流畅,如果显示时出现丢帧的情况,需要知道当前整个系统所处的状态,这个时候Systrace便是最佳的工具选择。     Systrace是Android4.1中新增的性能数据采样和分析工具。它可帮助开发者收集Android关键子系统(如Surfaceflinger、WindowManagerService等fr

Kitty_Landon的专栏 1万+

高校技术转移办公室人员在成果转化过程中如何快速提升技术推介效率?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

两相交错并联Boost电路仿真模型(Simulink仿真实现)

内容概要:本文档系统性地介绍了基于Simulink平台的两相交错并联Boost电路仿真模型,属于电力电子变换器建模与仿真研究的重要组成部分。该模型采用交错并联结构,有效提升了系统效率、降低了输出电流纹波,并具备优良的动态响应与系统稳定性。文档不仅聚焦于该特定拓扑的开环与闭环控制实现,还整合了丰富的配套资源,涵盖多种主流DC-DC变换器(如Buck、Boost、LLC、CLLC)、功率因数校正(PFC)电路、PWM整流器、双向充放电系统以及新能源应用场景(如V2G、微电网)等领域的仿真模型。资源体系强调软开关技术、多相交错控制、系统级建模与参数优化设计,所有内容均提供可运行的Simulink仿真文件,部分包含详细的设计报告、计算书及参考文献,具有较强的工程实践与科研复现价值。; 适合人群:电气工程、自动化、电力电子与电力传动等相关专业的硕士博士研究生、高校科研人员,以及从事新能源发电、电动汽车、电源系统设计等领域的工程技术人员。; 使用场景及目标:①支撑高校电力电子与电力系统方向的科研项目,用于新型拓扑结构的建模与先进控制算法的验证;②服务于本科生与研究生的毕业设计、课程设计及高水平学术论文的仿真复现;③为企业在电源产品研发、新能源系统集成等环节提供成熟的仿真方案参考,缩短研发周期,降低试错成本。; 阅读建议:建议使用者首先访问文档末尾提供的完整资源目录链接,按需下载对应仿真模型;在实践过程中,应重点关注模型的参数配置、控制策略实现细节与仿真工况设置,结合配套的说明文档深入理解其工作原理与设计思路,推荐在MATLAB/Simulink环境中动手调试与二次开发,以充分掌握电力电子系统的核心技术。

修改trace buffer size

Changing the trace buffer size can only be done in the parameter file: _trace_pool_size=100M[@more@] ...

510

基于单片机的电动工程机械高压管理单元控制器设计.docx

基于单片机的电动工程机械高压管理单元控制器设计.docx

给GDB增加调试信息,即添加GCC调试参数

GCC调试参数 gcc参数有:-g,-g3,-ggdb,-ggdb3 编译加上-g的时候,程序会是处理debug的状态,运行时候会记录更多的debug信息,从而占用内存更大的空间。 g,产生的debug信息是OS产生的,GDB可以合理封装使用。 g3,只是一个调试级别,级别越高产生的额外debug信息会越多,但是内存占用率会越大,3这个级别可以调试宏。 ggdb产生的debug信息更倾向于给GDB使用的。 ...

陈先森's blog 2160

IEC 101 仿真调试台是基于 Windows 桌面工具,用于 IEC 60870-5-101(简称 IEC 101 / 101 规约)串口远动通信的仿真、调试与报文分析

IEC 101 仿真调试台是基于 Windows 桌面工具,用于 IEC 60870-5-101(简称 IEC 101 / 101 规约)串口远动通信的仿真、调试与报文分析。同一个程序内既可充当主站(控制站),也可充当从站(被控站 / RTU),并内置 FT1.2 链路层原始帧的逐字段解析。 本软件是规约仿真与调试工具,不替代 SCADA/EMS 主站系统,也不作为生产环境长期运行的前置机。现场接入真实装置前,请确认串口电气接口(RS-232/RS-485)、电平转换与接线方式正确。

学习STM32的无人机控制

设计并实现无人机控制系统,使用STM32单片机进行控制。无人机控制系统主要包括飞行控制、姿态控制、定位导航等功能。以下是一个基于STM32的无人机控制系统的代码案例。以上是一个基于STM32的无人机控制系统的代码案例,包括飞行控制、姿态控制和定位导航等功能。请根据实际情况进行修改和完善。

qq_67153941的博客 837

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 1

这一周主要对KGTP的实现进行了简单的熟悉和分析,主要can'k

Calmdownba的专栏 1103

Codex VS Claude Code 全面测评!代码开发到底选谁?

评测结果6项指标(设计质量、提示遵从度、响应式、代码质量、细节关注、惊喜度)虽未公布最终赢家,但实测本身已揭示两工具在前端任务上的直接差异。Codex基于OpenAI的云沙箱架构,API通过全球CDN分发,但在国内直连时,依赖特定网络环境。:纯终端工具,直接在你的iTerm或终端中运行,不新建窗口、不切换上下文,与本地开发环境无缝融合。GPT-5.3 Codex(xhigh)输入$1.75/百万token,输出$14.00/百万token,混合均价约**$4.81/百万token**。

Jedudu的博客 3077

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 5

优快云开源夏令营 - 第周工作总结

Calmdownba的专栏 1678

蜗牛星际+OpenWrt实战:双网口变AP模式,让所有设备同网段互通

本文详细介绍了如何将蜗牛星际双网口小主机刷入OpenWrt系统,并将其配置为AP模式,实现与主路由同网段的无缝桥接。通过关闭DHCP、桥接物理网口等核心步骤,解决家庭网络设备割裂问题,让所有设备在同一局域网内高效互通,特别适合追求网络简洁和厌恶多级NAT的技术爱好者。

zero1的博客 960

利用HTML+CSS设计PPT:html-to-pptx实现自动化转换与可编辑输出

在办公自动化和前端开发领域,将网页技术应用于文档生成是一个重要的技术方向。其核心原理在于通过解析HTML/CSS的结构与样式,将其映射为目标文档的原生对象模型。这项技术的价值在于,它能够将Web技术栈强大的布局与样式能力(如Flexbox、CSS Grid)与办公软件(如Microsoft PowerPoint)的广泛兼容性和可编辑性相结合。在实际应用场景中,这种技术特别适合需要快速生成兼具设计感与实用性的演示文稿,例如数据报告、产品发布和营销材料。本文探讨的html-to-pptx项目正是这一思路的工程实

weixin_30652491的博客 486

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 7

优快云开源夏令营 - 第六周工作总结

Calmdownba的专栏 1134

DBeaver连接IoTDB避坑指南:手动配置JDBC驱动的完整流程(附问题排查)

本文提供了在DBeaver中手动配置Apache IoTDB JDBC驱动的完整流程与避坑指南。详细解析了从驱动创建、库文件添加(关键是指向整个lib目录)到连接测试的每一步,并重点针对常见的ClassNotFoundException、连接拒绝等错误提供了深度排查方案,帮助用户高效建立图形化管理连接。

weixin_28327051的博客 396

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 3

优快云开源夏令营 - 第三周工作总结 这一周zhu'yao

Calmdownba的专栏 1485

MCAL知识点(十):ERU驱动配置详解

ERS:外部请求单元ETL:中断逻辑单元OGU:输出逻辑单元MCU里面配置要使用的功能和选择输入的管脚,注意上述模块关注点讲述的ERU必须和边沿检测模块相关联。

梦想技术家 1223

学Simulink——基于Simulink的AUTOSAR架构下电机控制软件组件建模

本文详细介绍了在Simulink中基于AUTOSAR架构开发电机控制软件组件(SWC)的全流程。主要内容包括:首先阐述了AUTOSAR架构对汽车电子系统开发的价值,包括提高软件复用率、降低集成成本和改善验证环境。然后重点讲解了在Simulink中构建电机控制SWC的具体步骤:从创建AUTOSAR组件模型、定义数据端口和服务端口,到搭建FOC控制算法、配置运行实体,最后生成AUTOSAR描述文件和验证RTE接口。文章还提供了与基础软件(BSW)的集成方案、工程实践要点和常见问题解决方案,并以大众MEB平台等实

amy_mhd的博客 67

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 8

优快云开源夏令营 -

Calmdownba的专栏 1404

[EdgeAI] NXP eIQ 机器学习Toolkit (一):准备篇

eIQ™机器学习(ML)软件开发环境支持在恩智浦EdgeVerse™微控制器和微处理器(包括i.MX RT跨界MCU和i.MX系列应用处理器)上使用ML算法。eIQ ML软件包括称为eIQ Toolkit的ML工作流工具以及推理引擎、神经网络编译器和优化库。............

HowieXue 薛永浩的博客 1万+

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 2

优快云开源夏令营 - 第一周工作总结

Calmdownba的专栏 1086

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 6

优快云开源夏令营 - 第六周工作总结

Calmdownba的专栏 1095

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

上一篇: KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 3
下一篇: KGTP中增加对GDB命令“set trace-buffer-size”的支持 - Week 5
hustcalm
博客等级 码龄17年 9粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值