本人一般是不转贴的,(除了万院长的那篇经典中的经典)。今天无意中看到一篇文章,不禁回忆起自己当年在CE下摸索写驱动的时光。对于初接触嵌入式开发的人来说,一些基本方法和思路的确是需要“洗脑”的。

这篇文章不难看出是作者的经验总结,虽然有些内容不完全赞同,但是还是保持原汁原味吧。对处于探索阶段的同学肯定会有帮助。

原文地址:http://blog.csdn.net/xqhrs232/archive/2009/11/27/4888577.aspx


1。向串口打印消息———-//只能打印一般的消息,实时性要求高的地方建议不要去打印消息,因为串口打印很慢,即使要打印也尽量少打印或者有选择地打印–比如100次才打印一次

//串口打印也可以大致分析各个线程间有没存在对同一个资源访问的互锁什么的

2。写LOGO文件——-写文件应该比串口打印来的快,写LOGO也适合于分析数据量很大的场合

3。灵活使用static 变量—–//static变量有记忆的功能,可以用这一点来诊断程序的可靠性—特别是中断接收什么的—-记忆个几十K数据再写到LOGO文件是不错的调试方法

4。写驱动的时候往往要求正确延时什么的—–//所以正确地实现US/MS的延时很重要

//WINCE 微秒级延时函数

void delay_us(int n)
{

LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;

if(QueryPerformanceFrequency(&litmp)==FALSE)
{
MessageBox(NULL,TEXT(“Error:QueryPerformanceFrequency”),TEXT(“Error”),MB_OK);
return;

}

dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;

do
{
QueryPerformanceCounter(&litmp);
QPart2=litmp.QuadPart;
dfMinus=(double)(QPart2-QPart1);
dfTim=dfMinus/dfFreq;

}while(dfTim <0.000001*n);

}

//WINCE毫秒级延时函数

void delay_ms(DWORD tmp_time)
{
DWORD start;
DWORD time_i=0;
start=GetTickCount();

while(time_i<=tmp_time)
{
time_i=GetTickCount()-start;
}

}


5。写驱动程序一般都会有牵涉到对中断的处理———//所以在AP层面跟驱动里面正确无误地实现开中断跟关中断很必要


特别是在分析中断有没工作正常的时候—–//抓取一定数据量的中断数据然后关闭中断,确保接收到的数据不会被破坏这样分析到的实验结果才能是真实的情况



6。测试一段代码的运行时间——–//可以用 GetTickCount函数去大致测试一下一段代码的运行耗时找到程序的热点

dwStartTickCount=GetTickCount( );



。。。。。。XXXXXX

//要测试的代码片段


dwEndTickCount=GetTickCount( );


7。驱动一般都要求实时性很高所以在程序里面尽量把代码精简与优化

1》首先肯定是好的算法的选择与优化
2》尽量用加减法去代替乘除法
3》用移位操作去代替乘除法
4》在函数调用的时候不需要的变量尽量去除,因为函数调用存在一个压栈与出栈的操作,有一个无用的变量多了两次操作,变量最好分配成32位的
5》减少多次的函数调用,可以封到一起的功能尽量封成一个函数
6》内存COPY应该比一个个循环赋值来的快
7》减少循环嵌套的次数,减少循环的次数
8》降低计算的复杂度
9》尽量使用库函数不要自己去随便封装函数来用,库函数一般比我们自己封装的函数好用可靠
10》进程++++线程++++关键区++++消息队列++++互斥体的合理选择使用可以简化程序逻辑与优化对同一个资源的竞争使用
11》尽量减少程序编译的警告,减少强制类型转换



8。 volatile修饰语的使用—–//避免被优化什么的,重新读取什么的,网上有很详细的介绍文章


这个在中断处理程序里面一般很常用,一个变量开关由AP随时去控制


9。看系统的报错消息,分析源文件编译对应的MAP文件与COD文件

1》一般的什么DATA ABORT错误分析MAP文件可以定位错误到那个函数里面
2》分析对应的COD文件可以把错误定位到那一条语句,不过COD文件是用汇编语言写的



10。VIEWBIN/DUMPBIN/SET工具的使用

1》VIEWBIN工具一般用于看NK的内容看驱动程序有没被包括进NK什么的
2》DUMPBIN工具可以看看驱动里面导出了那些函数接口
3》SET工具看系统的环境变量设置


11。WINCE的那些远程工具

1》看内存情况,看有没存在内存泄漏
2》看注册表的情况看驱动有没被系统加载起来
3》看系统的CPU使用率看系统快与慢的原因,看是不是自己的驱动严重地占用了CPU的使用率
4》文件来回COPY


12。用KITL工具—–//去实现KITL调试手段

DEBUG的方式还是可以定位到很多问题的—–//可以看变量看内存看函数调用堆栈




13。用 GlobalMemoryStatus函数去定时诊断系统的内存状态看有没存在内存不够与内存泄漏的情况

1》在代码里面malloc跟free配对使用
2》在代码里面new跟delete陪对使用
3》动态NEW分配的数组要用delete[]去释放
4》使用过的位图/资源最后要记得正确释放,用好用准DeleteObject/DeleteDC/ReleaseDC这些释放资源的函数
5》声明指针时防止指针乱指,安全可靠地使用/释放指针,用指针前记得判断指针的合法性
6》防止在使用数组的时候出现访问越界

14。变量与BUFFER的存放位置—–//最好全盘考虑一下,放堆上还是栈上还是全局


15。尽量减少动态与多次地分配与释放内存——//容易造成内存碎片什么的,能够固定大小的内存分配可以考虑用数组去代替


16。创建跟线程绑定的事件的时候最好指定名称——-//有名称的事件在AP层面都可以去操作的,这样在没有实际的环境下就可以去模拟驱动的操作

有名称事件在整个系统里面是唯一的,多次打开指向的是同一个事件


17。灵活定义IOCONTROL宏,方便AP操作,AP模拟驱动的数据格式与操作,方便在没有实际环境的条件下走通驱动的整个流程

18。还有就是WINCE的驱动调试助手——–//很方便使用的,这样也不用每次去更新NK

19。CETK工具可以玩玩但我也没怎么玩过啊!!!

20。还有we-hjb这个牛人写的一个工具软件—-寄存器读写工具 ,用于WINCE50和WINCE60的版本都有.

可以随时看SFR的配置情况,很好用的一个工具软件.

21。编译开关与调试代码

1》#if/#else/#endif的灵活使用——–//这样可以在调试代码与实际代码间灵活地切换
2》现在有一种思路那就是测试先行,在写代码只前就得写好测试的代码,没有经过测试的代码那只是垃圾代码


22。硬件工具的灵活使用,常用的工具有

1》万用表
2》示波器———//看看波形有没受干扰,看看要不要接上拉电阻,应该接多少
3》逻辑分析仪—–//可以抓几K数据进行分析,常见的总线形式也可以分析的
4》频谱仪