} j = 1; break;
case 0x30: //sector erase *(Uint16 *)addr = type;
while((*(Uint16 *)addr & 0x80) != 0x80); for(i = 0; i < SECTOR_SIZE; i++) {
if(*(Uint16 *)(addr + i) != 0xffff) {
j = 0; break; } } j = 1; break;
case 0x10: //chip erase // for(;;) // {
*FLASH_5555 = type; // }
while((*FLASH_5555 & 0x80) != 0x80); for(i = 0; i < CHIP_SIZE; i++) {
if(*(Uint16 *)(addr + i) != 0xffff) {
j = 0; break; } } j = 1; break;
default:
break; }
return (j); }
while((*FLASH_5555 & 0x80) != 0x80); 为什么要写成无限循环的形式呢?
那是因为系统会为每一个任务保留一个堆栈空间,由系统在任务切换的时候恢复上下文,并执行一条reti 指令返回。如果允许任务执行到最后一个花括号(那一般都意味着一条ret指令)的话,很可能会破坏系统堆栈空间从而使应用程序的执行不确定。换句话说,就是“跑飞”了。所以,每一个任务必须被写成无限循环的形式。
程序员一定要相信,自己的任务是会放弃CPU使用权的,而不管是系统强制(通过ISR)还是主动放弃(通过调用OS API)。
标准C运行在操作系统下,退出你的函数后,控制权会交给操作系统。而在DSP的CCS中没有操作系统,退出函数意味着程序跑飞!!!这就是标准C和DSP的C的区别。所以while((*FLASH_5555 & 0x80) != 0x80);这里时,不是死循环!是程序的必要条件。
/********************************************************************************\\ \\* Write a single data. *\\
\\********************************************************************************/ void Flash_Writes(Uint32 addr,Uint16 data) {
// Uint16 TempData=0;
*FLASH_5555 = FLASH_UL1; *FLASH_2AAA = FLASH_UL2;
*FLASH_5555 = FLASH_PROGRAM;
*(Uint16 *)addr = data;
//TempData = *(Uint16 *)(addr+28); while(*(Uint16 *)addr != data); }
/********************************************************************************\\ \\* Write the certain length data. *\\
\\********************************************************************************/ void Flash_Writem(Uint32 addr,Uint16 *ptr,Uint32 length) {
Uint32 i;
for(i = 0; i < length; i++) {
// for(;;) // {
Flash_Writes(addr+2*i,*(ptr+i)); // } } }
/********************************************************************************\\ \\* Read a single data. *\\
\\********************************************************************************/ Uint32 Flash_Reads(Uint32 addr) {
return (*(Uint16 *)addr); }
/********************************************************************************\\ \\* Read the certain length data. *\\
\\********************************************************************************/ void Flash_Readm(Uint32 addr,Uint16 *ptr,Uint32 length) {
Uint32 i;
for(i = 0; i < length; i++) {
*(ptr + i) = Flash_Reads(addr+2*i); } }
/********************************************************************************\\ \\* End of DEC6713_FLASH.C *\\
\\********************************************************************************/
C6000软件优化经验总结
DSP 优化心得
1
推荐
C6XX优化经验总结 一、c6x的编译的常用选项
(一)c6x的编译程序为“cl6x.exe”使用的方法 Cl6x [options] [filenames] Cl6x: 编译程序 Options: 编译选项
Filenames: C或汇编源文件
说明:
编译选项是一个字母或者两个字母,对大小写不敏感。 编译选项的前面需要有一个“-”符号。
一个字母的选项可以合并在一起。比如“-sgq”与“-s -g -q”相同。
两个字母的选项如果第一个字母相同也可以合并在一起。比如“-mgt”与“-mg -mt”相同。 (二)有关优化的选项
-mt:表示在程序中没有使用alaising技术,这使得编译器可以进行比较好的优化。 -o3:对文件级别进行最强的优化,一般在编译时应该使用这个选项。但是在个别情况下使用这个选项优化程序可能会出现
错误(-o2有相同现象,-o0和-o1不会出现错误)。可能是在优化循环,组织流水线的时候发生错误。如果有这种现象出现可以同时
使用-g选项,程序优化就不会出现错误,但是优化效果会下降。另外可以调整程序的表达方式,可能会避免编译器发生错误。
-pm:在程序级别进行优化。可以将所以文件联合在一起进行优化,主要有去掉没有被调用的函数、总是常数的变量以及没有使用的
函数返回值。建议由程序员自己进行这种优化工作。使用这个选项在win98下编译可能会出现找不到编译程序的情况。
-ms0:不使用冗余循环进行优化,减小程序的大小。一般情况下这个选项对程序大小的优化作用不明显。
-mh[n]:去掉流水线的epilog,减小程序的大小。这个选项的作用比较明显。但是有可能出现读取地址超出有效范围的问题,
所以要在数据段的开始和结尾处增加一些pading,或者在分配内存时保证数组的前面和后面一段范围内都是有效的地址。
可选的参数n给出这种pading的长度字节数。 (三)保留编译和优化信息的选项 -k:保留优化后生成汇编语言文件。
-s:汇编语言文件中加入优化信息,如果没有则加入C语言源程序作为注释。 -mw:在汇编语言文件加入软件流水线信息。 (四)有关调试和剖析的选项
-g:允许符号调试,在“out”文件中包含符号信息和行号信息,可以在c语言级别进行调试和剖析。使用联合使用-g、-mt和-o3可以保 证能够进行符号调试的情况下最大限度的优化。
-mg:允许profile优化后的程序。在“out”文件中包含符号信息和很少的行号信息。允许在c
语言的函数基本进行剖析。
如果联合使用这两个选项,-g选项可能被忽略,结果与只用-mg相同。 (五)其它类型
-mln:生成大内存模式的程序。
-ml0:缺省情况下将集合变量(数组和结构)作为far型。 -ml1:缺省情况下将全部函数作为far型 -ml2:等于-ml0加-ml1
-ml3:缺省情况下将全部数据和函数作为far型 (六)建议使用的编译方式
Cl6x -gk -mt -o3 -mw -ss “filename”
方式1用于程序的调试,这种方式具有比较强的优化能力,并且支持符号调试。在编译的过程中不会发生错误。
由于生成的“out”文件中包含了符号信息和行号信息,所以比较大。 Cl6x -k -mgt -o3 -mw -ss “filename”
方式2用于程序的剖析(profile),这种方式的优化能力几乎最强(绝大多数情况下与方式3相同),
并且支持对程序进行profile。文件中只包含了符号信息和很少的行号信息,所以“out”文件比较小。
Cl6x -k -mt -o3 -mw -ss “filename”
方式3用于最终的发行版本程序,可以对程序进行最强的优化,并且去掉了全部的符号和行号信息,所以“out”文件比较小。
由多个文件组成的程序应该编写makefile,将编译参数放在该文件中,并在其中说明使用的编译器的版本号。 (七)连接参数 -heap:指定堆的大小 -stack:指定栈的大小
连接的各种选项应该统一放在“cmd”文件中 二、双重循环和多重循环的优化总结
双重循环多重循环看起来比较复杂,但实际上多重循环优化方法比较简单,就在于一个字:“拆”,一旦完成这一步之后,
多重循环就成为单层循环,优化就可以按照普通的单层循环来做了。
多重循环的特点是在优化器优化时只在最内层循环中形成一个pipeline,这样循环语句就不