How to avoid common errors and make program efficient.

本文档提供了避免Symbian C++编程中常见错误的建议,并介绍了如何通过两阶段构造等技巧提高程序效率,确保资源正确释放。
How to avoid common errors and make program efficient.

From Forum Nokia Wiki

Jump to: navigation , search

Following are the general tips for avoiding unnecssary and common errors,

and make your program efficient.


Contents

[hide]

[edit] KERN-EXEC 3

Kern-Exec 3 crashes are often caused due to stack corruption or stack Overflow, prefer the use of heap to the stack. Be aware that recursive functions can eat the stack at runtime — this will lead to a Kern-Exec 3 panic.


[edit] Some common errors for application panic

• Failure to have properly added a non-member, heap-allocated variable to the Cleanup Stack. • The ‘double delete’ – e.g. failure to correctly Pop() an already destroyed item from the Cleanup Stack, causing the stack to try to delete it again at a later time. • Accessing functions in variables which may not exist in your destructor;

e.g.

CSomeClass::~CSomeClass()

{

          iServer->Close();

          delete iServer;
 
}

The above statement should always be coded as

CSomeClass::~CSomeClass ()

{

	if (iSomeServer)

	{

	   iServer ->Close();

	   delete iServer;
	
	}
	
}

• Putting member variables on the Cleanup Stack – never do this, just delete them in your destructor as normal.


[edit] Use CleanupClosePushL()

Always use CleanupClosePushL() with R classes which have a Close() method. This will ensure they are properly cleaned up if a leave occurs.

For example:

RFile file;

User::LeaveIfError(file.Open(.....));

CleanupClosePushL(file);

// some code

CleanupStack::PopAndDestroy();


[edit] HBufC

Always set member HBufC variables to NULL after deleting them. Since HBufC allocation (or reallocation) can potentially leave, you could find yourself in a situation where your destructor attempts to delete an HBufC which no longer exists.


You don’t need to use HBufC::Des() to get into an HBufC. All you have to do is dereference the HBufC with the * operator – this is particularly relevant, for example, when passing an HBufC as an argument to a method which takes a TDesC& parameter.


[edit] _L() Macro

Dont use the _L() macro in your code. you should prefer _LIT() instead. The problem with _L() is that it calls the TPtrC(const TText*) constructor, which has to call a strlen() function to work out the length of the string. While this doesn’t cost extra RAM, it does cost CPU cycles at runtime. By contrast, the _LIT() macro directly constructs a structure which is fully initialized at compile time, so it saves the CPU overhead of constructing the TPtrC.

Alternatively, you can use following macros instead of _L():

#define __L(a) (TPtrC((const TText *)L ## a,sizeof(L##a)/2-1))

#define __L8(a) (TPtrC8((const TText8 *)(a),sizeof(a)-1))

#define __L16(a) (TPtrC16((const TText16 *)L ## a,sizeof(L##a)/2-1))

It gets rid of strlen, but still TPtrC constructors are not inline functions.

[edit] TRAP

If you have cause to use a TRAP of your own, do not ignore all errors. A common coding mistake is:

TPAPD(err, SomeFunctionL());

if (err == KErrNone || err == KErrNotFound)

{

// Do something else

}

This means all other error codes are ignored. If you must have a pattern like the above, leave for other errors:

TPAPD(err, SomeFunctionL());

if (err == KErrNone || err == KErrNotFound)

{

// Do something else

}

else

User::Leave(err);


[edit] Cleanup Stack

Do not wait to PushL() things on to the Cleanup Stack. Any newly allocated object (except member variables) should be added to the stack immediately. For example, the following is wrong:

void doExampleL()

{

  	CSomeObject* Object1=new (ELeave) CSomeObject;

	CSomeObject* Object[[Category:Symbian C++]]2=new (ELeave) CSomeObject;

}

because the allocation of Object2 could fail, leaving Object1 ‘dangling’ with no method of cleanup. The above should be:

void doExampleL()

{

	CSomeObject* Object1=new (ELeave) CSomeObject;

	CleanupStack::PushL(Object1);

	SomeObject* Object2=new (ELeave) CSomeObject;
	
	CleanupStack::PushL(Object2);

}


[edit] Don't push objects on the cleanup stack twice

Always remember that functions with a trailing C on their name automatically put the object on the Cleanup Stack. You should not push these objects onto the stack yourself, or they will be present twice. The trailing C functions are useful when you are allocating non-member variables.


[edit] Two-phase construction

Two-phase construction is specially designed to avoid memory leaks, It is essential that you implement this design pattern to avoid memory leaks in your code.For each line of code you write, a good question to ask yourself is ‘Can this line leave?’. If the answer is ‘Yes’, then think: ‘Will all resources be freed?’.


[edit] Descriptors as function parameters

When using descriptors as function parameters, use the base class by default. In most cases, pass descriptors around as a const TDesC&. For modifiable descriptors use TDes&.



[edit] When using Active Objects, be careful of the following things

• There is no need to call TRAP() inside RunL(). The Active Scheduler itself already TRAPs RunL() and calls CActive::RunError()after a leave.
• To this end, you should implement your own RunError() function to handle leaves from RunL().
• Keep RunL() operations short and quick. A long-running operation will block other AOs from running.
• Always implement a DoCancel() function and always call Cancel() in the AO destructor.

[edit] Ensure your application responds to system shutdown events

It is vital that you respond to EEikCmdExit (and any platform-specific events, for example EAknSoftkeyBack and EAknCmdExit on Series 60) in your AppUi::HandleCommandL() method.




[edit] Make use of the Active Object framework wherever possible

Tight polling in a loop is highly inappropriate on a battery powered device and can lead to significant power drain.


[edit] Program compiles for WINS but not for ARMI

Your program compiles for WINS even runs on the emulator but gives errors during ARMI build. Possible reason for this is you have left a space in the header file name i.e. instead of #include "headerfile.h" you've typed #include "headerfile.h ". Just remove that space and the compile again.


[edit] HTTP Posts

In case of HTTP posts with forms always remember to delete the instance of CHTTPFormEncoder. If it is a php script on your server the Form elements are read bottom to top whereas python script reads the Form elements top to bottom. So what may seem to work on php wont work if the scripting language is changed to python. So always:

delete iFormEncoder;

iFormEncoder = NULL;

iFormEncoder = CHTTPFormEncoder::NewL();
通过短时倒谱(Cepstrogram)计算进行时-倒频分析研究(Matlab代码实现)内容概要:本文主要介绍了一项关于短时倒谱(Cepstrogram)计算在时-倒频分析中的研究,并提供了相应的Matlab代码实现。通过短时倒谱分析方法,能够有效提取信号在时间与倒频率域的特征,适用于语音、机械振动、生物医学等领域的信号处理与故障诊断。文中阐述了倒谱分析的基本原理、短时倒谱的计算流程及其在实际工程中的应用价值,展示了如何利用Matlab进行时-倒频图的可视化与分析,帮助研究人员深入理解非平稳信号的周期性成分与谐波结构。; 适合人群:具备一定信号处理基础,熟悉Matlab编程,从事电子信息、机械工程、生物医学或通信等相关领域科研工作的研究生、工程师及科研人员。; 使用场景及目标:①掌握倒谱分析与短时倒谱的基本理论及其与傅里叶变换的关系;②学习如何用Matlab实现Cepstrogram并应用于实际信号的周期性特征提取与故障诊断;③为语音识别、机械设备状态监测、振动信号分析等研究提供技术支持与方法参考; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,先理解倒谱的基本概念再逐步实现短时倒谱分析,注意参数设置如窗长、重叠率等对结果的影响,同时可将该方法与其他时频分析方法(如STFT、小波变换)进行对比,以提升对信号特征的理解能力。
<think>我们正在处理一个关于Vivado编程错误的查询。根据引用内容,用户遇到了两个错误:一个是关于`connect_bd_intf_net`命令的错误(引用1),另一个是关于`program_hw_devices`的错误(引用2)。用户特别关注第二个错误:`ERROR: [Common 17-39] 'program hw devices' failed due to earlier errors.`。 引用1描述的错误发生在Block Design连接过程中,而引用2的错误发生在编程硬件设备时。引用2的错误信息还包含了一个关键点:`Device ... is not programmed (DONE status = 0)`。引用3建议如果连接服务器后没有检测到芯片,可以尝试更换烧写器或线缆。 用户的问题集中在解决`program_hw_devices`错误上。根据引用2,这个错误可能是由于之前的错误导致的(即错误信息中提到的`End of startup status: LOW`和`DONE status = 0`),这通常意味着FPGA没有完成编程。 可能的原因和解决方法: 1. **硬件连接问题**:检查JTAG连接(包括线缆和接口)是否正常。如果连接不稳定,可能导致编程失败。尝试更换USB线或烧写器(如引用3所述)。 2. **设备未正确初始化**:错误信息提到`DONE status = 0`,表示设备未完成编程。这可能是由于之前的编程失败导致的。可以尝试重新扫描硬件目标,或者重新启动Vivado和硬件服务器。 3. **其他错误导致**:根据错误信息`failed due to earlier errors`,我们需要检查之前的错误。在引用2中,有一个错误是`End of startup status: LOW`,这可能是由于FPGA的配置电路没有正确启动。可能的原因包括: - 电源问题:确保FPGA的供电稳定且符合要求。 - 复位问题:检查复位信号是否正常。 - 配置模式设置:确认JTAG模式设置正确。 4. **软件问题**:有时Vivado的硬件服务器可能出现问题。可以尝试断开并重新连接硬件服务器(如引用3提到的`disconnect_hw_server`和`connect_hw_server`命令)。 因此,解决步骤可以归纳为: 1. 检查硬件连接,更换线缆或烧写器。 2. 重启硬件服务器:在Vivado Tcl控制台中运行: ```tcl disconnect_hw_server connect_hw_server ``` 然后重新打开硬件目标并尝试编程。 3. 检查电源和复位电路。 4. 如果问题仍然存在,尝试重新启动Vivado,甚至重启计算机。 另外,引用1中提到的`connect_bd_intf_net`错误可能是另一个独立问题,但如果它发生在同一个工程中,也可能导致后续的编程失败。因此,需要确保Block Design中的连接正确无误。 由于用户只询问了`program_hw_devices`错误,我们主要关注硬件编程的问题。但也要注意,如果前面的设计步骤有错误(如Block Design连接错误),也可能导致生成比特流失败,从而在编程时出错。因此,确保整个设计流程没有错误。 总结回答: 我们将按照以下步骤解决`ERROR: [Common 17-39] 'program_hw_devices' failed due to earlier errors`: 1. 检查硬件连接(线缆、烧写器)。 2. 重启硬件服务器。 3. 确保设计没有其他错误(例如,在生成比特流之前的设计步骤)。 4. 检查电源和复位。 5. 重启软件或计算机。 如果上述步骤不能解决问题,可能需要进一步检查硬件或查看Vivado日志以获取更多信息。 </think> 以下是解决 Vivado 中 `ERROR: [Common 17-39] 'program_hw_devices' failed due to earlier errors` 的方法总结,结合引用内容和实际调试经验: ### 解决方法步骤 1. **检查 JTAG 连接状态** - 在 Tcl 控制台执行命令检查硬件服务器连接: ```tcl open_hw_target # 尝试打开目标设备 ``` - 若返回 `DONE status = 0`(如引用[2]),表示设备未编程成功。此时需: - 更换 USB 烧写器或数据线(尤其当设备列表中未检测到芯片时)[^3] - 重新插拔 JTAG 接口,确保接触牢固 2. **重启硬件服务** 在 Tcl 控制台执行: ```tcl disconnect_hw_server # 断开当前连接 connect_hw_server # 重新连接硬件服务器 ``` 此操作可清除残留连接状态(参考引用[3])。 3. **验证比特流生成** - 确认生成比特流(.bit 文件)时 **无前置错误**(如引用[1]中的 `connect_bd_intf_net` 错误): - 检查 Block Design 中接口连接是否完整(避免空参数报错) - 运行 `validate_bd_design` 确保设计无逻辑冲突 - 重新生成比特流: ```tcl reset_run impl_1 launch_runs impl_1 -to_step write_bitstream ``` 4. **电源与复位检查** - 使用万用表测量 FPGA 的 **VCCINT(核心电压)** 和 **VCCO(Bank电压)** 是否符合开发手册要求 - 确认 `PROGRAM_B` 和 `INIT_B` 复位信号未被意外触发(正常应为高电平) 5. **深度清理工程** 若仍失败,执行彻底清理: ```tcl reset_project # 重置工程 delete_files -force ./my_project.runs # 删除生成目录 restart # 重启 Vivado ``` ### 典型错误链分析 ``` [BD 5-106] → [Common 17-39] → program_hw_devices 失败 ``` 此错误链表明:**Block Design 接口错误** → **导致比特流生成异常** → **最终设备编程失败**[^1][^2]。需优先解决设计阶段错误。 ### 预防措施 - 每次修改 Block Design 后执行 `validate_bd_design` - 编程前在 Tcl 控制台检查设备状态: ```tcl get_hw_devices # 确认设备是否在列表中 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值