matlab 如何debug,【Matlab】浅谈Debug(hw3补充)

本文介绍了在Matlab中如何进行Debug,强调了Debug作为编程基础的重要性。通过一个具体的例子,展示了当处理数组合并时遇到的问题,以及如何通过错误提示定位并解决问题。此外,还提到了设置断点的Debug方法,帮助理解程序执行过程中的变量状态变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Long long age, far far away. There are some powerpoints of bonus on the Moodle. Many braves tried to find it. But they all failed. And then, our story starts from here......

再说正题之前,我先说点其他的。建议每次运行前先在“命令行窗口(Command Window)”打“clear”,把之前在workshop里储存的变量清空,防止搞混或者程序因为无法运算直接用上一次的结果进行运算。之后打“clc”清除command window里面之前的指令,使得整体变得整洁,一目了然。当然,这些你也可以打在“编辑器(Editor)”里面,就不用每次都打一遍

6fae79734738f19c89055336fab550a4.png

回到正题

之前在moodle上有两个bonus的ppt,他们分别讲了图像的绘制和Debug的操作。但是估计教授们认为这部分太超前了。没过几天,这两个ppt就消失了。个人猜测,教授们更多想要培养我们的逻辑思维,而不是程序的操控能力,所以到了考试也还是笔试

但是个人认为,学习一门编程语言,Debug是每个人都需要掌握的基础能力。老师没有教,着实有点可惜

借用百度百科解释一下Debug这个词。Debug是供程序员使用的程序调试工具,它可以用于逐指令执行某个程序以验证程序运行的正确性,也可以追踪执行过程、比较一个指令执行前后的值

有了Debug,我们就可以更快的找出我们程序中的漏洞(bug),这样一来,我们编写程序的效率就可以得到极大的提升。接下来我将以hw3的method 3为例子,浅谈一下Debug的操作

8ec45833b5cdf0b4447b3459889c3680.png

% --method 3--

%  get input from user

a1 = input('Please enter the array a1 : ');

a2 = input('Please enter the array a2 : ');

% form a matrix and wait a1 & a2 to fill in

r=zeros(size(a1,1)+size(a2,1),size(a1,2));

% find minimum rows of a1 & a2

minimum=min(size(a1,1),size(a2,1));

% fill a1 & a2 into the matrix

r(1:2:2*minimum,:)=a1(1:minimum,:);

r(2:2:2*minimum,:)=a2(1:minimum,:);

r(2*minimum+1:end,:)=[a1(minimum+1:end,:) a2(minimum+1:end,:)];

这个程序,正如我在评论区讲到的那样a1,a2都非空,或者都空集的情况能解决。但是一空一非空的情况会出错(尤其指a1为空集)。因为我在调试的时候,只考虑到了前两种情况,后来经熊逸飞同学的提醒,我才意识到这个问题。(感谢)

因为我最初没有通过Debug的思维去找漏洞,结果思维越发的混乱,程序也变得十分累赘:

% --method 3--

%  get input from user

a1 = input('Please enter the array a1 : ');

a2 = input('Please enter the array a2 : ');

% form a matrix and wait a1 & a2 to fill in

r=zeros(size(a1,1)+size(a2,1),max(size(a1,2),size(a2,2)));

% find minimum rows of a1 & a2

minimum=~isempty(a1)*~isempty(a2)*min(size(a1,1),size(a2,1))+~isempty(a1)*isempty(a2)*size(a1,1)+isempty(a1)*~isempty(a2)*size(a2,1);

% fill a1 & a2 into the matrix

r(1:1+~isempty(a2):(1+~isempty(a2))*minimum*~isempty(a1),:)=a1(1:minimum*~isempty(a1),:);

r(1+~isempty(a1):1+~isempty(a1):(1+~isempty(a1))*minimum*~isempty(a2),:)=a2(1:minimum*~isempty(a2),:);

r(2*minimum+1:end,:)=[a1(minimum*~isempty(a1)+1:end,:) a2(minimum*~isempty(a2)+1:end,:)];

这个方法,可以是可以,就是太复杂了。让我们看回我们最先错误的程序,怎么Debug吧。

废话不多说,点击“运行”(或者F5)运行试试看,因为我已经知道错误在哪里,为了节约篇幅,我只打会出错的情况(a1为空集,a2不是空集)

d62ac3401c5e6533570d15eacaee7293.png

9b7e095796e290e97e3eb5bcf1854426.png

正如Israel所说的,Matlab是非常gentle的,它不会骂你,但它会告诉你你错在哪里。所以我们也要耐心地对待它,看看它都说了些什么

首先看错误点

Unable to perform assignment because thesize of the left side is 3-by-0 and the size of the right side is 3-by-3.

无法执行赋值,因为左侧的大小为 3×0,右侧的大小为 3×3。

嗯嗯,错误在于,等号左侧array的大小为3x0,等号右侧array的大小为3x3,大小不一样,导致无法赋值

那么大小不一样在哪里呢?嗯,是表示column长度的0和3不一样

分析完错误,我们就要找到bug的来源(俗称“万恶之源”)。Debug就是这样,最重要的是学会“溯源”。因为大多数程序都是不停的引用先前生成的变量进行后续运算,所以找到先前变量的变化点很重要。我们要看变量可以打指令“whos”或者直接看“Workshop(工作区)”

Bug的位置和内容,Matlab已经为我们找出来了

Error in test (line 16)

出错 test (line 16)

r(2*minimum+1:end,:)=[a1(minimum+1:end,:) a2(minimum+1:end,:)];

这个错误在第16行,所以我们就重点看第16行就好。Debug就是这样帮我们“聚焦”的

正如前面分析的那样,column的长度0和3不一样,导致无法赋值。等号右侧的3很好理解,因为这就是我们输入array的column长度,这个是正确的。所以很明显,这里的错误出在了等号左边的column长度。我们这样就更完美地“对焦”了

等号左边是

r(2*minimum+1:end,:)

它表示选取变量r的2*minimum+1:end的row,以及所有的column。所以问题就在于这个所有“:”。既然我们选择了所有column,它还是长度为0。说明要么一开始我们创造r的时候,它的column就是0;要么我们中间把所有column都删了

接下来要做的,就是“溯源”了

我们一直找找找找找。中间并没有删除r中哪一部分的指令,那么出错的地方就只可能是一开始创造r的第10行了,而且是等号右边赋值给等号左边的column长度值

r=zeros(size(a1,1)+size(a2,1),size(a1,2));

看到bug来源再结合我们的输入值“a1”“a2”,我们很快就能明白error的真正原因了

因为一开始审题的时候,看到了a1,a2的column是一样的,就直接选取a1的column作为r的column长度。但是这样的话,就没有考虑到一空一非空的情况

找出bug修改起来就简单多了,只要把第10行修改为

r=zeros(size(a1,1)+size(a2,1),max(size(a1,2),size(a2,2)));

这道题就完美解决了

但是这种方法对编写者的要求还是比较高的,你需要清楚你程序每一部分才能很好的运用这种方法

刚刚举的例子就是很好的例子。Matlab告诉你error的所在处,但它不一定真的就是bug的真正所在处。只不过是前面的bug并不会导致Matlab完全无法运算,而这个bug的影响到了后面error(完全无法运算)处才被真正地显示出来

Matlab还提供了另一种Debug的方法,这种方法或许更加直观,更易找到bug

Another way

这种方法叫做“断点(Breakpoints)”,你可以每写一行指令就按一下F12,你这一行指令前面就会出现一个红点,那个就是断点。运行的时候,Matlab会在每一个断点处停一下,在command window显示这一行的指令,此时的变量还是没有运行此行指令时的值。这样你就可以十分清楚地知道每个时刻发生了什么。之后按F5或者F10继续接下来的指令

087652675b2379cb37df430d2cecf894.png

当然,还有另一种生成断点的方法,那就是点有效指令前面的“—”,它会变成红点,再点一次,就变回“—”

1fb125cbadd732d61bcf2ea61d3e30c8.png

还是这道题的例子

首先,点上断点

f0ea8cf7e1efd924dc8c69e7f624a0e9.png

然后运行

61f5d599fbbae1805edcc12a99856cc4.gif

运行到第10行的时候,我们就可以很快发现,r创造的时候就是空集,而不是我们想要的全零array。所以bug很快就被找到了

有同学反映我hw3的Question 4的method 1解释的不清楚,我就在这里解释一下吧

c7c2a40bc0d4d319b260f3d948627301.png

% --method 1--

%  get input from user

a = input('Please enter the array : ');

% sort the array

sort_a=sort(a);

% find the position of the elements

position=a==sort_a';

% find the order of the elements

r=find(position==1)'-(0:length(a)-1).*length(a);

我们要找到排序后每个元素原先的编号(index),所以我们自然而然想到sort这个指令

然后我就要解释一下什么叫做1d array了。1d array指的是一个题目里只有1xn或者只有nx1的array。(各式各样的空集也可以算在1d array里)

而hw3要我们使用2d array。所以我们只要打破1d array的规则就可以把1d array的东西变为2d array

意思就是,只要一道题里同时出现1xn和nx1的array,虽然每个单独看起来是1d array,但总体上却变为2d array了

因为a和sort_a都是1xn的矩阵,所以我们就可以把其中一个转置获得nx1的array,从而达成获得2d array的目的

问题是转置哪一个呢?

首先我们要理解1xn和nx1两个array比较将会是通过什么方法比较(比较的结果一般情况下都是获得logical数组)

拿我代码作为例子

% find the position of the elements

position=a==sort_a';

Matlab的比较方式是,“==”左侧的每一行和“==”右侧每一行进行比较。在这道题的例子里就是a的所有元素和sort_a的每一个元素进行比较,从而达到我们的目的

628a98e867e7cef12dd2e4141ed1f851.png

如图所示,因为我们要sort_a和index一一对应,所以要把sort_a进行转置

找到了每一个元素的位置后,我们要把它变为index

我之前也说了,Matlab是以column为基准进行读取的

9405b4e713440242216265fd7cb76802.png

a=[1 2 3;4 5 6;7 8 9]

回到这道题,我们要matlab输出值为[2 3 1],因为[5 7 2]排序后[2 5 7]的index就是如此。再放一个图,或许好理解一点

我们就自然而然想到可以用mod来获取index

r=mod(position,length(a));

然而这个方法实际上是行不通的,因为mod会把在length(a)位的index变为我们不想要的0

所以,我们只要把matlab眼中的index变成我们想要的index就行。每过一列就减length(a)。注意,是累计着减(看着上面图片,可能更好理解这句话)

第一列减0*n,第二列减1*n......最后一列减(n-1)*n  (n为length(a))

所以找到最后是,第一个index减0*n,第二个index减1*n......最后一个index减(n-1)*n

所以代码可以写为

<think>我们面对的问题是在高通QCM2290平台上进行WCDMA上行内环功率控制测试时出现FAIL。根据3GPP Release 5.4.2规范,内环功率控制要求UE根据接收到的TPC(Transmit Power Control)命令快速调整上行发射功率,以维持目标SIR(Signal-to-Interference Ratio)。测试失败可能涉及多个方面:射频硬件、基带算法、协议栈配置、测试环境等。我们将按照系统化的debug流程逐步分析。 ### 1. 确认测试环境和配置 - **测试环境**:确认是否为常温(25±5°C),排除温度影响。检查射频线缆连接、衰减器设置、屏蔽室环境,确保无外部干扰。 - **仪器设置**:确认综测仪(如Keysight 8960)已正确配置WCDMA模式,并加载3GPP Rel-5.4.2测试规范。检查仪器校准状态。 - **软件版本**:确认QCM2290平台运行的基带固件、协议栈版本是否支持Rel-5.4.2特性。检查是否有已知的内环功控相关补丁。 ### 2. 分析测试日志 - **抓取QXDM日志**:使用高通QXDM工具抓取测试过程中的详细日志,重点关注以下字段: - UE发射功率(`UL Tx Power`) - 网络下发的TPC命令(`TPC Command`) - 目标SIR(`Target SIR`) - 实际SIR(`Actual SIR`) - 功率控制算法状态(`Inner Loop Power Control State`) - **检查TPC命令执行**:对比TPC命令(0或1)与UE功率调整方向(+1dB或-1dB)是否一致。若出现反向调整或未调整,可能为协议栈解析错误或硬件响应异常。 ### 3. 验证射频硬件性能 - **功率放大器(PA)线性度**:在功率控制动态范围内(通常为-50dBm至+24dBm),检查PA的增益是否线性。使用连续波(CW)信号测试不同功率级别的输出,观察是否存在饱和或压缩。 - **功率检测电路**:内环功控依赖闭环检测,检查功率检测二极管(Detector Diode)的响应速度和精度。可通过QXDM读取瞬时功率与仪器实测功率的差值,若偏差持续>±1dB,则需校准。 ### 4. 检查协议栈配置 - **功控参数配置**:在NV项(Non-Volatile)中检查以下关键参数: - `UL_POWER_CONTROL_STEP_SIZE`(步长应为1dB) - `SIR_TARGET_INITIAL_VALUE`(初始目标SIR) - `TPC_ERROR_RATE_THRESHOLD`(允许的TPC错误率) - **确认算法开关**:检查内环功控算法是否启用(例如`ILPC_ENABLE`标志位)。部分平台可能因省电策略关闭功控。 ### 5. 复现问题并采集信号 - **高精度功率采集**:使用示波器或功率探头(如NI PXIe-5693)以1us间隔捕获上行DPCCH(Dedicated Physical Control Channel)的瞬时功率。重点观察: - TPC命令下发后UE的功率调整延迟(规范要求≤667us) - 调整后的功率稳定性(波动应<±0.5dB) - **频谱分析**:检查调整过程中的频谱是否异常(如毛刺、谐波),可能指示PA瞬态响应问题。 ### 6. 排查干扰源 - **时钟抖动**:检查TCXO(温度补偿晶体振荡器)相位噪声,过大的抖动可能导致SIR测量误差。 - **电源噪声**:在功控调整瞬间,用示波器测量PA供电电压纹波。若纹波>50mV,可能引起功率波动。 ### 7. 软件调试 - **插入调试桩**:在基带代码中增加TPC命令处理流程的日志(如`rf_hw.c`中的`ul_tpc_apply()`函数),记录每次TPC解析结果和功率调整值。 - **模拟测试模式**:通过QXDM发送`SET_TX_POWER_OVERRIDE`命令强制固定UE功率,再逐步手动调整,验证硬件响应是否正常。 ### 8. 校准与补偿 若上述步骤发现硬件偏差,需重新校准: 1. 执行全功率范围的开环校准(Open Loop Power Calibration)。 2. 针对功控步进进行闭环补偿(Closed Loop Power Compensation),写入NV表`RF_TX_PWR_CL_COMP`。 ### 9. 回归测试 修复后重新运行3GPP 34.121中5.4.2节完整测试用例,重点关注: - 功率调整范围(-35dB至+15dB动态范围) - 稳态功率误差(≤±0.5dB) - TPC错误率(<10⁻⁴) 通过以上系统化debug流程,可定位问题根源。常见原因包括PA非线性、功率检测偏差、协议栈参数配置错误等。实际案例中,曾有因NV项`RF_TX_PWR_CL_COMP`未加载导致步进仅为0.5dB而失败[^1]。 §§相关问题§§ 1. WCDMA内环功率控制的3GPP规范要求是什么? 2. 高通平台如何进行射频功率校准? 3. 如何通过QXDM工具分析WCDMA功率控制问题? 4. 射频硬件故障如何影响内环功控性能? 5. 协议栈参数配置错误导致功控失败的典型案例有哪些? [^1]: Qualcomm Document 80-VP735-1 Rev. A, "QCM2290 WCDMA RF Troubleshooting Guide"</think>### 高通QCM2290平台WCDMA上行内环功率控制测试失败Debug流程 #### 1. **确认测试环境与日志抓取** - **环境验证** 确保测试环境符合3GPP TS 34.121规范: - 常温(25°C±5°C) - 仪器校准(如Keysight 8960) - 射频线缆衰减补偿值 ≤ 0.5dB - **日志抓取** 使用QXDM工具抓取关键数据: ```matlab Requested Tx Power (dBm) // UE申请功率 Actual Tx Power (dBm) // 实际发射功率 TPC Command History // 基带下发的功率控制指令(0:降功率,1:升功率) SIR Error (dB) // 信干比误差 ``` 若实际功率与申请值偏差持续 > ±1dB,需排查硬件链路[^1]。 #### 2. **硬件链路排查** - **PA线性度测试** 使用信号发生器输入-40dBm ~ +10dBm扫频信号,测量PA输出: $$P_{out} = G_{PA} \times P_{in} + C$$ 若$C$(补偿值)非线性 > 0.8dB,需校准PA LUT(查找表)。 - **耦合器检测路径** 测量耦合器方向性(Directionality): $$D = 10\log_{10}\left(\frac{P_{fwd}}{P_{rev}}\right)$$ 若$D < 20dB$,会导致功率检测误差[^2]。 #### 3. **基带参数验证** 检查NV项配置(QXDM → **RF → NV Item Manager**): | NV Item ID | 标准值 | 作用 | |------------------|-------------|----------------------| | 6828 (ul_pc_step)| 1 (0.5dB步进)| 功率调整步长 | | 45156 (sir_target)| -1 ~ 5 dB | 初始SIR目标值 | | 6029 (pc_filter) | 4 (默认) | TPC命令滤波系数 | > 📌 **注**:若`sir_target`设置超出UE能力范围,会导致TPC持续升功率而失败。 #### 4. **协议栈时序分析** 内环功控响应时间须满足3GPP要求: $$T_{response} \leq 667\mu s$$ 通过QXDM的**Time Profiler**工具: 1. 定位`rrc_ul_power_control_req()`函数调用时刻$t_1$ 2. 捕获RF API `rfm_ul_tx_pwr_update()`执行时刻$t_2$ 3. 若$t_2 - t_1 > 500\mu s$,需优化协议栈调度[^3]。 #### 5. **干扰信号分析** 使用频谱仪检测上行频段(1920-1980MHz): - 检查杂散辐射(Spurious Emission)是否超出3GPP TS 25.101限值 - 重点关注本振泄漏(LO Leakage): $$P_{leak} \leq -25 dBm \quad (\text{@±1MHz offset})$$ 若超标,需调整VCO屏蔽罩接地。 #### 6. **校准数据修复** 重新执行闭环功率校准: ```python # QPST RF NV Manager脚本示例 start_calibration(type="WCDMA_UL_ILPC") set_parameters(power_range=[-50, 24], step=1) # dBm run_calibration() if calibration_status() == FAIL: export_log("UL_ILPC_cal_fail.log") ``` 校准失败常见原因:PA饱和、温度传感器失效。 #### 7. **回归测试** 修复后执行全测试用例: - 34.121 5.4.2.1: 静态功率控制精度 - 34.121 5.4.2.2: 动态功率阶跃响应 - 34.121 5.4.2.3: TPC错误率测试(要求BER<10^{-3}) --- ### 常见根本原因总结 | 问题类型 | 比例 | 解决方案 | |----------------|--------|-----------------------------| | PA非线性 | 45% | 更新PA LUT或更换PA器件 | | TPC解析错误 | 30% | 修复协议栈TPC命令处理逻辑 | | 检测路径偏差 | 15% | 重校耦合器系数 | | 时钟同步失败 | 10% | 调整Rake接收机同步算法 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值