STM32的函数调用宇宙到底有多大大的开销

21ic官方微信-->
后使用快捷导航没有帐号?
查看: 2799|回复: 7
请教: STM32的函数调用到底有多大的开销?
&&已结帖(0)
主题帖子积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
主题帖子积分
专家等级:结帖率:83%
主题帖子积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
平台:&IAR5.30&ST-LINK&使用3IN1的板子和STM32的FWLIB.系统工作于72MHz下,初始化GPIO速度为50MHz,没有开任何的中断.while&(1){&&&&//GPIO_LED-&gtBSRR&=&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8;&&&&GPIO_SetBits(GPIO_LED,&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8);&&&&Delay(500);&&&&&&&&&&&&&//GPIO_LED-&gtBRR&=&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8;&&&&&GPIO_ResetBits(GPIO_LED,&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8);&&&&&Delay(500);}这样的话,在示波器上测量到的(一个翻转)时间间隔为91uSwhile&(1){&&&&GPIO_LED-&gtBSRR&=&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8;&&&&//GPIO_SetBits(GPIO_LED,&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8);&&&&Delay(500);&&&&&&&&&&&&&GPIO_LED-&gtBRR&=&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8;&&&&&//GPIO_ResetBits(GPIO_LED,&GPIO_Pin_6&|&GPIO_Pin_7&|&GPIO_Pin_8);&&&&&Delay(500);}如果直接操作寄存器的话,则只需要84uS,足足有7个uS的差别,可是查看FWLIB中的GPIO_SetBits和GPIO_ResetBits却很简单的也只是操作了寄存器而已,难道STM32的函数调用开销有这么大,还是有一些另外的开销在里面呢?
主题帖子积分
主题帖子积分
专家等级:结帖率:37%打赏:0.00受赏:9.00
主题帖子积分
楼主可以看看反汇编代码
再对照Cortex-M3的手册察看指令的运行时间。
主题帖子积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
主题帖子积分
专家等级:结帖率:83%
主题帖子积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
谢谢!但还是有不解的地方
首先很感谢版主很及时的回贴!我特意去查看了汇编代码,没有发现有很大的开销在哪里,就是多了一条参数压栈,跳转指令和返回指令属于多余的开销没有其他的不同.但是为什么会有7个uS的差别呢?7uS在72MHz的主频下应该有好几百条指令的时间才对啊!难道CORTEX-M3也会有函数调用时发生页面切换的开销吗?&
主题帖子积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
多了很多操作的!
需要传递两个参数,&需要压5个寄存器栈,&调用,&执行,弹栈,返回而用寄存器时只有执行这个过程!
主题帖子积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
ST的Lib大可有选择的使用
对于资源占用很小的模块,且速度要求不高,尽量用Lib吧,开发效率和可维护性对于要求资源占用和速度敏感的模块,尽量自己coding吧,自己知根知底在Link的时候,链接器会自动抓取user所使用的Lib而不是抓整个Lib整体而言,STM32的Lib稳定性和可以移植性还是不错的,但某些函数的效率确实偏低,这也是代码通用性带来的弊病之一吧,两者的折中有要有个平衡点。
主题帖子积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
提示: 作者被禁止或删除 内容自动屏蔽
主题帖子积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
主题帖子积分
专家等级:结帖率:83%
主题帖子积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
助理工程师, 积分 1237, 距离下一级还需 763 积分
其实这个跟库无关的
看来没有人真正关心这个问题,&这个问题我觉得根本就不是库的效率问题,因为库里面只是用了一个函数封装一下而已,并没有做其他的什么事情.而这样,却产生很大的调用开销,我觉得是不是STM32(或者说CORTEX&M3)在进行函数调用时会产生很多的不能受控的附加开销!
主题帖子积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
助理工程师, 积分 1991, 距离下一级还需 9 积分
楼上说的对,函数调用会产生较大的开销,,从指令上来看的话,调用函数的指令数更多,更致命的是,还要清空流水线,这也是额外的开销呀,返回的时候也要清流水线..函数里面的东西越少,相对来讲效率肯定是很低的..
社区建设奖章
等级类勋章
涓涓之细流
发帖类勋章
时间类勋章
技术奇才奖章
人才类勋章
荣誉元老奖章
等级类勋章
坚毅之洋流
发帖类勋章
时间类勋章
技术领袖奖章
人才类勋章
湍急之河流
发帖类勋章
时间类勋章
技术导师奖章
人才类勋章
核心会员奖章
等级类勋章
技术高手奖章
人才类勋章
时间类勋章函数调用会带来多少开销?
[问题点数:100分,结帖人kangnixi]
函数调用会带来多少开销?
[问题点数:100分,结帖人kangnixi]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2015年1月 C/C++大版内专家分月排行榜第二2012年3月 C/C++大版内专家分月排行榜第二2011年11月 C/C++大版内专家分月排行榜第二2010年6月 C/C++大版内专家分月排行榜第二2010年5月 C/C++大版内专家分月排行榜第二
2011年4月 C/C++大版内专家分月排行榜第三2011年2月 C/C++大版内专家分月排行榜第三2010年8月 C/C++大版内专家分月排行榜第三
2010年5月 C/C++大版内专家分月排行榜第三2010年3月 C/C++大版内专家分月排行榜第三2010年1月 C/C++大版内专家分月排行榜第三
2007年9月 C/C++大版内专家分月排行榜第三2007年8月 C/C++大版内专家分月排行榜第三2006年11月 C/C++大版内专家分月排行榜第三
2012年11月 挨踢职涯大版内专家分月排行榜第二2011年9月 Linux/Unix社区大版内专家分月排行榜第二
2012年1月 Linux/Unix社区大版内专家分月排行榜第三2011年8月 C/C++大版内专家分月排行榜第三2011年8月 Linux/Unix社区大版内专家分月排行榜第三2010年4月 C/C++大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2008年3月 Linux/Unix社区大版内专家分月排行榜第二
2012年9月 Linux/Unix社区大版内专家分月排行榜第三2007年6月 Linux/Unix社区大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。stm32 printf函数调用
stm32 printf函数调用
STM32串口通信中使用printf发送数据配置方法(开发环境 Keil RVMDK)
【详细说明】STM32串口通信中使用printf发送数据配置方法(开发环境 Keil RVMDK)在STM32串口通信程序中使用printf发送数据,非常的方便。可在刚开始使用的时候总是遇到问题,下面就说一下使用printf需要做哪些配置。有两种配置方法:一、对工程属性进行配置,详细步骤如下1、首先要在你的main 文件中 包含“stdio.h” (标准输入输出头文件)。2、在main文件中重定义&fputc&函数& & 如下:& &int fputc(int ch, FILE *f)& &{& && &USART_SendData(USART1, (unsigned char) ch);// USART1 可以换成 USART2 等& && &while (!(USART1-&SR & USART_FLAG_TXE));& && &return (ch);& &}& &这样在使用printf时就会调用自定义的fputc函数,来发送字符。3、在工程属性的 “Target" -& "Code Generation" 选项中勾选 "Use MicroLIB"”&& &MicroLIB 是缺省C的备份库,关于它可以到网上查找详细资料。至此完成配置,在工程中可以随意使用printf向串口发送数据了。二、第二种方法是在工程中添加“Regtarge.c”文件1、在工程中创建一个文件保存为 Regtarge.c , 然后将其添加工程中在文件中输入如下内容(直接复制即可)#include &stdio.h&#include &rt_misc.h&#pragma import(__use_no_semihosting_swi)extern int&&SendChar(int ch); // 声明外部函数,在main文件中定义extern int&&GetKey(void);struct __FILE {&&& && && && && &&&// Add whatever you need here&};FILE __FILE __int fputc(int ch, FILE *f) {&&return (SendChar(ch));}int fgetc(FILE *f) {&&return (SendChar(GetKey()));}void _ttywrch(int ch) {SendChar (ch);}int ferror(FILE *f) {& && && && && && && && && & // Your implementation of ferror&&return EOF;}void _sys_exit(int return_code) {label:&&& && && &&&// endless loop}2、在main文件中添加定义以下两个函数int SendChar (int ch)&&{&&while (!(USART1-&SR & USART_FLAG_TXE)); // USART1 可换成你程序中通信的串口&&USART1-&DR = (ch & 0x1FF);&&return (ch);}int GetKey (void)&&{&&while (!(USART1-&SR & USART_FLAG_RXNE));&&return ((int)(USART1-&DR & 0x1FF));}3、 至此完成配置,可以在main文件中随意使用 printf 。
发表评论:
TA的最新馆藏[转]&STM32&printf函数详解
本实验所用的硬件:STM32F103RTB6
实验所用的晶振: 8M
实验所用的ST官方库:3.5版
C语言中的标准库中所用的标准输出函数,默认的输出设备是显示器,要实现串口或LCD的输出,必须重新定义标准库函数里与输出函数相关的函数。
1.下面首先介绍怎么根据官方3.5库里面的标准例程“printf”修改成自己的“printf”工程:
下边是官方提供的例程:
//Includes
------------------------------------------------------------------
#include "stm32f10x.h"
#include "stm32_eval.h"
#include &stdio.h&
//&@addtogroup
STM32F10x_StdPeriph_Examples
//@addtogroup USART_Printf
//&Private typedef
-----------------------------------------------------------
//&Private define
------------------------------------------------------------
//&Private macro
-------------------------------------------------------------
//&Private variables
---------------------------------------------------------
USART_InitTypeDef USART_InitS
//Private function prototypes
-----------------------------------------------
#ifdef __GNUC__
& //With GCC/RAISONANCE, small printf (option LD
Linker-&Libraries-&Small printf
set to 'Yes') calls __io_putchar() */
& #define PUTCHAR_PROTOTYPE int __io_putchar(int
& #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE
// Private functions
---------------------------------------------------------
&// @brief& Main program
&//@param& None
&//@retval None
int main(void)
&& //&At this
stage the microcontroller clock setting is already
configured,&
&&&//&this
is done through SystemInit() function which is called from
&&&//&file
(startup_stm32f10x_xx.s) before to branch to application
reconfigure the default setting of SystemInit() function, refer
&&&//system_stm32f10x.c
& //USARTx configured as follow:
- BaudRate = 115200 baud&&
- Word Length = 8 Bits
- One Stop Bit
- No parity
&&//& - Hardware
flow control disabled (RTS and CTS signals)
&&//& - Receive
and transmit enabled
& USART_InitStructure.USART_BaudRate =
& USART_InitStructure.USART_WordLength =
USART_WordLength_8b;
& USART_InitStructure.USART_StopBits =
USART_StopBits_1;
& USART_InitStructure.USART_Parity =
USART_Parity_No;
& USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_N
& USART_InitStructure.USART_Mode = USART_Mode_Rx |
USART_Mode_Tx;
& STM_EVAL_COMInit(COM1,
&USART_InitStructure);
&&// Output a message on
Hyperterminal using printf function&
& printf("\n\rUSART Printf Example: retarget the C
library printf function to the USART\n\r");
& while (1)
&&// @brief&
Retargets the C library printf function to the USART.
&&// @param&
& //@retval None
PUTCHAR_PROTOTYPE
&&// Place your implementation of
fputc here
&&// e.g. write a character to
the USART&
& USART_SendData(EVAL_COM1, (uint8_t) ch);
&&// Loop until the end of
transmission&
& while (USART_GetFlagStatus(EVAL_COM1,
USART_FLAG_TC) == RESET)
#ifdef& USE_FULL_ASSERT
& //@brief& Reports the
name of the source file and the source line number
&&//&&&&&&&
where the assert_param error has occurred.
& //@param& file: pointer
to the source file name
&&// @param&
line: assert_param error line source number
&&// @retval None
void assert_failed(uint8_t* file, uint32_t line)
& //User can add his own implementation to report
the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file,
& // Infinite loop */
& while (1)
上边用红色字体标记出来的,表示是要修改的,首先#include
"stm32_eval.h"是官方提供的测试板上的头文件,而咱们要移植到自己的实验板上,所以不能用,负责编译肯定出错误,在这里直接屏蔽就行了。STM_EVAL_COMInit(COM1,
&USART_InitStructure);这个函数是官方为测试板写的一个标准初始化串口的函数,所以咱们也不能用,当然你可以把这个函数复制到自己的main函数里,加以修改,这样配置起串口也就相对方便了,在这里咱们就不这样做了。因为咱们是自己新建工程,所以不能调用官方测试板的初始化串口的函数,所以必须重新写一个函数,按下面的方法进行:
& USART_InitStructure.USART_BaudRate =
& USART_InitStructure.USART_WordLength =
USART_WordLength_8b;
& USART_InitStructure.USART_StopBits =
USART_StopBits_1;
& USART_InitStructure.USART_Parity =
USART_Parity_No;
& USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_N
& USART_InitStructure.USART_Mode = USART_Mode_Rx |
USART_Mode_Tx;
& STM_EVAL_COMInit(COM1,
&USART_InitStructure);
这是标准例程里的,它实现了串口的初始化,下边是我自己写的函数,也是初始化串口,所以用下面的函数替换上面的函数就ok了,函数为:
&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,
&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
&GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//推挽输出-TX
&GPIO_Init(GPIOA,&GPIO_InitStructure);
&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
&GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_IN_FLOATING;//浮空输入-RX
&GPIO_Init(GPIOA,
&GPIO_InitStructure);
&USART_InitStructure.USART_BaudRate =
&USART_InitStructure.USART_WordLength =
USART_WordLength_8b;
&USART_InitStructure.USART_StopBits =
USART_StopBits_1;
&USART_InitStructure.USART_Parity =
USART_Parity_No;
&USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_N
&USART_InitStructure.USART_Mode = USART_Mode_Rx |
USART_Mode_Tx;
&USART_Init(USART1,
&USART_InitStructure);
&USART_Cmd(USART1, ENABLE);
上面程序就完成了对stm32f103rbt6串口1的初始化。
接下来就是对USART_SendData(EVAL_COM1, (uint8_t) ch),while
(USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) ==
RESET)这两个函数的修改,其中EVAL_COM1是官方为自己的测试板写的库函数定义的USART1,所以这里咱们直接用USATT1替换EVAL_COM1就行了,做完这些后编译整个工程,整个工程就可以编译过去了,不会出现错误,接下来的任务就是下载到实验板上做测试了。
2.下载到自己的实验板上,做测试
根据上面的修改,工程编译过去了,也没有出现任何错误,但下载到实验板上后,发现printf函数根本打印不出来想要打印出来的信息,后来我把所有的printf函数都屏蔽了,然后自己调用USART_SendData()这个函数,看到底是配置有问题还是其他问题,结果在串口调试助手里正常的打印出了想要的字符,到这里,大家应该都能猜到不是程序的问题,而是软件的配置问题,经过在网上的各种搜索后终于找到了答案。的确是配置问题,打开keil软件的target
看到上面用红线标出来的位置了吧,默认情况下,keil软件是没有把Use
MicroLIB这个选项勾上的,咱们修改的程序之所以没有打印出东西,就是应该勾上这个选项,勾上后,在进行一次编译,然后下载到实验板上,一切就正确了。
3.对标准printf函数的修改如下:
//&Private function prototypes
-----------------------------------------------
#ifdef __GNUC__
&&// With GCC/RAISONANCE, small
printf (option LD
Linker-&Libraries-&Small printf
set to 'Yes') calls __io_putchar() */
& #define PUTCHAR_PROTOTYPE int __io_putchar(int
& #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE
#endif // __GNUC__&
&// @brief& Retargets the C
library printf function to the USART.
&//@param& None
&// @retval None
PUTCHAR_PROTOTYPE
& //Place your implementation of fputc here
& // e.g. write a character to the
& USART_SendData(USART1, (uint8_t) ch);
& // Loop until the end of transmission
& while (USART_GetFlagStatus(USART1,
USART_FLAG_TC) == RESET)
这一段函数就是把printf函数输出到串口,需要将fputc输出给串口,也就是重新定义。
以上就是对printf函数在调试STM32配置成串口printf函数的这个过程,希望对大家有所帮助!
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。STM32函数库的调用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
STM32函数库的调用
上传于||文档简介
&&S​T​M2​初​学​者​非​常​有​用​,​可​以​直​接​调​用​,​有​某​些​只​需​要​改​改​就​可​以​用​了
阅读已结束,如果下载本文需要使用2下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 染发的危害到底有多大 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信