观海 发表于 2025-10-11 07:47

手把手教你用CLion进行CW32开发

最近CLion对非商业用途免费了,我立马下载了最新的CLion2025,现在针国产武汉芯源半导体的CW32单片机搭建CLion+GCC+CMake开发环境。



CLion是一款由 JetBrains开发的跨平台集成开发环境(IDE),专门为C和C++设计。以其智能编码辅助、易用的项目管理和强大的内置工具(如调试器、静态分析工具、单元测试框架)而著称,支持远程协作和嵌入式开发。
作为嵌入式工程师,在实际使用会发现后较Keil(MDK)在编写代码上的体验提升极大,但是在用外部调试器调试外部单片机时确实没有Keil(MDK)那么强大。
下面对他们列个表格进行主要差别对比:

(来源:https://gitee.com/lcsc/skystar-board-templates 开发文档)



1.环境搭建所用的软硬件
1.1 软件环境
1. Windows 10
2. CLion 2025 (下载地址:https://www.jetbrains.com/clion/ 自行下载安装)
3. GNU Arm Embedded Toolchain交叉编译器
4. Mingw-w64 GCC for Windows 64
5. CMake(CLion默认自带)
1.2 硬件环境
1. CW32F030核心板
2. WCH-Link DAP



2.软件安装配置
2.1 GNU Arm Embedded Toolchain交叉编译器
arm-none-eabi-gcc 是一个专门为ARM架构微控制器设计的交叉编译工具链。所谓“交叉编译”,是指编译过程发生在一个平台(比如你的Windows或Linux开发主机)上,但生成的二进制代码是为了在另一个平台(比如ARM Cortex-M微控制器)上运行。“none-eabi”部分意味着它生成的代码不依赖于任何操作系统,适合直接在硬件上运行,作为对比理解,这里的 arm-none-eabi-gcc 其实就是对标Keil(MDK)里面的AC5,AC6编译器。总的来说,我们用这个主要就是用于编译ARM架构的嵌入式系统代码,生成的是可以直接在ARM微控制器上运行的二进制文件。
进入arm开发者官网,往下滑动选择下载解压可用的ZIP压缩包文件 (当然各位直接下载最新版,当前使用版本并非最新版本)

下载链接: Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer

https://developer.arm.com/downloads/-/gnu-rm



下载好的压缩包文件解压在gcc-arm-none-eabi”文件夹中,并记住文件内“bin”文件的路径,后续需添加到系统环境变量Path中。






添完环境变量后,进行测试,检测是否安装好。



2.2 安装Mingw-w64 GCC
MinGW 是一个用于在Windows上编译和运行应用程序的编译工具集。支持编译标准的C/C++代码,并且适用于开发那些在Windows平台上运行的软件。
点击链接进入到SourceForge官网,往下翻可以找到很多版本的下载链接,选择红色框内型号即可,不同前后缀的具体差异请参考

https://blog.csdn.net/AMDDMA/article/details/111600238

下载链接:

https://sourceforge.net/projects/mingw-w64/files/



同样,将下载好的文件解压到“gcc-arm-none-eabi”文件夹下,记住目录下的“bin”文件路径



进入“bin”文件内找到“mingw32-make”应用程序文件,复制一份并重命名为“make”。这么做有利于在命令行执行make指令,而不是输入mingw32-make。



添加完环境变量后,进行测试,检测是否安装好。



2.3 配置CLion工具链



接下来开始配置工具链,选中设置的栏目中构建,执行,部署 里面的工具链,点击添加,新增一个工具链配置,这里我的命名是MinGW-ARM,这里不使用默认配置的原因是防止影响到普通c程序的编译运行,开发ARM系列单片机时就选择MinGW-ARM配置,开发普通c程序时就选择MinGW。



然后切换到CMake栏目下,确认当前的工具链配置值为我们上面设置的MinGW-ARM,然后就可以点击下方确定按钮来保存设置了。



3.工程模板创建
1. 工程文件目录





• application/
应用层代码,包括主程序 app_main.c、interrupts_cw32f030.c等。
• bspdriver/
板级支持包(BSP),如时钟、延时、定时器、板载资源初始化等。
• moduledriver/
常用模块驱动,如 LED 驱动、按键Button等。
• middlewares/
常用中间件库(如 FreeRTOS、log、Multitimer、软定时器SoftTimer等)。
• libraries/
芯片厂商提供的底层库(CMSIS、外设驱动等)。
• tools/
启动文件、链接脚本、DAP 配置等工具文件。
注意:启动文件、链接脚本官方并没有提供,这是参考其他F030系列芯片去编写的,在这里希望官方以后能支持GCC,
启动文件 startup_cw32f030_gcc.s
链接脚本 CW32F030x_FLASH.ld
2. CMakeLists.txt文件编写(重点)cmake_minimum_required(VERSION 3.20)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)

# 指定交叉编译工具链
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(cw32f030 C CXX ASM)# 修改工程名称
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
# 注意不同类型MCU修改其cortex内核
set(MCPU cortex-m0plus)# TODO: 根据实际MCU修改内核类型,例如cortex-m4

# 浮点运算选项配置
# 取消注释以启用硬件浮点
#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)

# 取消注释以启用软件浮点
add_compile_options(-mfloat-abi=soft)

# 通用编译选项
add_compile_options(-mcpu=${MCPU} -mthumb -mthumb-interwork -specs=nosys.specs)
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)

# 取消注释以消除C++17绝对地址警告
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")

# 根据构建类型设置优化级别
if ("${CMAKE_BUILD_TYPE}"STREQUAL"Release")
message(STATUS "Maximum optimization for speed")
add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}"STREQUAL"RelWithDebInfo")
message(STATUS "Maximum optimization for speed, debug info included")
add_compile_options(-Ofast -g)
elseif ("${CMAKE_BUILD_TYPE}"STREQUAL"MinSizeRel")
message(STATUS "Maximum optimization for size")
add_compile_options(-Os)
else ()
message(STATUS "Minimal optimization, debug info included")
add_compile_options(-Og -g)
endif ()

# 包含头文件目录 - 可修改
include_directories(
      application/
      bspdriver/adc/
      bspdriver/delay/
      bspdriver/rcc/
      bspdriver/timer/
      bspdriver/uart/
      moduledriver/button/
      moduledriver/beep/
      moduledriver/dht11/
      moduledriver/lcd/
      moduledriver/led/
      moduledriver/oled/
      libraries/cmsis/device/
      libraries/cmsis/include/
      libraries/drivers/inc/
      middlewares/
)

# 定义预处理宏
add_definitions(
#      -D USE_STDPERIPH_DRIVER# 使用标准外设驱动
)

# 收集源文件 - 可修改结束
file(GLOB_RECURSE SOURCES
"tools/startup_cw32f030_gcc.s"# 启动文件
"application/*.c"
"bspdriver/adc/*.c"
"bspdriver/delay/*.c"
"bspdriver/rcc/*.c"
"bspdriver/timer/*.c"
"bspdriver/uart/*.c"
"moduledriver/button/*.c"
"moduledriver/beep/*.c"
"moduledriver/dht11/*.c"
"moduledriver/lcd/*.c"
"moduledriver/led/*.c"
"moduledriver/oled/*.c"
"libraries/drivers/src/*.c"
)

# 链接器脚本配置
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/tools/CW32F030x_FLASH.ld)
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=${MCPU} -mthumb -mthumb-interwork --specs=nosys.specs)
add_link_options(-T ${LINKER_SCRIPT})

# 生成ELF可执行文件
add_executable(${PROJECT_NAME}.elf ${SOURCES}${LINKER_SCRIPT})

# 生成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}")



3. 打开工程





4. 编译代码






5. 注意点
Keil(MDK)中编译用的是ARMCC(AC5或AC6),我们这里Clion用的编译器是arm-none-eabi-gcc,他们两者对printf的重定向操作是不一样的,在Keil和CLion中引用到的stdio.h的文件内容是不一样的,在Keil中只需要在fputc函数里添加一个串口输出就可以了,在Clion中也是需要对串口进行重定向的。

#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */


/**
* @brief Retargets the C library printf function to the USART.
*
*/
PUTCHAR_PROTOTYPE
{
    USART_SendData_8bit(DEBUG_USARTx, (uint8_t)ch);

while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);

return ch;
}

/*!
* @brief       Redirect C Library function printf to serial port.
*            After Redirection, you can use printf function.
*
* @param       file:Meaningless in this function.
*
* @param       *ptr:Buffer pointer for data to be sent.
*
* @param       len:Length of data to be sent.
*
* @retval      The characters that need to be send.
*
* @note
*/
int _write(int file, char* ptr, int len)
{
int i;
for (i = 0; i < len; i++)
    {
      __io_putchar(*ptr++);
    }

return len;
}



4.下载程序
在CLion中进行程序下载与代码调试,就目前而言,确实不如在IAR或MDK中便捷。像STM32这类芯片,其生态体系较为成熟完善,相关支持也做得颇为出色,但对于国产芯片,CLion的支持却为数不多。尽管CLion支持通过 OpenOCD方式下载调试代码,然而OpenOCD目前尚不支持CW32芯片,期望后续官方能够增添对其的支持,或者社区中有技术大神能够尝试进行适配。
下载器选用武汉芯源半导体提供的WCH - Link,在MDK - ARM中完成下载器配置后,便可直接进行下载。鉴于本次使用的是GCC工具链进行编译,因此既能够使用官方的hex/bin文件下载工具,也可以使用Openocd或者Pyocd。由于OpenOCD不支持CW32芯片,虽然但通过网络搜索查询发现,可用Pyocd来下载CW32代码。当然,若想将代码下载到芯片中,方法多种多样。接下来,将重点介绍几种本人近期接触到的软件并予以推荐。

方法1 pycod flash 命令行下载
pyocd自行下载即可







方法2 开源MCUProg下载工具
MCUProg工具下载地址 https://gitee.com/Dozingfiretruck/MCUProg

使用pyocd下载一般是进行命令行输入,但是我们这一次选择了一个开源的DAP-Link,Pyocd可视化下载工具,主要太方便了,简单明了。

选择pack文件 (官方一般都有提供)
选择目标芯片
选择目标固件
连接下载器
进行下载









方法3 DAPLinkUtility下载工具
DAPLinkUtility下载地址 https://gitee.com/jhembed/DAPLinkUtility

通用DAPLink上位机,支持30+芯片厂商在线读取、烧录



连接DAP-Link,选择对应的芯片进行下载即可







下载成功



————————————————
版权声明:本文为CSDN博主「CW32生态社区」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2302_81038468/article/details/152277168



页: [1]
查看完整版本: 手把手教你用CLion进行CW32开发