achild 发表于 2024-2-26 11:59:13

stm32代码量影响函数调用速度吗?

问题为——
        Gd32f450使用定时器做2us级别的延时误差到了5us。
情况是这样的——
        用Gd32f450在调DS18b20温度传感器。问题出现在延时函数。我用了定时器来做延时函数。定时器通过先清零,再查询的方式做延时。
        然后我发现2us的延时来控制io的反转时。示波器显示延时竟然为5us。
问题分析——
        因为我在调用延时函数时都是先进入临界区的。所以应该并不会被外部中断打断。而定时器的执行速度应该也不会受其他因素影响。
        所以我只能怀疑是调用delay函数,调用hal库函数来做定时器清零,查询,等操作时因为函数调用速度过慢带来的延时,这也是我疑惑的地方。
        随后我发现空的工程里面,delay函数是正常的。于是我把原来工程中的任务都屏蔽掉,delay函数确实是正常的。
        这里我怀疑过是不是进入临界区没什么作用,还是被任务执行干扰了。
        于是我把温度读取这部分代码直接放在硬件初始化之后,循环读取,此时其他任务还没有机会启动。但是此时delay依旧不正常。
        所以问题就定位在了,代码量大的时候,函数调用速度变慢了。

        所以现在我也不确定问题定位是不是准确,有没有大佬有思路的?
       

1a2b3c 发表于 2024-2-26 12:04:04

如果你会汇编就看下汇编代码,哪些地方不必要的操作了
不会的话就看下汇编代码量,两种情况下的代码量是不是一样的就知道了,

gaolf_2012 发表于 2024-2-26 12:12:09

看使用手册2.2"MCU执行指令零等待区域最大支持到1024K字节空间(在闪存大小等于256K或512K时,
闪存全片执行指令零等待);在此范围外,CPU读取指令存在较长延时"

t3486784401 发表于 2024-2-26 13:00:46

所有的中断都套上临界区进出吗?

先设法测试吧,看样子就是某个中断遗漏了

Nuker 发表于 2024-2-26 15:24:43

GD32不是STM32

yuyu87 发表于 2024-2-26 16:34:48

gd32的,某些芯片,超过512KB后,是在另一个区域,速度会大幅变慢。

MAD_FISH 发表于 2024-2-26 16:36:14

flash分了程序块和数据块,速度不一样,代码量大时,部分代码存到了数据块中,运行速度慢,这是兆易的片子特点

1a2b3c 发表于 2024-2-26 17:19:59

楼上几位是哦芯片flash问题的我觉得搞错了,退一步说,即使速度慢十倍,楼主的延迟函数是使能定时器后死等定时标志,那么里面能有几条指令?理论上就一条判断标志,一条跳转(条转到再次判断或者跳出循环),那么撑死了5条左右而已。这几条指令就算一条指令要0.1us(此时不知道系统时钟多慢了),那么执行下来就算10条也就1us,和楼主的差了5us简直是天壤之别啊……
因为楼主并不是去执行了一大堆代码导致总的时间变大了,而是永远都是执行的那几条判断代码而已,

achild 发表于 2024-2-26 18:44:04

yuyu87 发表于 2024-2-26 16:34
gd32的,某些芯片,超过512KB后,是在另一个区域,速度会大幅变慢。
(引用自6楼)

应该是这样了,我程序确实600多K,在屏蔽了两个比较大的函数后,代码降低下来,所有时序都对了。
这两个函数是一堆数据计算相关的函数,并没有中断的操作。测试过程中也不会触发执行。所以并不会直接干扰执行。
有个现象也能对上,DS18b20驱动里面需要把IO从输出配置为输入。这个部分需要执行HAL_GPIO_Init函数,这里面有一大段代码。这个地方的时序错误也最明显。
谢谢了,知道了问题在哪,那就有办法处理了。

jianfengxixi 发表于 2024-2-26 18:48:52

进入临界区具体是怎么回事,可能中断没关?不如直接关中断试试。。。

why800 发表于 2024-2-26 18:51:05

gd的flas是spi的,很慢,超级慢。他用ram模拟flash,芯片启动要加载一部分内容到ram,这部分就比较快。而没有加载到ram的内容,就很慢,这就是手册的两种速度了。可以 在编译代码的时候,指定一下函数存放的地址,靠前放,看看能不能解决。

camtime 发表于 2024-2-27 08:55:30

GD32超过512KB后,会变慢
STM32也会这吗?

achild 发表于 2024-2-27 16:16:11

结贴,用了__attribute__((section(".xxx"))) 修饰相关函数,并把.xxx在.ld文件中最先连接到FLASH。延时问题完美解决。
谢谢各位大佬的指导。

fcm32 发表于 2024-2-28 12:15:11

1a2b3c 发表于 2024-2-26 17:19
楼上几位是哦芯片flash问题的我觉得搞错了,退一步说,即使速度慢十倍,楼主的延迟函数是使能定时器后死等 ...
(引用自8楼)

楼上几位没有搞错。如果在SPI flash里,就算你只有一条指令,它也慢,一个时钟只能取4个位,32位地址+32位指令,就64个位,需要耗费16个时钟,而且它还是个函数,要跳过去,几条指令一跑,就很慢了

887799 发表于 2024-2-28 15:07:16

fcm32 发表于 2024-2-28 12:15
楼上几位没有搞错。如果在SPI flash里,就算你只有一条指令,它也慢,一个时钟只能取4个位,32位地址+32 ...
(引用自14楼)

请教,其它的类似STM32 的国产MCU 是否有这个毛病?

fcm32 发表于 2024-2-29 17:43:53

887799 发表于 2024-2-28 15:07
请教,其它的类似STM32 的国产MCU 是否有这个毛病?
(引用自15楼)

看手册,大部分有0等待FLASH的,都是使用SPI FLASH+SRAM结构,就会有这个问题。

tomzbj 发表于 2024-3-1 11:27:04

看图, GD32的话, 红框范围内零等待, 出了这个范围就慢了, 可能会慢两三个数量级.

解决办法也简单, 几百k的话多半是有字库/图片之类大容量资源吧, 不至于全是程序吧? 手动指定这些东西放在靠后的位置, 保证程序都在前面, 就解决了.

个人建议在Makefile/编译脚本之类场合把flash容量设定为只有前面的部分,字库图片之类资源单独处理。

SCREA 发表于 2024-3-5 16:09:25

本帖最后由 SCREA 于 2024-3-5 16:11 编辑

代码放到RAM试试。
确定FLash是0等待吧?
运行到额定最高频率200Mhz。
只留当前使用的中断。
再试试,望对比出差异
===========
还真是合封NorFlash的问题,好帖。
页: [1]
查看完整版本: stm32代码量影响函数调用速度吗?