EDN首页   博客首页

1

关于投票
【分析】STM32的代码,跑在RAM里快?还是跑在Flash里快?

这肯定是很多人关心的问题,下面通过一个例子看看会有什么样的结论:


测试手段如下:

主循环一直在做一个变量的自加(sum1++),当然前提保证不会溢出。

用Cortex-M3内部的Systick计数,以一秒钟为限,这个sum1的数值大小,可以判断哪种方式比较快。为了严密,我们观察第一秒到第二秒之间的计数效果;而不是从第0秒到第1秒(因为使能Systick到真正开始执行sum1++可能有间隙)。在第一次进入Systick的ISR时,记录下sum1的值;第二次进入Systick的ISR时,再次记录sum1的值,两次值之差即为一秒钟间隔中sum1执行了多少次自加。由此看出哪种方式比较快。

同样的测试前提:Prefetch Buffer Enable + Flash Latenty="2" (根据Flash Programming Manual中要求的那样,当48MHz<SYSCLK<=72MHz时,对flash的访问插入两个等待周期)


测试结果如下:
不对代码优化,在RAM中执行程序:sum1计数69467/秒
不对代码优化,在FLASH中执行程序:sum1计数43274/秒 (Flash里跑得慢)

/***********循环体内代码为N个以下的block*************/
(1)LDR R0,[PC, #0x154]
(2)LDR R1,[PC, #0x154]

(3)LDR R1,[R1,#0]
(4)ADDS R1, R1,#0x1

(5)STR R1,[R0, #0]

    ......
/****************************************************/

打开速度优化开关,在RAM中执行程序:sum1计数98993/秒
打开速度优化开关,在FLASH中执行程序:sum1计数115334/秒 (Flash里跑得快)

/***********循环体内代码为N个以下的block*************/
(1)LDR R1,[R1,#4]
(2)ADDS R1, R1,#0x1
(3)STR R1,[R0, #0]
    ......
/****************************************************/


结论就是:

1)程序运行在RAM里速度快还是运行在Flash里速度快,不是绝对的一概而论的,取决于代码;

2)就以上两种具体的代码情况来说,我觉得无优化时,如果在Flash里执行:(1)(2)的取指(读flash)->译码->执行(读flash);取指和执行阶段flash的目标地址不是连续的,因此是non-sequencial access,所以会很慢;
打开优化时,(1)(2)(3)都不会造成flash的non-sequential access,所以在flash里的优势(取指和取数据走不同的总线ICode和DCode以及Prefetch)就体现出来了。


再进一步的分析,又有这样一些结论:

没有优化时,指令执行时要到Flash中取常数,结果造成指令预取队列的取指中断,取完常数后需要重新填充指令预取队列,而Flash访问需要插入等待周期,当然时间就比较长了。

经过代码优化后,指令执行时不用再到Flash中取常数,指令预取队列不会被打断,而Flash访问需要插入等待周期的效应被下面贴子中介绍的取指缓冲区抵消,所以自然速度就快了;而这个时候在RAM中执行反而慢了是因为RAM不在ICode总线上,从RAM取指需要绕一圈,当然要比在ICode总线上的Flash慢了。

关于Flash的性能,请看我的另一篇分析:【分析】STM32从Flash中运行程序的时序分析


另外,STR9与STM32的总线架构是一样的,这里有一个在STR9上实现的FFT函数的实测数据,可以进一步说明在Flash中运行代码可以比在RAM中快!

在ST的网站上有一个DSP的函数库,这是它的文档《STR91x DSP library (DSPLIB)》,在这篇文档中有一节讨论FFT运算速度的,那里给出了实际的运算时间比较,摘录如下:

Radix-4
Complex FFT
Operation Mode Cycle Count Microseconds
64 Point Program in Flash & Data in SRAM 2701 28.135
64 Point Program & Data in SRAM 3432 35.75
64 Point Program & Data in Flash 3705 38.594
256 Point Program in Flash & Data in SRAM 13740 143.125
256 Point Program & Data in SRAM 18079 188.323
256 Point Program & Data in Flash 19908 207.375

系统分类: 单片机
用户分类: 性能分析
标签: STM32 运行速度 Flash
来源: 原创
发表评论 阅读全文(224) | 回复(0)

2

关于投票
关于使用STM32的USART模块实现Modbus协议的讨论
香水城 发表于 2008-6-12 10:49 ST MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

楼主: 请教Modbus高手makesoft:实现Modbus协议一定需要超时检测吗?

首先声明,我对Modbus不熟悉,尤其是如何实现它,最近才从网上下载了协议研究了一下,特此向高手请教。搞清楚这些问题,才能有效地在芯片中实现相应的功能,满足大家的需要。

此帖的目的是继续另一帖的讨论:建议STM32的芯片加上串口超时功能,很好用的一个功能


这里是我的实现描述:
Modbus的请求数据包都是由下面几部分构成:
一、从机地址;固定为一个字节
二、功能代码;固定为一个字节
三、功能参数;长度依不同功能代码而不同
四、数据域;长度在功能参数中定义
五、校验码;固定为两个字节

下面以功能代码=0x03的数据包交换说明如何使用STM32进行数据传送:
1、主机发送8字节:
  从机地址:  1字节
  功能代码:  1字节 = 0x03
  起始地址:  2字节
  读取数目:  2字节 = N
  CRC校验码: 2字节
2、从机先接收2字节,当得知功能代码为0x03时,再继续接收6个字节
3、从机发送 N*2+4字节 = (1字节功能码+1字节数据长度+N*2字节数据+2字节校验码)
4、主机接收从机发出的(N*2+4)字节数据。因为主机知道N的数值,所以主机知道从机响应的数据包的长度

这里可以看到,如果没有FIFO,需要在上述第2阶段从机接收主机请求时分为两个步骤进行;而在其他的阶段使用DMA的效率不比使用FIFO差,而且在第4阶段,如果数据包长度大于FIFO深度时,使用DMA的效率更高!



根据我的理解,Modbus协议是主从结构,即主机发送请求给从机,从机收到请求后根据要求返回主机需要的数据或状态。主机的发送和接收都是主动的,它随时知道发送或接收数据的长度;而从机的发送是被动的,只有在接收到主机的请求后才能发送指定的数据或状态。

因此,主机没有必要通过超时检测来判断帧的开始和结束。对于从机讲,在接收第一个请求帧时,它一定知道帧的开始,同时根据我上面描述的步骤,它也可以很容易的知道帧的结束。既然可以判断出第一个帧的开始和结束,那么随后的帧就不难区分了。

所以,我希望makesoft能够对你的注解(“关键是你没有延时无法判断什么时候是一个帧的开始和结束”)加以解释,“延时判断”真的很关键吗?谢谢!

签名:


makesoft 发表于 2008-6-12 11:00 ST MCU ←返回版面