20200708 昨天突然发现 Systick这个定时器不大好用了,慢了不少。
但是串口和以太网都好用,所以这些天没发现这个问题。把mbed启动过程屏蔽了就好用了。
发现是是SystemCoreClock这个值 由168000000变为成了0x20000000,
那么什么时候变得呢?断点发现是在__user_setup_stackheap里面变的。这个值估计就是成了ram的起始地址了。
找了一下网上,发现了香水城的帖子 《【实战经验】使用mbed 进行STM32 开发及STM32F0的时钟问题》,
另注:我一直认为香水城是ST推广成功最大功臣。只要他的帖子肯定是正确且有价值的。
他帖子是关于F0的,我遇到的是F4,
并且帖子里的和我遇到的完全不一样,我遇到的是栈的最高地址的值(SystemCoreClock)变了。
所以我想了个绝妙的办法,弄个临时变量放在寄存器里倒腾一把,
uint32_t temp = SystemCoreClock;
__user_setup_stackheap();
SystemCoreClock = temp;
反汇编如下:
0x08074532 4807 LDR r0,[pc,#28] ; @0x08074550
0x08074534 6804 LDR r4,[r0,#0x00]
...........................
0x0807453E 4804 LDR r0,[pc,#16] ; @0x08074550
0x08074540 6004 STR r4,[r0,#0x00]
这样的话代码改动比较小,就是system_stm32f4xx.c一点不用动。
当然还有2种方法,就是 把SystemCoreClock弄成个const,这样就放在了code区域,当然需要把这个函数SystemCoreClockUpdate屏蔽掉。
还有3种方法就是把变量SystemCoreClock别放在system_stm32f4xx.c外面,或者把变量SystemCoreClock与变量AHBPrescTable交换个位置(就是先定义AHBPrescTable)。
后两种方法我没试过。
总而言之,看下map文件,反汇编,就能得到相对正确的做法。