<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>对影成三人 &#187; CCS</title>
	<atom:link href="http://ichaochao.com/tag/ccs/feed/" rel="self" type="application/rss+xml" />
	<link>http://ichaochao.com</link>
	<description></description>
	<lastBuildDate>Wed, 21 Jul 2010 03:29:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>FFT在C6000DSP上的仿真</title>
		<link>http://ichaochao.com/2008/07/01/fft_in_dsp/</link>
		<comments>http://ichaochao.com/2008/07/01/fft_in_dsp/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 09:04:00 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[假装爱摄影]]></category>
		<category><![CDATA[c6000]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>
		<category><![CDATA[fft]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/07/01/fft_in_dsp/</guid>
		<description><![CDATA[经过一段时间的学习，今天在CCS内成功仿真了基2频域抽取FFT(radix2 DIF FFT)。
环境：CCS 3.1 + C6201 Device Simulator
仿真结果如下图：

全部代码在下面，为了描述简单，把所有函数写在了一起，实际运用中不应该这样做。另外位反转索引表和旋转因子表都是在里面实时生成的，实际运用时，应该做好表格后嵌入，或在编译时生成而不是运行时生成。
感谢 pacificxu 的教程，他貌似曾经是闻亭的高手。
#include &#8220;math.h&#8221;
/*========================================*/
/* GLOBAL CONSTANTS                                                          */
/*========================================*/
#define PI    3.14159265358979
#define N        2048
/*========================================*/
/* GLOBAL VARIABLES                                                          */
/*========================================*/
static short index1[64], w1[N];
static short x1[N*2];
static int x2[N];
int i;
void DSP_radix2(int n, short *restrict xy, const short *restrict w)
{
short n1,n2,ie,ia,i,j,k,l;
short xt,yt,c,s;
n2 = n;
ie = 1;
for (k=n; k &#62; 1; k = (k &#62;&#62; 1) )
{
n1 = <a href="http://ichaochao.com/2008/07/01/fft_in_dsp/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>经过一段时间的学习，今天在CCS内成功仿真了基2频域抽取FFT(radix2 DIF FFT)。</p>
<p>环境：CCS 3.1 + C6201 Device Simulator</p>
<p>仿真结果如下图：</p>
<p><span id="more-155"></span><a href="http://ichaochao.com/wp-content/uploads/2008/07/fft-timewave.jpg"><img style="0px" src="http://ichaochao.com/wp-content/uploads/2008/07/fft-timewave-thumb.jpg" border="0" alt="fft_timewave" width="244" height="169" /></a><a href="http://ichaochao.com/wp-content/uploads/2008/07/fft-freqwave.jpg"><img style="0px" src="http://ichaochao.com/wp-content/uploads/2008/07/fft-freqwave-thumb.jpg" border="0" alt="fft_freqwave" width="244" height="168" /></a></p>
<p>全部代码在下面，为了描述简单，把所有函数写在了一起，实际运用中不应该这样做。另外位反转索引表和旋转因子表都是在里面实时生成的，实际运用时，应该做好表格后嵌入，或在编译时生成而不是运行时生成。</p>
<p>感谢 pacificxu 的教程，他貌似曾经是闻亭的高手。</p>
<p>#include &#8220;math.h&#8221;<br />
/*========================================*/<br />
/* GLOBAL CONSTANTS                                                          */<br />
/*========================================*/</p>
<p>#define PI    3.14159265358979<br />
#define N        2048</p>
<p>/*========================================*/<br />
/* GLOBAL VARIABLES                                                          */<br />
/*========================================*/<br />
static short index1[64], w1[N];<br />
static short x1[N*2];<br />
static int x2[N];<br />
int i;</p>
<p>void DSP_radix2(int n, short *restrict xy, const short *restrict w)<br />
{<br />
short n1,n2,ie,ia,i,j,k,l;<br />
short xt,yt,c,s;<br />
n2 = n;<br />
ie = 1;<br />
for (k=n; k &gt; 1; k = (k &gt;&gt; 1) )<br />
{<br />
n1 = n2;<br />
n2 = n2&gt;&gt;1;<br />
ia = 0;<br />
for (j=0; j &lt; n2; j++)<br />
{<br />
c = w[2*ia];<br />
s = w[2*ia+1];<br />
ia = ia + ie;<br />
for (i=j; i &lt; n; i += n1)<br />
{<br />
l = i + n2;<br />
xt      = xy[2*l] &#8211; xy[2*i];<br />
xy[2*i] = xy[2*i] + xy[2*l];<br />
yt      = xy[2*l+1] &#8211; xy[2*i+1];<br />
xy[2*i+1] = xy[2*i+1] + xy[2*l+1];<br />
xy[2*l]   = (c*xt + s*yt)&gt;&gt;15;<br />
xy[2*l+1] = (c*yt &#8211; s*xt)&gt;&gt;15;<br />
}<br />
}<br />
ie = ie&lt;&lt;1;<br />
}<br />
}<br />
void DSP_bitrev_cplx(int *x, short *index, int nx)<br />
{<br />
int     i;<br />
short       i0, i1, i3;<br />
short       j0, j1, j3;<br />
int     xi0, xi1, xi3;<br />
int     xj0, xj1, xj3;<br />
short       t;<br />
int     a, b, ia, ib, ibs;<br />
int     mask;<br />
int     nbits, nbot, ntop, ndiff, n2, halfn;<br />
nbits = 0;<br />
i = nx;<br />
while (i &gt; 1)<br />
{<br />
i = i &gt;&gt; 1;<br />
nbits++;<br />
}</p>
<p>nbot    = nbits &gt;&gt; 1;<br />
ndiff   = nbits &amp; 1;<br />
ntop    = nbot + ndiff;<br />
n2      = 1 &lt;&lt; ntop;<br />
mask    = n2 &#8211; 1;<br />
halfn   = nx &gt;&gt; 1;<br />
for (i0 = 0; i0 &lt; halfn; i0 += 2)<br />
{<br />
b   = i0 &amp; mask;<br />
a   = i0 &gt;&gt; nbot;<br />
if (!b) ia  = index[a];<br />
ib  = index[b];<br />
ibs = ib &lt;&lt; nbot;<br />
j0  = ibs + ia;<br />
t   = i0 &lt; j0;<br />
xi0 = x[i0];<br />
xj0 = x[j0];</p>
<p>if (t){x[i0] = xj0;<br />
x[j0] = xi0;}</p>
<p>i1  = i0 + 1;<br />
j1  = j0 + halfn;<br />
xi1 = x[i1];<br />
xj1 = x[j1];<br />
x[i1] = xj1;<br />
x[j1] = xi1;</p>
<p>i3  = i1 + halfn;<br />
j3  = j1 + 1;<br />
xi3 = x[i3];<br />
xj3 = x[j3];<br />
if (t){x[i3] = xj3;<br />
x[j3] = xi3;}<br />
}<br />
}<br />
void bitrev_index(short *index, int n)<br />
{<br />
int   i, j, k, radix = 2;<br />
short nbits, nbot, ntop, ndiff, n2, raddiv2;<br />
nbits = 0;<br />
i = n;<br />
while (i &gt; 1)<br />
{<br />
i = i &gt;&gt; 1;<br />
nbits++;<br />
}<br />
raddiv2 = radix &gt;&gt; 1;<br />
nbot    = nbits &gt;&gt; raddiv2;<br />
nbot    = nbot &lt;&lt; raddiv2 &#8211; 1;<br />
ndiff   = nbits &amp; raddiv2;<br />
ntop    = nbot + ndiff;<br />
n2      = 1 &lt;&lt; ntop;<br />
index[0] = 0;<br />
for ( i = 1, j = n2/radix + 1; i &lt; n2 &#8211; 1; i++)<br />
{<br />
index[i] = j &#8211; 1;<br />
for (k = n2/radix; k*(radix-1) &lt; j; k /= radix)<br />
j -= k*(radix-1);<br />
j += k;<br />
}<br />
index[n2 - 1] = n2 &#8211; 1;<br />
}<br />
/*===================================*/<br />
/* MAIN()                                                                    */<br />
/*===================================*/<br />
void main()</p>
<p>{<br />
double delta;</p>
<p>/*======== init the index table for FFT bitrev =====*/</p>
<p>bitrev_index(index1, N);</p>
<p>/*======== init the FFT coeficients =====*/<br />
delta = 2*PI/N;<br />
for (i=0;i&lt;N/2;i++)<br />
{<br />
w1[2*i] = 32767*(-cos((double)i*delta));<br />
w1[2*i+1] = 32767*(-sin((double)i*delta));<br />
}</p>
<p>/*======== init the input data =====*/<br />
for (i=0;i&lt;N;i++)<br />
{<br />
x1[2*i] = (short)((cos(PI*i/20.0)+cos(PI*i/10.0)+cos(PI*i/5.0))*0&#215;80);<br />
x1[2*i+1] = 0;<br />
}<br />
/*======== implement FFT =====*/</p>
<p>DSP_radix2(N, x1, w1);<br />
for (i=0; i&lt;N; i++)<br />
{<br />
x2[i] = sqrt(x1[2*i]*x1[2*i]+x1[2*i+1]*x1[2*i+1]);  //&#8212;?<br />
}</p>
<p>/*======== bitrev =====*/</p>
<p>DSP_bitrev_cplx(x2, index1, N);<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/01/fft_in_dsp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CCS的一些问题(转)</title>
		<link>http://ichaochao.com/2008/07/01/ccs_problem/</link>
		<comments>http://ichaochao.com/2008/07/01/ccs_problem/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 02:15:40 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>

		<guid isPermaLink="false">http://ichaochao.com/?p=150</guid>
		<description><![CDATA[来自DSP交流网
CCS版本:V3.1
1.run和animate的区别
如果没有断点的话,这两个没区别.
如果有断点,那么run的时候到断点会停止,直到再次按run或者F5才继续执行.
而Animate到断点的时候,会停一小会,将所有窗口刷新一遍,然后就继续执行

一般就是在要看数据变化的时候,先把曲线画出来,然后在改变数据的循环里面设个断点,然后用animate,就能看到图片动态改变了,可以参考 Help-&#62;tutorial里面的&#8221;Code Composer Studio? IDE&#8221;-&#62;&#8221;Using Debug Tools&#8221;这一个教程
2.Probe Point 和Breakpoints的区别和联系
共性:他们都会暂停程序运行
区别:
1.Probe Point暂停程序,执行一个设定的任务(如File I/O),然后继续执行程序.而BreakPoint暂停后必须手动继续(当用run的时候)
2.BreakPoints会刷新所有窗口,而ProbePoint不会
3.Probe Point可以执行一些任务(如File I/O),而BreakPoints就是纯粹的停止.
3.阻塞(blocked)和中断(interrupt)的区别和联系
共性:他们都能停止一个tsk(任务,具体见我的另一篇文章:关于tsk和mbx)的执行
区别:
1.只有tsk(任务)能被阻塞,而swi(软中断)和hwi(硬中断)不能阻塞,只能中断
2.停止的原因不一样,阻塞是在某些条件不满足的时候停止tsk,中断是因为有高优先级的事情要做而停止
3.恢复运行的条件不一样,阻塞是要等到原来不满足的条件满足后才能继续,而中断是要等高优先级的任务返回后才继续执行.
4.阻塞改变tsk的任务队列,而中断一个tsk不会改变tsk的任务队列.
举个现实的例子:
如果你在写作业,写着写着,碰到一道很难的题,你百思不得其解,这个时候写作业的这个tsk就被阻塞了,只有等到你想出来这道题怎么做,才能继续做下去.
另外一种情况,还是在写作业,突然门铃响了,你必须去开门,那写作业这个tsk就被中断了,你开完门就能回来继续写作业.
4.LOG_printf和printf的区别和联系
共性:都是用于输出一些内容,一般用于显示一些调试信息,而且可以格式化输出,比如用&#8217;%d&#8217;输出整数
区别:
1.输出目标不同,printf输出到output窗口,而LOG_printf输出到BIOS的log窗口
2.汇编指令条数不同,printf需要上万条汇编指令,而LOG_printf只要30多条汇编指令,因此LOG_printf的运行速度比printf要快的多,一般在实时系统中,都使用LOG_printf来输出,这样对系统的实时性影响才不大
3.参数个数不同,printf后面的参数个数可以有很多个(具体多少个没测试过),而LOG_printf后面最多只能有4个参数,第一个是写入的地址,第二个是字符串,后面最多加上两个格式化输出的数据,这两个数据还必须是整型,或者指针,或者常量字符串
4.可以输出的格式不同,printf有很多的格式,而LOG_printf只有有限的几种.(%d整型,%x无符号16进制数,%o无符号8进制数,%s常量字符串,%p指针)
5.LOG_printf输出的长度受设定的buffer大小限制,如果超出buffer大小,根据设置的不同,可以是停止输出,或者覆盖原来的内容
6.LOG_printf的优先级比较低,可能是在KNL层,只有系统比较空闲的时候,才会输出,而printf是必然会输出.(比如在一个i=1到 100的循环中,用printf就会输出100个数,而用LOG_printf就只会输出一部分数,而且在没有碰到断点的时候,根本不会输出,因为他的优 先级相当低,只有在走到断点的时候,系统才允许他执行.)
5.设置tab的宽度
1.打开&#8221;Option -&#62; Editor -&#62; language&#8221;
2.在左边的File Type里面选择要修改的扩展名(CCS中每种不同扩展名的文件都能设置不同的tab宽度,而不是象一般的代码编辑器,可以全局设置)
3.在右边顶部选择&#8221;Tabs/Indenting&#8221;选项卡
4.在&#8221;Tab Columns&#8221;下面的框中输入&#8221;3 5&#8243;(默认值是5 9,注意两个数值中间有空格)
5.点击OK按钮
解释一下&#8221;3 5&#8243;的意义,第一个数字等于在一行的最开头按Tab键时跳过的列数加1,第二个数减去第一个数的结果,等于除去每行最开头外的Tab的宽度.
设置成&#8221;3 5&#8243;表示如果在每行开头按Tab,缩进3-1=2列,而其它地方的缩进是5-3=2列,也就是无论什么地方Tab键的宽度都是2列.
个人觉得,CCS的这个设置Tab键宽度挺有意思的.
]]></description>
			<content:encoded><![CDATA[<p>来自<a href="http://www.hellodsp.com/" target="_blank">DSP交流网</a><br />
CCS版本:V3.1</p>
<p>1.run和animate的区别</p>
<p>如果没有断点的话,这两个没区别.<br />
如果有断点,那么run的时候到断点会停止,直到再次按run或者F5才继续执行.<br />
而Animate到断点的时候,会停一小会,将所有窗口刷新一遍,然后就继续执行</p>
<p><span id="more-150"></span></p>
<p>一般就是在要看数据变化的时候,先把曲线画出来,然后在改变数据的循环里面设个断点,然后用animate,就能看到图片动态改变了,可以参考 Help-&gt;tutorial里面的&#8221;Code Composer Studio? IDE&#8221;-&gt;&#8221;Using Debug Tools&#8221;这一个教程</p>
<p>2.Probe Point 和Breakpoints的区别和联系</p>
<p>共性:他们都会暂停程序运行</p>
<p>区别:</p>
<p>1.Probe Point暂停程序,执行一个设定的任务(如File I/O),然后继续执行程序.而BreakPoint暂停后必须手动继续(当用run的时候)<br />
2.BreakPoints会刷新所有窗口,而ProbePoint不会<br />
3.Probe Point可以执行一些任务(如File I/O),而BreakPoints就是纯粹的停止.</p>
<p>3.阻塞(blocked)和中断(interrupt)的区别和联系</p>
<p>共性:他们都能停止一个tsk(任务,具体见我的另一篇文章:关于tsk和mbx)的执行</p>
<p>区别:</p>
<p>1.只有tsk(任务)能被阻塞,而swi(软中断)和hwi(硬中断)不能阻塞,只能中断</p>
<p>2.停止的原因不一样,阻塞是在某些条件不满足的时候停止tsk,中断是因为有高优先级的事情要做而停止</p>
<p>3.恢复运行的条件不一样,阻塞是要等到原来不满足的条件满足后才能继续,而中断是要等高优先级的任务返回后才继续执行.</p>
<p>4.阻塞改变tsk的任务队列,而中断一个tsk不会改变tsk的任务队列.</p>
<p>举个现实的例子:<br />
如果你在写作业,写着写着,碰到一道很难的题,你百思不得其解,这个时候写作业的这个tsk就被阻塞了,只有等到你想出来这道题怎么做,才能继续做下去.</p>
<p>另外一种情况,还是在写作业,突然门铃响了,你必须去开门,那写作业这个tsk就被中断了,你开完门就能回来继续写作业.</p>
<p>4.LOG_printf和printf的区别和联系</p>
<p>共性:都是用于输出一些内容,一般用于显示一些调试信息,而且可以格式化输出,比如用&#8217;%d&#8217;输出整数</p>
<p>区别:</p>
<p>1.输出目标不同,printf输出到output窗口,而LOG_printf输出到BIOS的log窗口</p>
<p>2.汇编指令条数不同,printf需要上万条汇编指令,而LOG_printf只要30多条汇编指令,因此LOG_printf的运行速度比printf要快的多,一般在实时系统中,都使用LOG_printf来输出,这样对系统的实时性影响才不大</p>
<p>3.参数个数不同,printf后面的参数个数可以有很多个(具体多少个没测试过),而LOG_printf后面最多只能有4个参数,第一个是写入的地址,第二个是字符串,后面最多加上两个格式化输出的数据,这两个数据还必须是整型,或者指针,或者常量字符串</p>
<p>4.可以输出的格式不同,printf有很多的格式,而LOG_printf只有有限的几种.(%d整型,%x无符号16进制数,%o无符号8进制数,%s常量字符串,%p指针)</p>
<p>5.LOG_printf输出的长度受设定的buffer大小限制,如果超出buffer大小,根据设置的不同,可以是停止输出,或者覆盖原来的内容</p>
<p>6.LOG_printf的优先级比较低,可能是在KNL层,只有系统比较空闲的时候,才会输出,而printf是必然会输出.(比如在一个i=1到 100的循环中,用printf就会输出100个数,而用LOG_printf就只会输出一部分数,而且在没有碰到断点的时候,根本不会输出,因为他的优 先级相当低,只有在走到断点的时候,系统才允许他执行.)</p>
<p>5.设置tab的宽度</p>
<p>1.打开&#8221;Option -&gt; Editor -&gt; language&#8221;<br />
2.在左边的File Type里面选择要修改的扩展名(CCS中每种不同扩展名的文件都能设置不同的tab宽度,而不是象一般的代码编辑器,可以全局设置)<br />
3.在右边顶部选择&#8221;Tabs/Indenting&#8221;选项卡<br />
4.在&#8221;Tab Columns&#8221;下面的框中输入&#8221;3 5&#8243;(默认值是5 9,注意两个数值中间有空格)<br />
5.点击OK按钮</p>
<p>解释一下&#8221;3 5&#8243;的意义,第一个数字等于在一行的最开头按Tab键时跳过的列数加1,第二个数减去第一个数的结果,等于除去每行最开头外的Tab的宽度.<br />
设置成&#8221;3 5&#8243;表示如果在每行开头按Tab,缩进3-1=2列,而其它地方的缩进是5-3=2列,也就是无论什么地方Tab键的宽度都是2列.</p>
<p>个人觉得,CCS的这个设置Tab键宽度挺有意思的.</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/01/ccs_problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CCS中DSP的编译连接</title>
		<link>http://ichaochao.com/2008/05/27/compile_link_of_ccs/</link>
		<comments>http://ichaochao.com/2008/05/27/compile_link_of_ccs/#comments</comments>
		<pubDate>Tue, 27 May 2008 02:57:18 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>

		<guid isPermaLink="false">http://ichaochao.com/?p=61</guid>
		<description><![CDATA[源代码，经编译器，生成可重定位的代码块和数据块（称为段-section）.
然后经连接器，将这些段分配到目标存储器。
可通过.cmd文件用两个伪指令来定义连接：
memory &#8211; 定义存储器各部分的起始地址和长度
sections &#8211; 定义把各个段放在存储器的什么位置

可通过生成.map文件来观察代码和数据空间的映射关系。
CCS例程中的一个.cmd文件如下：
MEMORY
{
IPRAM       : origin = 0&#215;0,         len = 0&#215;10000
IDRAM       : origin = 0&#215;80000000,  len = 0&#215;10000
}
SECTIONS
{
.vectors &#62; IPRAM
.text    &#62; IPRAM
.bss     &#62; IDRAM
.cinit   <a href="http://ichaochao.com/2008/05/27/compile_link_of_ccs/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>源代码，经编译器，生成可重定位的代码块和数据块（称为段-section）.</p>
<p>然后经连接器，将这些段分配到目标存储器。</p>
<p>可通过.cmd文件用两个伪指令来定义连接：</p>
<p>memory &#8211; 定义存储器各部分的起始地址和长度</p>
<p>sections &#8211; 定义把各个段放在存储器的什么位置</p>
<p><span id="more-61"></span></p>
<p>可通过生成<a title="关于map文件的一点认识" href="http://ichaochao.com/?p=21" target="_blank">.map文件</a>来观察代码和数据空间的映射关系。</p>
<p>CCS例程中的一个.cmd文件如下：</p>
<p>MEMORY<br />
{<br />
IPRAM       : origin = 0&#215;0,         len = 0&#215;10000<br />
IDRAM       : origin = 0&#215;80000000,  len = 0&#215;10000<br />
}</p>
<p>SECTIONS<br />
{<br />
.vectors &gt; IPRAM<br />
.text    &gt; IPRAM</p>
<p>.bss     &gt; IDRAM<br />
.cinit   &gt; IDRAM<br />
.const   &gt; IDRAM<br />
.far     &gt; IDRAM<br />
.stack   &gt; IDRAM<br />
.cio     &gt; IDRAM<br />
.sysmem  &gt; IDRAM<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/05/27/compile_link_of_ccs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于 关键字 restrict</title>
		<link>http://ichaochao.com/2008/05/14/dsp_restrict/</link>
		<comments>http://ichaochao.com/2008/05/14/dsp_restrict/#comments</comments>
		<pubDate>Wed, 14 May 2008 08:12:58 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>

		<guid isPermaLink="false">http://blog.ichaochao.com/2008/05/14/%e5%85%b3%e4%ba%8e-%e5%85%b3%e9%94%ae%e5%ad%97-restrict/</guid>
		<description><![CDATA[为了帮助编译器确定存储器相关性，可以使用关键字restrict来限定指针、引用或数组。关键字restrict是对指针、引用或数组的一种限定。使用restrict关键字是为了确保其限定的指针在声明的范围内，是指向一个特定对象的唯一指针，及这个指针不会和其它指针指向存储器的同一地址。这使编译器更容易确定是否有别名信息，从而更好地优化代码。
下例中，关键字restrict的使用告知编译器func1中指针a和b所指向的存储器范围不会交叠，这表明通过指针变量a和b对存储器的访问不会冲突，即对一个指针变量的写操作不会影响另一个指针变量的读操作。
void func1(int * restrict a, int * restrict b)
{
/* func1&#8217;s code here */
}
To help the compiler determine memory dependencies, you can qualify a pointer, reference, or array with the restrict keyword. The restrict keyword is a type qualifier that may be applied to pointers, references, and arrays. Its use represents a guarantee by the programmer <a href="http://ichaochao.com/2008/05/14/dsp_restrict/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>为了帮助编译器确定存储器相关性，可以使用关键字restrict来限定指针、引用或数组。关键字restrict是对指针、引用或数组的一种限定。使用restrict关键字是为了确保其限定的指针在声明的范围内，是指向一个特定对象的唯一指针，及这个指针不会和其它指针指向存储器的同一地址。这使编译器更容易确定是否有别名信息，从而更好地优化代码。<span id="more-22"></span><br />
下例中，关键字restrict的使用告知编译器func1中指针a和b所指向的存储器范围不会交叠，这表明通过指针变量a和b对存储器的访问不会冲突，即对一个指针变量的写操作不会影响另一个指针变量的读操作。<br />
void func1(int * restrict a, int * restrict b)<br />
{<br />
/* func1&#8217;s code here */<br />
}</p>
<p>To help the compiler determine memory dependencies, you can qualify a pointer, reference, or array with the restrict keyword. The restrict keyword is a type qualifier that may be applied to pointers, references, and arrays. Its use represents a guarantee by the programmer that within the scope of the pointer declaration the object pointed to can be accessed only by that pointer. Any violation of this guarantee renders the program undefined. This practice helps the compiler optimize certain sections of code because aliasing information can be more easily determined.</p>
<p>In the example that follows, the restrict keyword is used to tell the compiler that the function func1 is never called with the pointers a and b pointing to objects that overlap in memory. You are promising that accesses through a and b will never conflict; this means that a write through one pointer cannot affect a read from any other pointer. The precise semantics of the restrict keyword are described in the 1999 version of the ISO C standard.</p>
<p>Use of the restrict type qualifier with pointers</p>
<p>void func1(int * restrict a, int * restrict b)<br />
{<br />
/* func1&#8217;s code here */<br />
}</p>
<p>This example illustrates using the restrict keyword when passing arrays to a function. Here, the arrays c and d should not overlap, nor should c and d point to the same array.<br />
Use of the restrict type qualifier with arrays</p>
<p>void func2(int c[restrict], int d[restrict])<br />
{<br />
int i;<br />
for(i = 0; i &lt; 64; i++)<br />
{<br />
c[i] += d[i];<br />
d[i] += 1;<br />
}<br />
}</p>
<p>下面的文字来自<a href="http://blog.sina.com.cn/u/1461433393" target="_blank">flybird</a>:</p>
<p>关键字restrict的使用可以通过下面两个程序来说明 。<br />
如下程序：两个均完成2个16位短型数据数组的矢量和</p>
<p>程序1:</p>
<p>void vecsum( short *sum, short *in1, short *in2, unsigned int N)<br />
{<br />
int i;<br />
for(i=0;i&lt;N;i++)<br />
sum[i]=in1[i]+in2[i];<br />
}</p>
<p>程序2:</p>
<p>void vecsum(short * restrict sum, restrict short * in1, restrict short * in2,unsigned int N)<br />
{<br />
int i;<br />
for (i=0;i&lt;N;i++)<br />
sum[i]=in1[i]+in2[i];<br />
}</p>
<p>编译器在编译程序1时，无法判断指针*sum与指针*in1,*in2是否独立。此时，编译器采取保守的办法，认为他们是相关的，即：认为*sum指向的存储区与*in1,in2指向的存储区可能混迭。这时编译出的代码必须执行完前一次写，然后才能开始下一次读取。在编译程序2的时候restrict表明指针*in1,*in2是独立的，*sum不会指向他们的存储区，因而可以并行进行多个数据的读取与求和。这两种程序编译出的代码执行速度相差极大。</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/05/14/dsp_restrict/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于MAP文件的一点认识</title>
		<link>http://ichaochao.com/2008/05/14/dsp_map/</link>
		<comments>http://ichaochao.com/2008/05/14/dsp_map/#comments</comments>
		<pubDate>Wed, 14 May 2008 05:24:44 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>

		<guid isPermaLink="false">http://blog.ichaochao.com/2008/05/14/%e5%85%b3%e4%ba%8emap%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%80%e7%82%b9%e8%ae%a4%e8%af%86/</guid>
		<description><![CDATA[转载自 hellodsp 论坛，作者: huttu
MAP文件是CCS软件编译后产生的有关DSP用到所有程序、数据及IO空间的一种映射文件。
一、生成方法
MAP文件主要有两种生成方法，一种是由系统自动生成，默认文件名为所建立的项目名（如XXX为项目名）加上.map后缀xxx.map，另一种在CMD文件中指定生成MAP文件，操作方法为在MEMORY指令前面加上“－m abc.map”，文件名可以任意。
二、文件格式
MAP文件大概分为文件头、内存配置、段映射、全局符号四部分。内存配置与CMD文件中的MEMORY指令关联，在CMD文件中定义的程序与数据区间定 义，在该部分均可以找到对应，与CMD文件不同的时，在MAP文件中加入了一个实际使用的区间，即在程序中实际用到的空间长度。段映射部分与CMD文件中 的SECTION指令关联，在该部分程序中所有的段实际映射的起始地址与实际长度均有详细说明。可以具体到程序中PROGMA指定的段和各个单独文件产生 的OBJ文件。全局符号可以是程序使用的每一个函数、程序中定义的全局变量均可以在此找到对应的起始地址。MAP文件中采用两种方式列举，一种为按相应地 址排列，另一种按全局符号字母排列。
三、存储地址
MAP文件默认保存在所在项目下面，由CMD文件产生的MAP文件保存在该项目的DEBUG目录下面。
]]></description>
			<content:encoded><![CDATA[<p>转载自 <a href="http://www.hellodsp.com/" target="_blank">hellodsp</a> 论坛，作者: huttu<br />
MAP文件是CCS软件编译后产生的有关DSP用到所有程序、数据及IO空间的一种映射文件。<span id="more-21"></span></p>
<p>一、生成方法<br />
MAP文件主要有两种生成方法，一种是由系统自动生成，默认文件名为所建立的项目名（如XXX为项目名）加上.map后缀xxx.map，另一种在CMD文件中指定生成MAP文件，操作方法为在MEMORY指令前面加上“－m abc.map”，文件名可以任意。</p>
<p>二、文件格式<br />
MAP文件大概分为文件头、内存配置、段映射、全局符号四部分。内存配置与CMD文件中的MEMORY指令关联，在CMD文件中定义的程序与数据区间定 义，在该部分均可以找到对应，与CMD文件不同的时，在MAP文件中加入了一个实际使用的区间，即在程序中实际用到的空间长度。段映射部分与CMD文件中 的SECTION指令关联，在该部分程序中所有的段实际映射的起始地址与实际长度均有详细说明。可以具体到程序中PROGMA指定的段和各个单独文件产生 的OBJ文件。全局符号可以是程序使用的每一个函数、程序中定义的全局变量均可以在此找到对应的起始地址。MAP文件中采用两种方式列举，一种为按相应地 址排列，另一种按全局符号字母排列。</p>
<p>三、存储地址<br />
MAP文件默认保存在所在项目下面，由CMD文件产生的MAP文件保存在该项目的DEBUG目录下面。</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/05/14/dsp_map/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
