assembly - 使用 CMake 构建 STM32 固件时的中断处理
问题描述
我调试用 CMake 创建的 STM32 项目。它使用 HAL 库,一开始我配置了 HAL 和 SysTick。
root/
├─ core/
│ ├─ core.c
│ ├─ core.h
│ ├─ stm32g4xx_it.c
│ ├─ stm32g4xx_it.h
│ ├─ CMakeLists
├─ main.c
├─ startup.s
├─ CMakeLists.txt
startup.s
文件包含弱SysTick_Handler,如下:
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
stm32g4xx_it.c
还包含SysTick_Handler
覆盖弱声明的内容。问题是当编译、链接和加载应用程序时,如上所示,SysTick 中断以Default_Handler
. 如果我从文件中删除弱声明startup.s
,那么它可以正常工作并执行正确的处理函数。我认为这是 cmake 工作方式的结果。在根目录中有一个主 CMakeLists.txt 文件,它编译startup.s
和main.c
文件,然后链接核心库。正确SysTick handler
的是放在核心库中,因此startup.s
文件的编译“看不到”这个处理函数的其他实现。解决它的正确而优雅的方法是什么?
我想到的另一个问题是我应该如何为其他中断处理程序编写代码以及如何在 CMake 构建系统中链接它们?假设我有一个 UART 模块,并且该模块有自己的中断处理程序。我应该创建一个基于startup.s
文件的单独库并将所有其他具有中断处理程序的模块链接到它吗?我认为 CMake 应该让构建更透明、更易读和更容易,但这样看起来更像意大利面条。可能我错过了一些东西......
编辑 2021 年 4 月 14 日
我发现问题仅与启动 asm 文件有关。例如,我可以在main.c中创建一个弱函数符号,例如:
__attribute__((weak)) void SystemInit(void)
在核心库中,在core.c我创建函数:
void SystemInit(void)
然后在编译并链接core.c中的正确函数后使用。所以看起来这里有一些与 asm 文件严格相关的东西。
解决方案
这种链接器行为的原因是它以不同的方式处理库。当它在源文件中找到弱符号时,它会停止在库中查找相同的符号。原因是库提供了一些功能,开发人员应该能够覆盖这些功能以使它们与自己的项目保持一致。
无需在微控制器的嵌入式项目中使用库。我发现它会引起更多的痛苦。一些开发人员不在add_library()
他们的CMakeLists.txt
. 在使用 CMake 时,我觉得它不是很合理。它用于更好地组织项目文件和管理模块之间的依赖关系。
这里的问题可以通过使用OBJECT
库简单地解决。该类型的链接已添加到target_link_libraries
3.12 版本中。我认为它是专门为微控制器项目添加的,而且效果非常好。
推荐阅读
- python - GraphFrame:查找简单图形 pyspark 直径的问题
- laravel - 嗨,我在 laravel 中发送电子邮件表单后重定向到路由时遇到问题
- python - 返回具有动态变量名称的函数以用于例如 lmfit
- python-3.x - 如何在生产中从 Django Admin 中删除 Celery Task 结果
- csv - pyspark 或 sparklyr:使用包含换行符的文本读取 csv;由“|”分隔
- c# - 变量泛型类型计数运行时反射
- shell - 如何编写批处理脚本来运行多个 adb shell 命令
- html - 如何使用 flexbox CSS 将两个项目连续隔开?
- angular - isStable 在角度中的真正含义是什么?
- python-3.x - 当我在 python 中使用 wptools 时导入错误