CLion搭建STM32开发环境(基于野火开发板STM32F103C8T6)

CLion搭建STM32开发环境(基于野火开发板STM32F103C8T6)

硬件环境:

  • STM32F103C8T6
  • 野火DAP调试器

软件环境

  • Windows 11(23H2)
  • STM32CubeMX
  • CLion2024.2.2
  • MinGW(新版本CLion,捆绑了MinGW,可以省略)
  • OpenOCD
  • arm-none-eabi-gcc

链接

  1. STM32CubeMX
  2. CLion2024.2.2
  3. MinGW
  4. OpenOCD
  5. arm-none-eabi-gcc

参考教程:

Clion搭建stm32开发环境(STM32F103C8T6),有这一篇就够(只愿意博君一笑!!!)_clion写单片机-CSDN博客

本次教程是针对,在开发环境中遇到的问题和解决方法,以及更细致完善的分析整个过程

一、工具安装

1.Clion(本次演示,未删除中文插件,所以安装界面为中文)

Step1:双击CLion-2024.2.2.exe 打开安装程序,点击下一步

在这里插入图片描述

Step2:选择安装目录,点击下一步

在这里插入图片描述

Step3:配置安装选项,这里建议全选,点击下一步

在这里插入图片描述

Step4:选择启动菜单文件夹创建快捷方式,点击安装

在这里插入图片描述

Step5:等待安装完成,选择稍后重启,点击完成

在这里插入图片描述

Step6:进入软件,使用账户激活软件(这里不提供破解方法,自行上网查找)
在这里插入图片描述

Step7:为软件安装中文插件,点击插件选项,安装中文插件,完成软件的安装设置

在这里插入图片描述

2.MinGw(踩坑过程)

之前一直都是通过MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net下载安装的,在Files文件下载安装的免安装包,这次一看,居然没有了。于是就开始踩坑过程。

  1. 通过mingw-get-setup.exe,安装程序,下载安装。装完后下载组件,但是很漫长,下了一个多小时都没有安装完,速度很慢(因为要访问外网服务器,所以很慢)果断放弃了。

在这里插入图片描述

2.直接通过SourceForge网址下载最新的安装包,但是下载完解压后,发现文件结构和目录看不懂,也找不到bin文件夹

在这里插入图片描述

在这里插入图片描述

3.去官网Downloads - MinGW-w64下载,但是进去后发现又看不懂,找了一会儿,看到了SourceForge,点进去后看到了熟悉的页面。于是下载了一个mingw-w64-8.03.zip版本的,解压后发现依旧不对

在这里插入图片描述

4.继续在官网Downloads - MinGW-w64寻找答案,看到了MinGW-W64-builds下的GitHup的链接,点了进去。进去后发现好像对了(进入GitHup需要运气,当然也可以使用科学上网工具,这里不在说明,下载时可以使用多线程下载工具,速度较快,这里我使用的是IDM)

在这里插入图片描述

在这里插入图片描述

但是进去后发现不知道应该下载哪一个,这些名称都不怎么认识,于是又开始了一段查找。将其中的选择参数说明如下表:

参数分类参数说明
CPU架构i68632位系统架构
CPU架构x86_6464位系统架构
操作系统接口协议win32开发windows应用程序
操作系统接口协议posix开发Linux、Mac应用程序(可移植应用程序等)
异常处理模型(32bit)dwarf版本新,性能好,只支持32位系统,不支持64位系统
异常处理模型(64bit)seh版本新,性能好,只支持64位系统,不支持32位系统
运行时库msvcrt传统上,MinGW-w64 编译器使用 MSVCRT 作为运行时库,它在所有版本的 Windows 上都可用(win10一下版本使用)
运行时库ucrtUCRT,全称Universal C Runtime(通用C运行时库),是微软为Windows平台引入的一项关键技术,旨在提供符合ISO C99、C11及POSIX标准的C语言运行时支持。自Windows 10起,UCRT作为操作系统的核心组件,为应用程序带来了更好的兼容性、稳定性和性能。(win10及其以上版本更好的选择)

这里作为开发单片机,这里选择x68_64-14.2.0-release-posix-seh-ucrt-rt-v12-rev0.7z使用解压软件,解压到指定文件夹即可
在这里插入图片描述

3.arm-none-eabi-gcc

Step1:Arm官网下载arm-none-eabi-gcc编辑器,选择Zip的免安装版本

在这里插入图片描述

Step2:将压缩包,解压到指定文件夹,方便管理,即可

在这里插入图片描述

4.OpenOCD

Step1:点击网址链接,进入网站,下载最新的即可

在这里插入图片描述

Step2:将下载好的压缩包,解压到指定文件夹,即可。路径不要有空格和中文

在这里插入图片描述

5.STM32CubeMx

5.1 JAVA环境配置

Step1:打开JAVA官网,下载最新版,点击下载按钮

在这里插入图片描述

Step2:双击运行jre-8u421-windows-x64.exe进行安装,点击安装

在这里插入图片描述

Step3:勾选更改目标文件夹,点击安装,更改完成后,点击下一步

在这里插入图片描述

Step4:等待安装完成

在这里插入图片描述

5.2Cubemx下载

Step1:进入官网下载,点击下载STM32CubeMX按钮

在这里插入图片描述

Step2:选择Windows版本,点击下载按钮,稍后就能使用账户登录或访客模式下载软件

在这里插入图片描述

Step3:双击SetupSTM32CubeMX-6.12.0-Win.exe文件进行安装,点击Next

在这里插入图片描述

Step4:勾选相关同意事项,点击Next

在这里插入图片描述

Step5:更改安装路径,点击Nxet,等待安装完成,最后点击Done,完成安装

在这里插入图片描述

在这里插入图片描述

相关目录及安装路径如图

在这里插入图片描述

STM32Cub文件夹包含如下文件,gcc-arm、mingw64、OpenOCD

在这里插入图片描述

二、基础环境配置

1.添加系统环境变量

打开系统的环境变量(右击此电脑->属性->高级系统设置->环境变量),找到系统变量中的PATH变量,点击编辑,在当中新建三个路径,分别是OpenOCDMinGW64arm-none-eabi-gcc三个软件安装目录下的bin文件夹的安装路径

在这里插入图片描述

重启电脑,使用CMD命令行,输入一下命令,出现版本号后,证明环境添加成果

gcc -v
arm-none-eabi-gcc -v
openocd -v

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三、CLion配置、创建STM32项目

1.STM32F1库文件安装

Step1.官网下载指定芯片的库文件包,这里选择F1,鼠标单击F1位置

在这里插入图片描述

Step2.选择要安装的版本,这里选择安装最新版(登录后即可下载)

在这里插入图片描述

Step3.解压后完成下载

在这里插入图片描述

2.准备STM32所需要的固件库

说明:新建四个文件夹分别为Libraries、STARTUP、CMSIS、User。Libraries文件夹用于存放库函数,STARTUP文件夹用于存放启动文件,CMSIS文件夹用于存放标准接口文件,User文件夹用于存放中断函数、和主函数,以及用户自己写的显示和驱动函数。

在这里插入图片描述

2.1标准库文件准备

打开STM32F10x_StdPeriph_Lib_V3.6.0库文件夹,点击Libraries文件夹,在点击下面的STM32F10x_StdPeriph_Driver文件夹,找到inc、src文件两个文件复制到新建的Libraries文件夹中。

在这里插入图片描述

2.2coer_cm3文件准备

打开STM32F10x_StdPeriph_Lib_V3.6.0库文件夹,点击Libraries文件夹,在点击下面的CMSIS文件夹,继续点击下面的CM3文件夹,最后点击下面的CorSupport文件,将里面的core_cm3.c、core_cm3.h文件复制到,新建的CMSIS文件夹中。

在这里插入图片描述

2.3系统文件准备

打开STM32F10x_StdPeriph_Lib_V3.6.0库文件夹,点击Libraries文件夹,在点击下面的CMSIS文件夹,继续点击下面的CM3文件夹,接着点击下面的DevicSupport文件夹,然后点击下面的ST文件夹,最后点击下面的STM32F10x文件夹,将里面的stm32f10x.h、system_stm32f10x.c、system_stm32f10x.h文件复制到,新建的CMSIS文件夹中。

在这里插入图片描述

2.4启动文件准备

打开STM32F10x_StdPeriph_Lib_V3.6.0库文件夹,点击Libraries文件夹,在点击下面的CMSIS文件夹,继续点击下面的CM3文件夹,接着点击下面的DevicSupport文件夹,然后点击下面的ST文件夹,点击下面的STM32F10x文件夹,最后点击startup文件夹将里面startup_stm32f10x_md.s文件复制到,新建的STARTUP文件夹中。

在这里插入图片描述

名称解释
arm适用于arm编译器
gcc_ride7适用于GCC编译器
iar适用于iar编译器
TrueSTDIO适用于TrueSTDIO编译器

具体选择cl还是md,需要查看数据手册,看自己芯片的存储容量,这里选择md,中等容量的启动文件。

2.5中断、stm32f10x_conf.h文件准备

打开STM32F10x_StdPeriph_Lib_V3.6.0库文件夹,点击Project文件夹,在点击下面的STM32F10x_StdPeriph_Template文件夹,将下面的stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h文件复制到,新建的User文件夹中。

在这里插入图片描述

其中stm32f10x_it.c、stm32f10x_it.h是中断的相关函数,stm32f10x_conf.h包含了所有外设的头文件,还有断言处理语句,至此完成了STM32所需要的全部固件库、和相关文件的准备工作。

3.CLion工具链配置

打开软件,打开->设置->构建、执行、部署->工具链,输入mingw的路径(新版本的CLion有绑定的mingw,可以跳过,这个步骤主要用于编辑纯c,可以跳过)

在这里插入图片描述

按照上一个步骤,新建一个工具链,名字叫做MinGW-STM32,其它使用捆绑默认,更改构建工具、C编译器、C++编译器,调试器的路径。其中C编译器和C++编译器使用gcc-arm-none-eabi文件夹的对应文件,将新建的MinGW-STM32工具链设置为默认。

在这里插入图片描述

打开构建、执行、部署->嵌入式开发,设置OpenOCD和STM32CubeMX执行文件的路径(否则使用STM32CubeMX创建项目时会报错)

在这里插入图片描述

设置Debug,这里工具链选择新建的MinGW-STM32,更改名称为Debug-STM32,生成器选择MinGW Makefiles,其它保持默认

在这里插入图片描述

4.CubeMX生成STM32项目

打开文件->新建->项目->嵌入式->STM32CubeMX,设置文件路径

在这里插入图片描述

项目创建完成后,点击通过STM32CubeMX打开

在这里插入图片描述

进去STM32CubeMX后,依次点击File->New Project,然后选择芯片型号,这里输入STM32F103C8T6,然后双击被框住的地方,进去芯片设置界面。

在这里插入图片描述

这里使用标准库开发,不需要进行任何设置(STM32CubeMX生成的相关代码均为HAL库的文件)点击Project Manager 设置工程名称,以及保存路径。IDE选择STM32CubeIDE(这里只针对新版本,老版本自行网上查找),设置完成后点右上角的GENERATE CODE,生成工程。

[!WARNING]

这里路径必须和CLion路径、名称必须完全一致,否则生成的工程不能覆盖原有工程导致出错

在这里插入图片描述


生成的项目如下图:

这里我们是标准库开发,需要删除Core、Drivers文件夹

在这里插入图片描述

删除Core、Drivers文件后,导入之前整理准备的固件库的四个文件夹

在这里插入图片描述

在User文件下,新建main.c和main.h文件,这个时候发现软件报错了,因为这个工程是基于CMakeLists,我们需要更改这个文件的相关设置。

在这里插入图片描述

打开CMakeLists.txt文件,进行如下设置,最后点击右边的从新加载按钮,这样错误就消除了,并添加标准库和芯片板子的宏定义

在这里插入图片描述

USE_STDPERIPH_DRIVER   //标准库
STM32F10X_MD           //板子芯片型号
add_definitions(-DDEBUG -DUSE_STDPERIPH_DRIVER -DSTM32F10X_MD)   //CMakeLists.txt 宏定义部分,可以直接复制使用

点击编译,发现新的报错,内存地址 [r1] 处尝试进行字节存储,操作失败,这是因为core_cm3.c文件的相关代码,与CLion中要求不同,需要进行更改,我直接把更换代码的链接贴出来,直接更换即可。

在这里插入图片描述

core_cm3.c

更改完成后,又发现了新的问题,提示arm-none-eabi-gcc相关问题,期初认为是版本太高,或者没有设置环境变量,但是经过一番排除后发现都没有问题,于是点击报错链接,发现是STM32F103C8TX——FLASH.ld文件的某个位置报错。

[!IMPORTANT]

链接脚本文件:用于指导编译器如何组织生成的代码和数据,以及如何在微控制器的存储器中分配空间。它是在使用GNU工具链(如GCC编译器)进行STM32F103C8Tx微控制器的裸机编程时使用的一个重要文件。

在这里插入图片描述

在这里插入图片描述

于是各种开始在网上,查资料,试图解决问题,但是查询无果后,既然问题出在这个链接文件上,就仔细分析这个链接文件,然后代码注释的后面发现了这样一段注释。意思就是说“READONLY” 关键字仅在 GCC11 及更高版本中受支持,如果使用 GCC10 或更早版本,请将其删除。

在这里插入图片描述

然后备份了一下工程,就试着删除了一下“READONLY” 这个关键字,然后果然,编译就通过了,可以看到以及成功的生成了.bin和.hex文件,证明编译已经通过了。

在这里插入图片描述

[!CAUTION]

复盘原因时,发现了arm-none-eabi-gcc版本是10.3.1的,所以编译时链接脚本文件会报错,因为识别不了“READONLY” 这个关键字,版本不够高。但是之前配置时,也没有出现过这种情况。所以还得分析根本原因,于是我找到了之前配置成功的项目,对比了一下有了重大发现,贴图如下:

在这里插入图片描述

不难发现,两者有很大的不同,老版没有“READONLY” 关键字,还有很多语句和写法上也相差很大。那么造成差异的原因是什么,这个链接文件是由STM32CubeMX直接生成的,不难猜测是版本差异,之前的工程都是用老版本生成的链接文件,这一次使用的是最新版的STM32CubeMX生成的版本为6.12,那么也就是说,后面使用6.12及其以上的版本,如果GCC版本不在11以上,都要删除“READONLY” 这个关键字。

如果不想麻烦,这里也提供原始版本的链接文件的相关代码,可以复制直接使用。

/*
******************************************************************************
**

**  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>&copy; 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) }
}
————————————————


5.烧录配置

5.1添加烧录配置(OpenOCD)

点击,编辑配置选项

在这里插入图片描述

在弹出的对话框,中点击左上角+,选择添加配置。找到OpenOCD下载并运行选项,添加该选项

在这里插入图片描述

点击面版配置文件选择后面的辅助,弹出的对话框,选择stm32f103c8_blue_pill.cfg文件,点击复制到项目并使用按钮

在这里插入图片描述

5.2配置cfg文件

打开刚才的stm32f103c8_blue_pill.cfg,将下面代码,复制到下面

# SPDX-License-Identifier: GPL-2.0-or-later

# STM32F103C8 "Blue Pill"

adapter driver cmsis-dap
#source [find interface/cmsis-dap.cfg]
transport select swd
# 0x10000 = 64K Flash Size
set FLASH_SIZE 0x20000
source [find target/stm32f1x.cfg]
# download speed = 10MHz
adapter speed 10000

在这里插入图片描述

前两行设置了仿真器的类型和接口,下面几行指定了Flash大小芯片类型下载速度等,如果这些参数不一样可以根据实际情况更改以下文件

如果对自己的芯片不知道怎么设置,可以参考OpenOCD自带的一系列配置文件,路径在OpenOCD安装目录的share\openocd\scripts下:

只需要关注这几个目录:

  • board:板卡配置,各种官方板卡
  • interface:仿真器类型配置,比如ST-Link、CMSIS-DAP等都在里面
  • target:芯片类型配置,STM32F1xx、STM32L0XX等等都在里面
5.3编写测试程序

新建main.c、main.h文件,并编写简单点灯测试程序

在这里插入图片描述

5.4下载烧录

在这里插入图片描述

6.调试配置

6.1添加GDB服务器

点击,编辑配置选项,在弹出的对话框,中点击左上角+,选择添加配置。找到嵌入式GDB服务器选项,添加该选项

在这里插入图片描述

6.2配置GDB服务器

按下图配置

在这里插入图片描述

target remote(远程目标):localhost:3333(其中3333为OpenOCD端口号),据情况自行设置,默认为3333

GDB服务器:OpenOCD.exe文件的路径地址

GDB服务器实参:第一个是打开对应仿真器的.cfg文件,第二个是打开对应的芯片板子型号的.cfg文件(据情况自行设置,本套设置,适用于STM32F103C8T6野火开发板)

6.3外设文件添加

进入意法半导体-STMicroelectronics官网,搜索stm32f1svd(具体情况适自己而定)

在这里插入图片描述

下载并进行,解压

在这里插入图片描述

打开CLion,选择正在调试的程序,点击外设,点击加载SVD文件

在这里插入图片描述

选择加载文件的路径,和具体的芯片型号,点击确定

在这里插入图片描述

选择要显示的外设,这里按需自行设置

在这里插入图片描述

配置好后,选择外设就能观察到具体寄存器值

在这里插入图片描述

完结:

本教程从CLion搭建基础开发环境,到代码的编辑,项目的创建,从编辑,编译,到下载烧录,再到调试,全方位的展示了整个流程。后面还会涉及到串口中的输出重定向 printf,那又是后话了,就暂且写这么多。

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值