赞
踩
当涉及到 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 存在的局限性。但在做出决策之前,建议您仔细考虑您的项目需求、个人偏好以及迁移成本。
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模式。
首先,您需要从JetBrains的官方网站下载CLion安装程序。访问 https://www.jetbrains.com/clion/download/other.html,选择适用于您操作系统的版本,得到Clion.exe文件。

下载完成后,运行安装程序。根据您的操作系统,可能会有一些特定的步骤。以下是一些常见操作系统的安装流程

在安装向导中,您可以选择安装位置、启动菜单文件夹等选项。默认设置通常是可以的,但您可以根据需要进行自定义设置。


点击“Install”按钮开始安装过程。安装可能需要一些时间,取决于您的系统性能。


安装完成后,在开始菜单中找到CLion图标并双击它以启动CLion。


首次运行CLion时,您可能需要选择激活方式。您可以选择使用JetBrains帐户登录激活,或者使用许可证密钥进行激活。

OpenOCD(Open On-Chip Debugger)是一个开源的、灵活的、用于嵌入式系统开发的调试和编程工具。它允许开发人员通过调试适配器连接到目标芯片的调试接口(如JTAG、SWD等),以进行调试、烧录固件以及执行其他与硬件相关的任务。可以在多个操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版。这使得开发人员能够在不同的开发环境中使用 OpenOCD, 支持多种调试适配器,包括广泛使用的 JTAG、SWD、FTDI 等。这使得您可以选择适合您硬件和需求的合适调试适配器, OpenOCD 提供了广泛的目标芯片支持,包括多种处理器架构(如ARM、MIPS、RISC-V等)。通过相应的配置文件,您可以轻松配置 OpenOCD 以支持特定的目标芯片, 是一个模块化的工具,允许开发人员编写自定义的插件和扩展,以增强功能或添加特定的支持,拥有活跃的社区,您可以在论坛、邮件列表等地方获取帮助、分享经验和解决问题。总之,OpenOCD 是一个功能强大且灵活的嵌入式调试和编程工具,为开发人员提供了在嵌入式系统开发过程中进行调试、烧录和交互的能力。无论您是在开发嵌入式系统、单板计算机还是其他硬件项目,OpenOCD 都可以成为一个有价值的工具。
首先,您需要从 OpenOCD 官方网站下载 Windows 版本的 OpenOCD。访问 https://gnutoolchains.com/arm-eabi/openocd/ 并选择合适的版本。通常您可以选择预编译的 Windows 执行文件。
下载完成后,将下载的压缩文件解压到您选择的文件夹中。您可以使用 Windows 自带的压缩工具或第三方工具(如 7-Zip)来完成这一步骤,这里我使用的是WinRAR解压工具,工具方面任选。


解压完毕后即可安装成功,安装的本质就是解压。
虽然不是必需的步骤,但您可以将 OpenOCD 的路径添加到系统的 PATH 环境变量中,以便在任何目录下都可以直接运行 OpenOCD 命令。要配置环境变量,请按照以下步骤:
在桌面上,右键单击“此电脑”(或“我的电脑”),然后选择“属性”。

点击左侧的“高级系统设置”。

在弹出的窗口中,点击“环境变量”按钮。

在系统变量部分,找到名为“Path”的变量,双击它,在变量值文本框的末尾,添加 OpenOCD 执行文件所在文件夹的路径,然后点击“确定”。

访问 MinGW 官方网站 https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/ 下载 MinGW 安装程序(mingw-get-setup.exe 文件)。

双击下载的 mingw-get-setup.exe 文件,系统将提示您是否允许此应用对您的设备进行更改。点击“是”继续。


在安装向导中,您需要选择 MinGW 的安装目录。建议选择一个不包含空格或特殊字符的路径,例如 C:\MinGW。然后点击“Continue”继续。
在此步骤中,您需要选择要安装的 MinGW 组件。通常,您至少需要选择 mingw32-base 和 mingw32-gcc-g++ 组件,这些组件将提供基本的编译环境。您还可以根据需要选择其他组件。选择完成后,点击“Continue”继续。

在下一个页面,点击“Installation”以开始安装选择的组件。安装可能需要一些时间,取决于您选择的组件和系统性能。


虽然不是必需的步骤,但您可以将 OpenOCD 的路径添加到系统的 PATH 环境变量中,以便在任何目录下都可以直接运行 OpenOCD 命令。要配置环境变量,请按照以下步骤:
在桌面上,右键单击“此电脑”(或“我的电脑”),然后选择“属性”。

点击左侧的“高级系统设置”。

在弹出的窗口中,点击“环境变量”按钮。

在系统变量部分,找到名为“Path”的变量,双击它,在变量值文本框的末尾,添加 OpenOCD 执行文件所在文件夹的路径,然后点击“确定”。

打开命令提示符(Command Prompt)或 PowerShell,输入以下命令验证 MinGW 是否正确安装:
g++ --version
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 架构下开发高效的嵌入式应用程序。
首先,您需要从 ARM 官方网站下载 arm-none-eabi-gcc 工具链。访问 https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 下载适用于 Windows 的版本。
找到下载后的arm-none-eabi-gcc.exe 文件 双击打开。

双击点开exe文件后,进入语言选择界面,进行语言选择后,点击ok。




打开命令提示符(Command Prompt)或 PowerShell,输入以下命令验证工具链是否正确安装:
arm-none-eabi-gcc --version
如果显示了工具链的版本信息,则表示安装成功。
现在,您已经成功安装了 arm-none-eabi-gcc 工具链,可以使用它来编译 ARM 架构的代码。在实际使用中,您可能还需要配置您的开发环境(如编辑器、调试工具等)以与工具链配合使用。请注意,上述步骤假设您在 Windows 操作系统上进行安装,如果您使用其他操作系统,请适当调整步骤。




ST固件库(STM32 Firmware Library)是由STMicroelectronics提供的一组软件函数和驱动程序,专门用于支持STMicroelectronics的STM32微控制器系列。这些库提供了一些高级功能和底层驱动,使开发人员能够更轻松地编写STM32微控制器的应用程序。
准备固件库文件

导入源文件

导入头文件

导入系统文件

core_cm3 文件导入

导入stm32f10x_conf.h 文件

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****/
是一个链接脚本(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) } }
是用于配置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}")


更新或重新生成 CMake 构建系统的相关文件,随后点击运行按钮。

内存地址 [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) );

上面错误基本都会出现,修改代码后即可解决,修改完成后再次点击运行即可。

出现如上内容编译通过
工程根目录下新建一个文件夹Config,在里面新建一个配置文件linkConfig.cfg,文件的内容如下:

野火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
点击File ->Settings->Build,Execution,Deployment->Embedded Development
修改OpenOCD为我们自己的安装路径

选择 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
提取码:6i1m
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。