[AT32L021] 【AT-START-L021测评】2--perf_counter

[复制链接]
 楼主| [鑫森淼焱垚] 发表于 2024-12-26 19:09 | 显示全部楼层 |阅读模式

1 perf_counter 简介
为Cortex-M Systick提供专用的性能计数器。它与用户原始SysTick功能共享SysTick,而不会干扰它们。该库将带来新的功能,例如性能计数器、delay_us和clock()服务定义在time.h中。

仓库地址如下: https://github.com/GorgonMeducer/perf_counter

2 移植 perf_counter

2.1 新建工程
以之前的工程 at32l021_blinky 工程为模板,复制一份,重名为 at32l021_coremark。
f83b8aa7847f9d3debdd021627e7ca35
2.1.1 添加 Debug 配置
删除原来的 Debug 配置,重新添加一个 at32l021_coremark 配置,如下所示,切记要勾选 WinUSB
78599cce6fadad294e819f39002ab6a2

2.2 添加 perf_counter 到工程
在工程目录新建一个 3rd_party 目录,并拷贝 perf_counter 源码到 3rd_party 目录下,然后在 AT32IDE 中刷新一下工程,就可以看到新加入的 perf_counter 源码。
f3c4b52ba6aedbe05ce19ab6875729e0

2.3 排除无需使用的文件
perf_counter 目录下的 example 文件夹下的所有文件显然不需要加入编译,右键点击此文件夹,然后再弹出的菜单中选择 Properties ,修改其属性。
fc1920f1a2a09166690d2794f8f82519
选择 C/C++ Build 然后勾选 Exclude resource from Build。
549997b69a91840c06bce5ba7eb2ecec
注意,考虑到 Debug/Release 两个配置都需要排除这个文件夹,所以也需要选择配置为 All configurations。
6cb00159b5c2447b166d80bfb31a3e3b
最终排除了如下文件和文件夹:
  • 3rd_party/perf_counter/benchmark/coremark/barebones
  • 3rd_party/perf_counter/benchmark/coremark/freebsd
  • 3rd_party/perf_counter/benchmark/coremark/linux
  • 3rd_party/perf_counter/benchmark/coremark/macos
  • 3rd_party/perf_counter/benchmark/coremark/posix
  • 3rd_party/perf_counter/benchmark/coremark/rtems
  • 3rd_party/perf_counter/benchmark/coremark/simple
  • 3rd_party/perf_counter/benchmark/coremark/zephyr
  • 3rd_party/perf_counter/benchmark/coremark/core_main.c
  • 3rd_party/perf_counter/example
  • 3rd_party/perf_counter/os
  • 3rd_party/perf_counter/template
  • 3rd_party/perf_counter/systick_wrapper_gnu.s
  • 3rd_party/perf_counter/systick_wrapper_ual.s


2.4 编译报错 coremark.h 文件找不到
在排除了不需要的文件之后,编译工程,提示 coremark.h 文件找不到。
cc8c7522230c182950c085727e4745a4
显示这是头文件路径没有找到,按如下方式添加 perf_counter 需要的头文件路径:
切记,这里修改 All configurations 配置,一下子实现 Debug/Release 两个配置,都增加了如下的3个头文件搜索路径。
97d045fd9db403071765e91566ae70e0

2.5 编译报错,__cycleof__() 需要开启 GNU 扩展
495d4f430b0cd8f5f3918755439560d3
按照如下步骤,修改编译器语言标准为 gnu99
19132ec22bf98bd42e91e6997d8a4afc

2.6 coremark_main() 函数报错
这个函数有几个版本,最终选用perf_counter.h 定义的版本,它的原型如下,返回值和入口参数都是 void 类型。但是其他的版本入口参数不是 void 类型。
8bbca77b1ce7c7a32080c801847d276a
解决办法如下,新增两个宏定义,分别是 MAIN_HAS_NOARG=1 和 MAIN_HAS_NORETURN。配置方法如下
d236cb08ef84ece13440db7be5bef337

2.7 汇编文件 systick_wrapper_gnu.s 报错
26b4367db740d5a7471e8422135c5e4d
当前是GCC编译器,排除两个汇编文件,分别是
systick_wrapper_gnu.s
systick_wrapper_ual.s

2.8 delay_us() 和 delay_ms() 两个函数重复定义
因为 perf_counter 已经提供了这两个函数,但是 at32l021_board.c 也提供了这两个函数的实现,所以重复了。
9fddb69aee971643e9158a9f2f26f2dd
f13d1ad9d8352dd87f4b89aa693d5507
这里推荐使用 perf_counter 的延时函数版本,因为更通用、更精准。
解决办法是屏蔽 at32l021_board.c 中这两个函数的实现,用 #if 0 括住这两个函数即可。

2.9 编译报错 SystemCoreClork 变量未定义
perf_counter 计时需要使用这个全局变量,它需要精准的表示CPU时钟频率。
1669985b5ca4c0cb29e44adf3a7a7581
显然当前 AT32L021 BSP没有定义这个变量,而是在 cmsis/system_at32l021.c 文件中定义了一个 system_core_clock 变量,它的作用就是 SystemCoreClock 。奈何 AT32 标新立异,取了一个和 CMSIS 标准不同的变量名。
d9e319763076b37e10999a4e29493fb9
解决办法是新增一个变量 SystemCoreClock,并且及时更新此变量的值。
aceb2ac037bd78c103c906fa724dd7ff
在函数 system_core_clock_update() 尾部更新 SystemCoreClock 变量的值。
2a17e843f27194f7b42d85679e43a832
此外编译还是报错,因为 AT32 BSP又有如下的奇葩宏定义,注释这个宏定义即可。
6f99c3a1bc1c64a8a7dd7ac40b5ae706

2.10 编译通过
8e0463fc5baf720b3f7d3e6afe63c309

3 解决 perf_counter 调用时的编译报错
在 main.c 头部引入 perf_counter.h 头文件,然后加入下面的代码,初始化 perf_counter,并测量 LED2 翻转一次耗费了多少个时钟周期。
aff991db8adea5503d266cc220aee335
这里 init_cycle_counter(false) 表示让 perf_counter 接管 SysTick ,那么 at32_board_init() 函数中就不需要初始 SysTick 了,修改如下:
f8419ea96b88c101af2dee05e548ff4f
同时把 at32l021_board.c 中三个 `delay_xxx()` 函数都屏蔽,同时 at32l021_board.h 中的函数声明也屏蔽。
最后还需要在 SysTick_Handler() 中增加一行函数调用,如下图所示:
da67347b69ca691ca7037dec2e995461

4 测试 LED4 翻转速度
最后修改测试代码,在 main_loop() 中使用如下代码测试 LED4 的翻转占用的时钟周期数。
9237f6e56d37e4ad2743cf95daa70214
运行结果如下,可知 LED4 翻转一次占用的时钟周期数大约是 62~72 个时钟周期。
5fb45e340c33d6ea373d012deca9cb00

4.1 Release 版本运行对比
把工程 Debug 配置复制一份,重命名为 Release,如下图所示:
426f2d9fe18256d956190c404fce1669
然后修改工程 Release 版本编译选项,优化等级修改为 -Ofast
a469328209deb8ce8913e65f51b4ed07
Release 版本的程序运行结果
a3a19e6301f7d25de1cdf89db26a9280
可以看到 Release 版本的 LED4 翻转速度在13个时钟周期,而 Debug 版本的时钟周期是62个,速度快了约5倍。

闪烁阴影 发表于 2025-1-21 10:57 | 显示全部楼层
perf_counter和以前用的SysTick的delay有啥区别不
 楼主| [鑫森淼焱垚] 发表于 2025-1-23 19:02 | 显示全部楼层
闪烁阴影 发表于 2025-1-21 10:57
perf_counter和以前用的SysTick的delay有啥区别不

perf_counter 使用了 SysTick 中断而不单独占用,此外如果用了 RTOS,perf_counter 只需要注意初始化参数,不需要过多修改代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

127

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部