【教程】clion开发stm32环境搭建,有这一篇就够(只愿意博君一笑!!!)
文章目录
clion环境搭建
当涉及到 STM32 的开发环境时,目前使用 Keil IDE 存在一些缺点,而转向使用 CLion(一个流行的跨平台 C/C++ 集成开发环境)可能带来以下优点,Keil IDE 的集成开发环境可能对于某些项目的需求不够灵活,因为它主要针对 ARM 和特定 MCU 架构的开发,插件和扩展性,Keil IDE 的插件和扩展性相对有限,这可能限制了您在开发过程中使用一些定制化工具和功能,对于新手来说,Keil IDE 的学习曲线可能较陡,特别是在熟悉其界面、配置和工作流程方面,CLion 是一个跨平台的 IDE,可在 Windows、macOS 和 Linux 上运行,为开发者提供了更大的灵活性,强大的代码分析,CLion 提供先进的代码分析和智能感知功能,可以帮助您更轻松地发现和解决代码问题,丰富的插件生态系统CLion 支持丰富的插件,您可以根据项目需求轻松集成各种工具和扩展,CLion 的现代化界面和用户友好的操作方式可以提高开发效率,并使开发过程更加舒适,CMake 集成CLion 对 CMake 的集成非常强大,这对于跨平台开发和项目管理非常有帮助,特别适用于复杂的 STM32 项目,社区支持CLion 拥有活跃的社区,您可以在社区中获取帮助、分享经验,并从其他开发者的经验中受益。
总之,转向使用 CLion 可能为您提供更灵活、功能更强大的开发环境,帮助您更高效地进行 STM32 开发并解决一些 Keil IDE 存在的局限性。但在做出决策之前,建议您仔细考虑您的项目需求、个人偏好以及迁移成本。
一 工具安装
1、工具安装clion
1.1 产品概述
Clion是一款专门开发C以及C++所设计的跨平台的IDE。它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员的生产力。这种强大的IDE帮助开发人员在Linux、OS X和Windows上来开发C/C++,同时它还能使用智能编辑器来提高代码质量、自动代码重构并且深度整合Cmake编译系统,从而提高开发人员的工作效率。
提供C以及C++支持(包含C++,libc++和Boost),同时也支持JavaScript,XML,HTML和CSS。跨平台:您可以在64-bit Linux、OS X以及64-bit Windows上使用它。支持GCC、clang、MinGW、Cygwin编译器以及GDB调试器。提供对Cmake支持:包含自动处理Cmake changes和Cmake Targets,更新新创建的C/C++档案以及Cmake Cache编辑器。提供各式编码辅助:包含多行编辑功能、智能完成一键导航等。安全可信的自动代码重构功能。代码分析功能:监控代码品质并提供快速修复让开发人员得以及时就地解决问题。集成了GDB调试器及评估表达式(expressions)功能、STL容器渲染器(renderers)、监视(watches)、内嵌变量视图等。与最热门的版本控制系统集成:Subversion、Git、GitHub、Mercurial、CVS、Perforce及TFS。内建terminal模式并可以通过插件实现提供Vim-emulation模式。
1.2 下载CLion
首先,您需要从JetBrains的官方网站下载CLion安装程序。访问 https://www.jetbrains.com/clion/download/other.html,选择适用于您操作系统的版本,得到Clion.exe文件。
1.3 运行安装程序
下载完成后,运行安装程序。根据您的操作系统,可能会有一些特定的步骤。以下是一些常见操作系统的安装流程
1.4 选择安装选项
在安装向导中,您可以选择安装位置、启动菜单文件夹等选项。默认设置通常是可以的,但您可以根据需要进行自定义设置。
1.5 安装clion
点击“Install”按钮开始安装过程。安装可能需要一些时间,取决于您的系统性能。
1.6 启动CLion
安装完成后,在开始菜单中找到CLion图标并双击它以启动CLion。
1.7激活Clion
首次运行CLion时,您可能需要选择激活方式。您可以选择使用JetBrains帐户登录激活,或者使用许可证密钥进行激活。
2、安装OpenOCD
2.1 产品概述
OpenOCD(Open On-Chip Debugger)是一个开源的、灵活的、用于嵌入式系统开发的调试和编程工具。它允许开发人员通过调试适配器连接到目标芯片的调试接口(如JTAG、SWD等),以进行调试、烧录固件以及执行其他与硬件相关的任务。可以在多个操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版。这使得开发人员能够在不同的开发环境中使用 OpenOCD, 支持多种调试适配器,包括广泛使用的 JTAG、SWD、FTDI 等。这使得您可以选择适合您硬件和需求的合适调试适配器, OpenOCD 提供了广泛的目标芯片支持,包括多种处理器架构(如ARM、MIPS、RISC-V等)。通过相应的配置文件,您可以轻松配置 OpenOCD 以支持特定的目标芯片, 是一个模块化的工具,允许开发人员编写自定义的插件和扩展,以增强功能或添加特定的支持,拥有活跃的社区,您可以在论坛、邮件列表等地方获取帮助、分享经验和解决问题。总之,OpenOCD 是一个功能强大且灵活的嵌入式调试和编程工具,为开发人员提供了在嵌入式系统开发过程中进行调试、烧录和交互的能力。无论您是在开发嵌入式系统、单板计算机还是其他硬件项目,OpenOCD 都可以成为一个有价值的工具。
2.2下载 OpenOCD
首先,您需要从 OpenOCD 官方网站下载 Windows 版本的 OpenOCD。访问 https://gnutoolchains.com/arm-eabi/openocd/ 并选择合适的版本。通常您可以选择预编译的 Windows 执行文件。
2.3解压缩文件
下载完成后,将下载的压缩文件解压到您选择的文件夹中。您可以使用 Windows 自带的压缩工具或第三方工具(如 7-Zip)来完成这一步骤,这里我使用的是WinRAR解压工具,工具方面任选。
解压完毕后即可安装成功,安装的本质就是解压。
2.4配置环境变量(可选)
虽然不是必需的步骤,但您可以将 OpenOCD 的路径添加到系统的 PATH 环境变量中,以便在任何目录下都可以直接运行 OpenOCD 命令。要配置环境变量,请按照以下步骤:
-
在桌面上,右键单击“此电脑”(或“我的电脑”),然后选择“属性”。
-
点击左侧的“高级系统设置”。
-
在弹出的窗口中,点击“环境变量”按钮。
-
在系统变量部分,找到名为“Path”的变量,双击它,在变量值文本框的末尾,添加 OpenOCD 执行文件所在文件夹的路径,然后点击“确定”。
3、安装编译器MinGW 和arm-none-eabi-gcc
3.1下载 MinGW 安装程序
访问 MinGW 官方网站 https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/ 下载 MinGW 安装程序(mingw-get-setup.exe
文件)。
3.2运行安装程序
双击下载的 mingw-get-setup.exe
文件,系统将提示您是否允许此应用对您的设备进行更改。点击“是”继续。
3.3选择安装目录
在安装向导中,您需要选择 MinGW 的安装目录。建议选择一个不包含空格或特殊字符的路径,例如 C:\MinGW
。然后点击“Continue”继续。
3.4 选择组件
在此步骤中,您需要选择要安装的 MinGW 组件。通常,您至少需要选择 mingw32-base
和 mingw32-gcc-g++
组件,这些组件将提供基本的编译环境。您还可以根据需要选择其他组件。选择完成后,点击“Continue”继续。
3.5 安装MinGW
在下一个页面,点击“Installation”以开始安装选择的组件。安装可能需要一些时间,取决于您选择的组件和系统性能。
- 这里等待一下,等它安装到100%
-
勾选全部选项。
-
点击左上角【Installation】中的【Apply Changes】
-
点击【Apply】
-
3.7 点击【Close】,完成
3.8 添加 MinGW 到系统 PATH 环境变量(可选)
虽然不是必需的步骤,但您可以将 OpenOCD 的路径添加到系统的 PATH 环境变量中,以便在任何目录下都可以直接运行 OpenOCD 命令。要配置环境变量,请按照以下步骤:
-
在桌面上,右键单击“此电脑”(或“我的电脑”),然后选择“属性”。
-
点击左侧的“高级系统设置”。
-
在弹出的窗口中,点击“环境变量”按钮。
-
在系统变量部分,找到名为“Path”的变量,双击它,在变量值文本框的末尾,添加 OpenOCD 执行文件所在文件夹的路径,然后点击“确定”。
3.9 验证安装
打开命令提示符(Command Prompt)或 PowerShell,输入以下命令验证 MinGW 是否正确安装:
g++ --version
4、安装arm-none-eabi-gcc
4.1 arm-none-eabi-gcc产品概述
arm-none-eabi-gcc
是 ARM 架构的裸机嵌入式系统开发中常用的编译器工具链。它是 GNU Compiler Collection (GCC) 的一部分,专门用于编译 ARM 架构的代码,适用于嵌入式系统开发,特别是不依赖于操作系统(裸机)的情况。提供了一整套编译器工具,包括 C 语言编译器 (arm-none-eabi-gcc
)、C++ 编译器 (arm-none-eabi-g++
)、汇编器 (arm-none-eabi-as
) 和链接器 (arm-none-eabi-ld
) 等。这些工具允许开发人员编译、汇编和链接 ARM 架构的代码。支持多种 ARM 架构: arm-none-eabi-gcc
工具链支持多种 ARM 架构,包括 ARM Cortex-M 系列(如 Cortex-M0、Cortex-M3、Cortex-M4 等)和其他 ARM 架构变体。这使得它适用于广泛的嵌入式项目,主要用于裸机嵌入式系统开发,即开发没有操作系统支持的嵌入式应用。它可以生成适合在裸机环境下运行的代码,如裸机驱动程序、引导加载程序等。工具链提供了丰富的优化选项,可以根据开发人员的需求调整代码生成的优化级别,以提高代码性能和资源利用率。是跨平台的工具链,可以在多种操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版。它遵循自由软件许可证,允许开发人员在开源项目中免费使用和分发它。可以与其他开发工具集(如 GDB、OpenOCD 等)集成,以提供完整的嵌入式开发环境,支持调试、烧录和代码分析等任务。由于 arm-none-eabi-gcc
是 GCC 的一部分,它可以借助 GCC 社区和生态系统的支持和资源。开发人员可以从广泛的社区资源中获益,包括文档、示例和讨论论坛。总之,arm-none-eabi-gcc
工具链是嵌入式系统开发中重要的工具之一,适用于裸机嵌入式应用程序的编译、汇编和链接。它提供了丰富的功能和灵活性,帮助开发人员在 ARM 架构下开发高效的嵌入式应用程序。
4.2 下载arm-none-eabi-gcc
首先,您需要从 ARM 官方网站下载 arm-none-eabi-gcc
工具链。访问 https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 下载适用于 Windows 的版本。
4.3 安装arm-none-eabi-gcc
-
找到下载后的arm-none-eabi-gcc.exe 文件 双击打开。
-
双击点开exe文件后,进入语言选择界面,进行语言选择后,点击ok。
- 同意协议许可
- 安装路径选择页面,这个根据个人硬盘大小进行修改。
- 安装向导最后一页,勾选最后两项。
4.4验证安装
打开命令提示符(Command Prompt)或 PowerShell,输入以下命令验证工具链是否正确安装:
arm-none-eabi-gcc --version
如果显示了工具链的版本信息,则表示安装成功。
现在,您已经成功安装了 arm-none-eabi-gcc
工具链,可以使用它来编译 ARM 架构的代码。在实际使用中,您可能还需要配置您的开发环境(如编辑器、调试工具等)以与工具链配合使用。请注意,上述步骤假设您在 Windows 操作系统上进行安装,如果您使用其他操作系统,请适当调整步骤。
二 项目创建
1、在Clion中创建项目
2、创建新项目文件夹
3、导入stm32 需要的固件库
3.1 固件库文件准备
ST固件库(STM32 Firmware Library)是由STMicroelectronics提供的一组软件函数和驱动程序,专门用于支持STMicroelectronics的STM32微控制器系列。这些库提供了一些高级功能和底层驱动,使开发人员能够更轻松地编写STM32微控制器的应用程序。
-
准备固件库文件
-
导入源文件
-
导入头文件
-
导入系统文件
-
core_cm3 文件导入
-
导入stm32f10x_conf.h 文件
3.2 启动文件准备
STM32启动文件(Startup File)是用于初始化微控制器硬件和软件环境的重要文件。它在微控制器的启动过程中执行,并负责设置初始状态、配置系统时钟、初始化堆栈、调用主函数等。启动文件在裸机编程(Bare-Metal Programming)中扮演关键角色,确保微控制器正确启动并进入应用程序。
写入如下内容或者文件直接导入
/**
*************** (C) COPYRIGHT 2017 STMicroelectronics ************************
* @file startup_stm32f103xb.s
* @author MCD Application Team
* @brief STM32F103xB Devices vector table for Atollic toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Configure the clock system
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.equ BootRAM, 0xF108F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word ADC1_2_IRQHandler
.word USB_HP_CAN1_TX_IRQHandler
.word USB_LP_CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBWakeUp_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word BootRAM /* @0x108. This is for boot in RAM mode for
STM32F10x Medium Density devices. */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_IRQHandler
.thumb_set PVD_IRQHandler,Default_Handler
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USB_HP_CAN1_TX_IRQHandler
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
.weak USB_LP_CAN1_RX0_IRQHandler
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_SCE_IRQHandler
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak TIM1_UP_IRQHandler
.thumb_set TIM1_UP_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_IRQHandler
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
3.3 创建链接脚本文件
是一个链接脚本(Linker Script)文件,用于指导编译器如何组织生成的代码和数据,以及如何在微控制器的存储器中分配空间。它是在使用GNU工具链(如GCC编译器)进行STM32F103C8Tx微控制器的裸机编程时使用的一个重要文件。
在STM32F103C8Tx_FLASH.ld文件中写入如下内容
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : Auto-generated by System Workbench for STM32
**
** Abstract : Linker script for STM32F103C8Tx series
** 64Kbytes FLASH and 20Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed “as is,” without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in src and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** 1. Redistributions of src code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** 3. Neither the name of STMicroelectronics nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20005000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
4、编写CMakeLists.txt文件
是用于配置CMake构建系统的脚本文件,它的作用是指导CMake如何生成项目的构建文件(如Makefile、Visual Studio项目等),以便在不同的编译环境中进行项目的构建和编译。
使用如下内容覆盖
原来的CMakeLists.txt文件内容
#THIS FILE IS AUTO GENERATED FROM THE TEMPLATE! DO NOT CHANGE!
# 设置交叉编译的系统名称为 Generic,系统版本为 1
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
# 指定最低的 CMake 版本要求为 3.20
cmake_minimum_required(VERSION 3.20)
# specify cross compilers and tools
# 指定交叉编译的工具
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# project settings
# 项目设置
project(CLionSTM32Demo C CXX ASM)
# CMake 中的一个命令,用于设置 C++ 编译的标准版本。在这个特定的命令中,它将 C++ 标准设置为 C++17。
set(CMAKE_CXX_STANDARD 17)
#是 CMake 中的一个命令,用于设置 C 编译的标准版本。在这个特定的命令中,它将 C 标准设置为 C11。
set(CMAKE_C_STANDARD 11)
#Uncomment for hardware floating point
#add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
#add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#Uncomment for software floating point
#add_compile_options(-mfloat-abi=soft)
# 添加 ARM Cortex-M3 处理器相关的编译选项
add_compile_options(-mcpu=cortex-m3 -mthumb -mthumb-interwork)
# 添加编译选项,优化代码大小和资源使用
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)
# uncomment to mitigate c++17 absolute addresses warnings
# 设置 C++ 编译选项,以减轻 C++17 的绝对地址警告
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")
# 根据 CMake 构建类型设置编译选项
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") #这是一个条件判断语句,检查 CMake 构建类型是否为 "Release"(发布)模式。
message(STATUS "Maximum optimization for speed") #如果构建类型是 "Release",则会输出一条状态消息,指示当前选择了最大化的速度优化。
add_compile_options(-Ofast) #在 "Release" 模式下,通过 add_compile_options 命令添加编译选项 -Ofast,这是 GCC 编译器的一个选项,用于启用最大级别的优化,以提高代码运行速度。它通常会应用各种优化策略,包括内联函数、循环展开等。
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") # 如果构建类型不是 "Release",则检查是否为 "RelWithDebInfo"(带有调试信息的发布)模式。
message(STATUS "Maximum optimization for speed, debug info included") #如果构建类型是 "RelWithDebInfo",则输出一条状态消息,指示当前选择了最大化的速度优化,并且还包含了调试信息。
add_compile_options(-Ofast -g) # 在 "RelWithDebInfo" 模式下,除了启用最大化的速度优化外,还添加了 -g 选项,该选项会生成用于调试的符号信息,以便在调试时可以查看变量和代码执行的详细信息。
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel") # 如果构建类型不是 "RelWithDebInfo",则检查是否为 "MinSizeRel"(最小化大小发布)模式。
message(STATUS "Maximum optimization for size") # 如果构建类型是 "MinSizeRel",则输出一条状态消息,指示当前选择了最大化的大小优化。
add_compile_options(-Os) # 在 "MinSizeRel" 模式下,添加编译选项 -Os,这是 GCC 编译器的一个选项,用于启用最大化的大小优化,以减小生成的可执行文件的大小。
else () # 如果前面的条件都不满足,即构建类型不是 "Release"、"RelWithDebInfo" 或 "MinSizeRel",则执行下面的代码块。
message(STATUS "Minimal optimization, debug info included") # 在其他构建类型下,输出一条状态消息,指示当前选择了最小化的优化,并且还包含了调试信息。
add_compile_options(-Og -g) # 在其他构建类型下,添加编译选项 -Og -g,这是 GCC 编译器的选项,用于启用适用于调试的优化级别,并生成调试符号信息。
endif ()
# 添加宏定义,指定使用 HAL 驱动和 STM32F103xB 芯片
add_definitions(-DUSE_HAL_DRIVER -DSTM32F103xB -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD)
# 链接源文件 # 配置头文件搜索路径
include_directories( user/inc STM32F10x_FWLib/inc hardware/inc)
# 文件 # 设置源文件列表
file(GLOB_RECURSE SOURCES "startup/*.*" "user/*.*" STM32F10x_FWLib/*.* "hardware/*.*")
# 设置链接脚本路径
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32F103C8Tx_FLASH.ld)
# 添加链接选项,包括链接脚本和其他选项
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=cortex-m3 -mthumb -mthumb-interwork)
add_link_options(-T ${LINKER_SCRIPT})
add_link_options(-specs=nano.specs -specs=nosys.specs -u _printf_float)
# 创建可执行文件目标,包括源文件和链接脚本
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
# 数学函数需要用到
target_link_libraries(${PROJECT_NAME}.elf m)
# 设置输出的 HEX 和 BIN 文件路径
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
# 添加自定义的构建命令,用于生成 HEX 和 BIN 文件
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
COMMENT "Building ${HEX_FILE}
Building ${BIN_FILE}")
5、编写主函数测试
5.1 添加主函数
5.2 删除cmake-build-debug
5.3 测试项目
更新或重新生成 CMake 构建系统的相关文件,随后点击运行按钮。
5.4 出现异常
内存地址 [r1]
处尝试进行字节存储,操作失败。
解决方式修改STM32F10x_FWLib/src/core_cm3.c文件的第736行和752行
// 736 行内容
//__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
// 752 行内容
//__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
5.5 再次点击运行
上面错误基本都会出现,修改代码后即可解决,修改完成后再次点击运行即可。
出现如上内容编译通过
三、烧录配置
1. 创建烧录配置文件
工程根目录下新建一个文件夹Config
,在里面新建一个配置文件linkConfig.cfg
,文件的内容如下:
2. 仿真器文件创建:
野火fireDap作为
# choose st-link/j-link/dap-link etc.
adapter driver cmsis-dap
source [find target/stm32f1x.cfg]
用ST-Link使用:
source [find interface/stlink.cfg]
transport select hla_swd
source [find target/stm32f1x.cfg]
adapter speed 10000
3. clion添加open ocd
点击File ->Settings->Build,Execution,Deployment->Embedded Development
修改OpenOCD为我们自己的安装路径
4.添加烧录配置
选择 OpenOCD Download& Run 配置选项,准备编辑烧录配置文件。
编辑配置,点击烧录配置文件,为烧录做准备。
配置完成之后就可以进行烧录了。
最后提升如下内容没有出现异常,即为项目创建成功,clion打印信息是红色的没有关系
。
[0m[0mOpen On-Chip Debugger 0.12.0 (2023-02-02) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use '
transport select <transport>'.
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: SWO-UART supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: FW Version = 0253
Info : CMSIS-DAP: Serial# = 0700000100480064410000104e543246a5a5a5a597969908
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x1ba01477
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : gdb port disabled
[stm32f1x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xb9337822 msp: 0x4c05b510
** Programming Started **
Info : device id = 0x20036410
Info : flash size = 64 KiB
Warn : Adding extra erase range, 0x080066e8 .. 0x080067ff
** Programming Finished **
shutdown command invoked
四、 项目模板
https://github.com/xing-guangEasy/stm32-STM32F103C8T6.git
五、 创建所需文件
https://pan.baidu.com/s/1H0fhTDgxEjwXgBIk6KlM0Q?pwd=6i1m
提取码:6i1m
作者:尘事间