Clion使用ARMClang编译(STM32F1、F4)

0 预备环境

1.正常使用gcc的环境编译可以运行

2.STM32CubeMX可以生成 SW4STM32

image-20230416104153221

注意:一定要是SW4STM32 ,不然后期在Clion中无法进行编译

SW4STM32 在新版本中已经取消,这里提供一个老的版本

链接:https://pan.baidu.com/s/1NPl9mFzq8jIvHnfeq4cPZg?pwd=vpck
提取码:vpck

3.这里使用的是stlink烧录的

4.参考视频:https://www.bilibili.com/video/BV1z44y1t7Lg/?share_source=copy_web&vd_source=08ffec12a130bb99e9aac8670b5b9c2f

5.上面视频的资料:https://share.weiyun.com/KdkTFRnp

1 配置ARMCLANG环境

Keil_v5的安装路径,进入ARM文件夹

image-20230416104706430

打开ARMCLANG文件夹

image-20230416104745716

打开里面的bin目录,并复制其地址

image-20230416104850085

在系统环境变量中配置

打开【此电脑】→右键【属性】→【高级系统设置】→【环境变量】

在path中添加刚才的地址

image-20230416105105904

2 使用CubeMX新建工程

此处省略-----

只需要在最后的Toolchain / IDE中选择SW4STM32即可

3 使用Clion打开,修改CMakeLists.txt

这里会让你选择board,选择下图所示的这个(如果后面烧录出错的话,里面可能需要更改)【如果是F4则选择f4对应的】

image-20230416105603944

打开CMakeLists.txt文件

image-20230416105823498

这一部分是CMakeLists.txt默认生成的,这里需要和你自己的保持一致,所以复制粘贴替换的时候,要从这一部分之下开始,把这一部分之下的内容全部替换成下面的程序

3.1 STM32F1系列替换文件

#*************************************************************
# 1. 设定项目名称
# 需要给定 PROJECT_NAME 的值,必须与项目名称一致,否则 MDK 生成 *.sct 时路径不对
set(PROJECT_NAME demo)
# 2. 设定芯片类型
# 设定芯片类型,必须正确以 -mcpu 的参数规则命名,后边的编译参数会调用这个值
set(CMAKE_SYSTEM_PROCESSOR Cortex-M3)


############################################################
# 1. 指定编译器和链接器,避免使用默认的 gcc
############################################################
# 设置编译器 C 的编译器
set(CMAKE_C_COMPILER armclang.exe)
set(CMAKE_C_COMPILER_WORKS TRUE)

# 即便用不到C++ 的编译器,还是要显示说明的,否则报错
set(CMAKE_CXX_COMPILER armclang.exe)
set(CMAKE_CXX_COMPILER_WORKS TRUE)

#设置 ASM 的编译器(不设置配合 -masm=auto 使用)
set(CMAKE_ASM_COMPILER armclang.exe)
#set(CMAKE_ASM_COMPILER armasm.exe)     # 指明 ASM 编译器,配合 第二种 CMAKE_ASM_FLAGS_INIT 方式使用
set(CMAKE_ASM_COMPILER_WORKS TRUE)

#设置链接器
set(CMAKE_C_LINK_EXECUTABLE armlink.exe)
set(CMAKE_ASM_LINK_EXECUTABLE armlink.exe)
set(CMAKE_CXX_LINK_EXECUTABLE armlink.exe)


#*******************************************************************************************#
# 2. 获取芯片地址描述信息
# 获取当前 MCU 的 section 描述,及存储空间和起始地址的描述(注意:需要先用 keil 打开编译一下当前项目才能生成)
# 设置Sections脚本路径,CubeMX生成 MDK 后先编译一下,就会在MDK-ARM 目录下生成工程名命名的文件夹
# 在那个目录里会生成以项目名命名的sct文件。 由于在本地调用,不需要加 global 全局变量标记,更简洁
set(SECTIONS_SCRIPT_PATH ${CMAKE_HOME_DIRECTORY}/MDK-ARM/${PROJECT_NAME}/${PROJECT_NAME}.sct)


#********************************************************************************************#
# 3. 设置与芯片对应的 --target 编译选项
# 设置编译时默认参数片段,这些参数参见 MDK 中的配置,注意:Target 分页中要选 6.12 的 ARM 编译器,并抄各分页的 --target 配置
set(C_TARGET_FLAG --target=arm-arm-none-eabi)               # MDK 的 link 分页中的配置
set(ASM_TARGET_FLAG --target=arm-arm-none-eabi)             # MDK 的 link 分页中的配置(不支持显示指定 ASM 编译器的方式)
set(LINKER_TARGET_FLAG --cpu=${CMAKE_SYSTEM_PROCESSOR})     # MDK 的 link 分页中的配置


#********************************************************************************************#
# 4. 设置编译规则,这些规则变量要被外部的 CMakelistes.txt 调用,所以需要用 CACHE STRING "global" 声明为全局变量
# 编译参数,这些编译参数是从 MDK 中来的,具体的含义看 《 armclang Reference Guide 》 第一章节有详细介绍
# 需要注意的是不是 MDK 中的每个参数都要哪进来的,有些参数已经在 include 和 source 中被配置了
set(COMPILE_RULE_FLAG "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")

# 设置 C 编译器选项(这里就把MDK中的 C/C++ 分页里最下边一栏的属性贴进来)
# 参数 -w 表示忽略所有警告,不然要配具体忽略哪些警告,尽管贴过来也行,但是太乱
# 优化选项 -O 有 1~3   -Os 是平衡  -Oz 是最小体积
set(CMAKE_C_FLAGS_INIT "${C_TARGET_FLAG} ${COMPILE_RULE_FLAG} \
    -xc -std=c99 -fno-rtti -funsigned-char -fshort-enums -fshort-wchar \
    -gdwarf-3 -Oz -ffunction-sections -w")

# 设置 C++ 编译器选项(没有用到 c++ 所以不用配置)
#set(CMAKE_CXX_FLAGS_INIT ${CMAKE_C_FLAGS_INIT})

# 设置ASM编译器选项
# 注意: -masm=auto 选项是 MDK 的 link 分页里没有的参数,需要加上  -g 是debug 用的加不加都行
set(CMAKE_ASM_FLAGS_INIT "${ASM_TARGET_FLAG} ${COMPILE_RULE_FLAG} \
        -masm=auto -c -gdwarf-3 ")
# 第二种方式 配套显示执行 armasm.exe 为 ASM 编译器的方法,看上起更清晰一些
#set(CMAKE_ASM_FLAGS_INIT "${ASM_TARGET_FLAG} --cpu=Cortex-M3")



# 设置链接器选项
# 这些参数再 ARMCC 文档里么有,但 MDK 的 link 分页有,
# 使用忽略所有警告的配置时没有 --map 及其之后的内容, 这里根据需要保留了一些信息,在 demo.map 中可以看到
set(CMAKE_EXE_LINKER_FLAGS_INIT  " \
            ${LINKER_TARGET_FLAG} \
            --strict \
            --scatter ${SECTIONS_SCRIPT_PATH} \
            --info sizes --info totals --info unused --info veneers \
            --summary_stderr \
            --info summarysizes"
        )


# project settings
project(demo C CXX ASM)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)

#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)


include_directories(App Core/Inc RT-Thread Drivers/STM32F1xx_HAL_Driver/Inc/Legacy Drivers/STM32F1xx_HAL_Driver/Inc Drivers/CMSIS/Device/ST/STM32F1xx/Include Drivers/CMSIS/Include Middlewares/Third_Party/RealThread_RTOS/include/ Middlewares/Third_Party/RealThread_RTOS/bsp/_template/cubemx_config)

add_definitions(-DUSE_HAL_DRIVER -DSTM32F103xB)

file(GLOB_RECURSE SOURCES "startup/*.*" "RT-Thread/*.*" "Middlewares/*.*" "Drivers/*.*" "Core/*.*" App)
# 对于混合兼容的环境,需要屏蔽各种编译环境引起的文件“干扰”,通过 list(REMOVE_ITEM) 命令移除不同编译环境下的干扰文件
# 在原来 CubeMX 自动生成的 gcc 编译环境目录上,附加 ARMCC 编译需要的文件
file(GLOB_RECURSE SOURCES ${SOURCES} "MDK-ARM/startup_stm32f103xb.s")
# 将由 CubeMX 生成的 GCC 编译环境中的会干扰ARMCC环境的文件,放在 EXCLUDE_SRCS 自定义列表中
file(GLOB_RECURSE EXCLUDE_SRCS
        "Middlewares/Third_Party/RealThread_RTOS/libcpu/arm/cortex-m3/context_gcc.S"
        "startup/*.*"
        "Core/Src/syscalls.c"
        "STM32F103C8Tx_FLASH.ld"
        )
# 从源文件列表(SOURCES)中剔除干扰文件(EXCLUDE_SRCS)
list(REMOVE_ITEM SOURCES ${EXCLUDE_SRCS})


add_executable(${PROJECT_NAME} ${SOURCES} ${LINKER_SCRIPT})

set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
set(ELF_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf)

# 使用 armclang 自带的 fromelf 工具,实现 elf 转 hex
set(ARMCC_fromelf fromelf.exe)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
        # 相当于fromelf.exe" --i32combined --output="xxx/demo.hex" "xxx/demo.elf"
        COMMAND ${ARMCC_fromelf} --i32combined --output="${HEX_FILE}" "${ELF_FILE}"
        COMMENT "Building ${HEX_FILE}"
        )

## 使用了 gcc 的 arm-none-eabi-objcopy 工具实现 elf 转 hex 和 bin, 跟 armclang 不是一脉
#set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
#add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
#        COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}> ${HEX_FILE}
#        COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}> ${BIN_FILE}
#        COMMENT "Building ${HEX_FILE} Building ${BIN_FILE}")

3.2 STM332F4系列替换文件

#THIS FILE IS AUTO GENERATED FROM THE TEMPLATE! DO NOT CHANGE!
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
cmake_minimum_required(VERSION 3.24)

#*************************************************************
# 1. 设定项目名称
# 需要给定 PROJECT_NAME 的值,必须与项目名称一致,否则 MDK 生成 *.sct 时路径不对
set(PROJECT_NAME testF4)
# 2. 设定芯片类型
# 设定芯片类型,必须正确以 -mcpu 的参数规则命名,后边的编译参数会调用这个值
set(CMAKE_SYSTEM_PROCESSOR Cortex-M4)


############################################################
# 1. 指定编译器和链接器,避免使用默认的 gcc
############################################################
# 设置编译器 C 的编译器
set(CMAKE_C_COMPILER armclang.exe)
set(CMAKE_C_COMPILER_WORKS TRUE)

# 即便用不到C++ 的编译器,还是要显示说明的,否则报错
set(CMAKE_CXX_COMPILER armclang.exe)
set(CMAKE_CXX_COMPILER_WORKS TRUE)

#设置 ASM 的编译器(不设置配合 -masm=auto 使用)
set(CMAKE_ASM_COMPILER armclang.exe)
#set(CMAKE_ASM_COMPILER armasm.exe)     # 指明 ASM 编译器,配合 第二种 CMAKE_ASM_FLAGS_INIT 方式使用
set(CMAKE_ASM_COMPILER_WORKS TRUE)

#设置链接器
set(CMAKE_C_LINK_EXECUTABLE armlink.exe)
set(CMAKE_ASM_LINK_EXECUTABLE armlink.exe)
set(CMAKE_CXX_LINK_EXECUTABLE armlink.exe)


#*******************************************************************************************#
# 2. 获取芯片地址描述信息
# 获取当前 MCU 的 section 描述,及存储空间和起始地址的描述(注意:需要先用 keil 打开编译一下当前项目才能生成)
# 设置Sections脚本路径,CubeMX生成 MDK 后先编译一下,就会在MDK-ARM 目录下生成工程名命名的文件夹
# 在那个目录里会生成以项目名命名的sct文件。 由于在本地调用,不需要加 global 全局变量标记,更简洁
set(SECTIONS_SCRIPT_PATH ${CMAKE_HOME_DIRECTORY}/MDK-ARM/${PROJECT_NAME}/${PROJECT_NAME}.sct)


#********************************************************************************************#
# 3. 设置与芯片对应的 --target 编译选项
# 设置编译时默认参数片段,这些参数参见 MDK 中的配置,注意:Target 分页中要选 6.12 的 ARM 编译器,并抄各分页的 --target 配置
set(C_TARGET_FLAG --target=arm-arm-none-eabi)               # MDK 的 link 分页中的配置
set(ASM_TARGET_FLAG --target=arm-arm-none-eabi)             # MDK 的 link 分页中的配置(不支持显示指定 ASM 编译器的方式)
set(LINKER_TARGET_FLAG --cpu=${CMAKE_SYSTEM_PROCESSOR})     # MDK 的 link 分页中的配置


#********************************************************************************************#
# 4. 设置编译规则,这些规则变量要被外部的 CMakelistes.txt 调用,所以需要用 CACHE STRING "global" 声明为全局变量
# 编译参数,这些编译参数是从 MDK 中来的,具体的含义看 《 armclang Reference Guide 》 第一章节有详细介绍
# 需要注意的是不是 MDK 中的每个参数都要哪进来的,有些参数已经在 include 和 source 中被配置了
set(COMPILE_RULE_FLAG "-mcpu=${CMAKE_SYSTEM_PROCESSOR} -mfpu=fpv4-sp-d16 -mfloat-abi=hard -c ")

# 设置 C 编译器选项(这里就把MDK中的 C/C++ 分页里最下边一栏的属性贴进来)
# 参数 -w 表示忽略所有警告,不然要配具体忽略哪些警告,尽管贴过来也行,但是太乱
# 优化选项 -O 有 1~3   -Os 是平衡  -Oz 是最小体积
set(CMAKE_C_FLAGS_INIT "${C_TARGET_FLAG} ${COMPILE_RULE_FLAG} \
    -xc -std=c99 -fno-rtti -funsigned-char -fshort-enums -fshort-wchar \
    -gdwarf-4 -O1 -ffunction-sections -w")

# 设置 C++ 编译器选项(没有用到 c++ 所以不用配置)
#set(CMAKE_CXX_FLAGS_INIT ${CMAKE_C_FLAGS_INIT})

# 设置ASM编译器选项
# 注意: -masm=auto 选项是 MDK 的 link 分页里没有的参数,需要加上  -g 是debug 用的加不加都行
set(CMAKE_ASM_FLAGS_INIT "${ASM_TARGET_FLAG} ${COMPILE_RULE_FLAG} \
        -masm=auto -c -gdwarf-4 ")
# 第二种方式 配套显示执行 armasm.exe 为 ASM 编译器的方法,看上起更清晰一些
#set(CMAKE_ASM_FLAGS_INIT "${ASM_TARGET_FLAG} --cpu=Cortex-M3")



# 设置链接器选项
# 这些参数再 ARMCC 文档里么有,但 MDK 的 link 分页有,
# 使用忽略所有警告的配置时没有 --map 及其之后的内容, 这里根据需要保留了一些信息,在 testF4.map 中可以看到
set(CMAKE_EXE_LINKER_FLAGS_INIT  " \
            ${LINKER_TARGET_FLAG} \
            --strict \
            --scatter ${SECTIONS_SCRIPT_PATH} \
            --info sizes --info totals --info unused --info veneers \
            --summary_stderr \
            --info summarysizes"
        )


# project settings
project(testF4 C CXX ASM)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)

#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)


include_directories(Core/Inc Drivers/STM32F4xx_HAL_Driver/Inc Drivers/STM32F4xx_HAL_Driver/Inc/Legacy Drivers/CMSIS/Device/ST/STM32F4xx/Include Drivers/CMSIS/Include)

add_definitions(-DUSE_HAL_DRIVER -DSTM32F407xx)

file(GLOB_RECURSE SOURCES "startup/*.*" "Drivers/*.*" "Core/*.*")
# 对于混合兼容的环境,需要屏蔽各种编译环境引起的文件“干扰”,通过 list(REMOVE_ITEM) 命令移除不同编译环境下的干扰文件
# 在原来 CubeMX 自动生成的 gcc 编译环境目录上,附加 ARMCC 编译需要的文件
file(GLOB_RECURSE SOURCES ${SOURCES} "MDK-ARM/startup_stm32f407xx.s")
# 将由 CubeMX 生成的 GCC 编译环境中的会干扰ARMCC环境的文件,放在 EXCLUDE_SRCS 自定义列表中
file(GLOB_RECURSE EXCLUDE_SRCS
        "Middlewares/Third_Party/RealThread_RTOS/libcpu/arm/cortex-m3/context_gcc.S"
        "startup/*.*"
        "Core/Src/syscalls.c"
        "STM32F103C8Tx_FLASH.ld"
        )
# 从源文件列表(SOURCES)中剔除干扰文件(EXCLUDE_SRCS)
list(REMOVE_ITEM SOURCES ${EXCLUDE_SRCS})


add_executable(${PROJECT_NAME} ${SOURCES} ${LINKER_SCRIPT})

set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
set(ELF_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf)

# 使用 armclang 自带的 fromelf 工具,实现 elf 转 hex
set(ARMCC_fromelf fromelf.exe)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
        # 相当于fromelf.exe" --i32combined --output="xxx/testF4.hex" "xxx/testF4.elf"
        COMMAND ${ARMCC_fromelf} --i32combined --output="${HEX_FILE}" "${ELF_FILE}"
        COMMENT "Building ${HEX_FILE}"
        )

## 使用了 gcc 的 arm-none-eabi-objcopy 工具实现 elf 转 hex 和 bin, 跟 armclang 不是一脉
#set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
#add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
#        COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}> ${HEX_FILE}
#        COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}> ${BIN_FILE}
#        COMMENT "Building ${HEX_FILE} Building ${BIN_FILE}")

3.3 替换文件需要注意的事项

根据自己项目的不同需要更改的地方

image-20230416110210966 image-20230416110246331 image-20230416112227865

4 使用CubeMX生成MDK文件

打开CubeMX,如果你之前的关了,那么从下面这里进入

image-20230416110437698

将SW4STM32换成MDK,然后生成

image-20230416110646289

Keil打开生成的工程,并进行编译(这里编译环境要看一下,是不是6.**以上的,如果使用AC5是不行的)

image-20230416110849413

编译运行一下,然后就可以关掉Keil了

5 Clion编译运行测试

重新加载一下CMakeLists

image-20230416111311932 image-20230416111354506

如果这里没有出现锤子,那么就进去更换一下文件

image-20230416111029278

image-20230416111103861

打开后,点一下,它会自动让你选择正确的,默认的是带.elf的,这里就是选一个不带.elf的

image-20230416111050867

点击锤子开编译

image-20230416111440107

点击三角,进行烧录运行

image-20230416111652135

如果出现错误,需要去找一下st_nucleo_f103rb.cfg的位置,并打开

image-20230416111850366

image-20230416111742908

再次烧录就可以了

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
c 环境配置 colin 主要包括三个步骤:安装编译器、配置环境变量和测试编译器。 首先,安装编译器。在安装 c 环境之前,我们需要先下载对应的编译器软件。常用的 c 编译器有 gccclang、MSVC 等。根据个人需求选择适合自己的编译器,并下载对应的安装包。然后,按照安装向导进行安装即可。安装完成后,我们就拥有了一个可用的 c 编译器。 接下来,配置环境变量。环境变量的配置可以使得我们在任意目录下都能够直接使用 c 编译器。首先,找到我们安装的编译器安装目录。然后,将该目录添加到系统的环境变量中。具体的配置步骤可以根据操作系统的不同而有所差异,但一般都是在控制面板或者系统设置中找到“环境变量”选项,然后添加编译器安装目录到系统的“PATH”变量中。配置完成后,我们就可以在任意目录下打开命令行终端,输入编译器命令来编译和运行 c 程序。 最后,测试编译器。经过以上两个步骤的配置,我们就可以测试我们的 c 编译器是否正常工作了。在任意目录下新建一个文本文件,将其后缀改为“.c”,比如“test.c”。然后,用任意文本编辑器打开该文件,输入一段简单的 c 代码,比如“#include <stdio.h> int main(){ printf("Hello, world!"); return 0; }”。保存文件后,回到命令行终端,进入该文件所在的目录,输入编译命令,如“gcc test.c -o test”,然后按回车键进行编译。如果没有出现错误信息,说明我们的 c 编译器已经成功配置。 综上所述,通过安装编译器、配置环境变量和测试编译器三个步骤,我们可以完成 c 环境的配置,从而能够顺利编译和运行 c 程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值