最近clion用的比较多,和mdk一对比,clion实在是趁手了许多,所以一直就像在clion进行开发,之前使用clion编辑代码,mdk进行编译,总觉得优点太low了,所以为了一劳永逸,最近把rtthread在clion中搭建好了,并且集成了编译,下载,debug,这里分享出来以供参考。
目前我也只搭建了编译环境,可以对代码进行编译,并没有搭建起来构建环境,无法对源码进行选择和组织。
RT-Thread官方的构建工具
官方的rt-thread使用的是scons进行构建。
SCons 简介
SCons 是一套由 Python 语言编写的开源构建系统,类似于 GNU Make。它采用不同于通常 Makefile 文件的方式,而是使用 SConstruct 和 SConscript 文件来替代。这些文件也是 Python 脚本,能够使用标准的 Python 语法来编写。所以在 SConstruct、SConscript 文件中可以调用 Python 标准库进行各类复杂的处理,而不局限于 Makefile 设定的规则。
在 SCons 的网站上可以找到详细的 SCons 用户手册。
什么是构建工具
构建工具是一种软件,它可以根据一定的规则或指令,将源代码编译成可执行的二进制程序。这是构建工具最基本也是最重要的功能。实际上构建工具的功能不止于此,通常这些规则有一定的语法,并组织成文件。这些文件用来控制构建工具的行为,在完成软件构建之外,也可以做其他事情。
目前最流行的构建工具是 GNU Make。很多知名开源软件,如 Linux 内核就采用 Make 构建。Make 通过读取 Makefile 文件来检测文件的组织结构和依赖关系,并完成 Makefile 中所指定的命令。
由于历史原因,Makefile 的语法比较混乱,不利于初学者学习。此外在 Windows 平台上使用 Make 也不方便,需要安装 Cygwin 环境。为了克服 Make 的种种缺点,人们开发了其他构建工具,如 CMake 和 SCons 等。
而Clion使用的是cmake进行构建。所以需要把rt-thread使用cmake重新进行构建。
MDK转换到cmake
事实上之前开发项目,也并没有用到scons,大部分情况都是
选择对应芯片的bsp->使用scons生成mdk5工程->在mdk5进行开发
scons只是作为一个生成mdk5工程的工具而已。不知道这是不是大部分开发stm32嵌入式工程师的现状?
那么问题来了,要把MDK的工程转到cmake需要做哪些工作?
编写Cmakelists.txt
首先需要一份基础的Cmakelists
clion2019.1版本之后支持将stm32cube的工程转换为cmakelist,使用该功能可以得到一份基础的cmakelist
#THIS FILE IS AUTO GENERATED FROM THE TEMPLATE! DO NOT CHANGE!
使用这份Cmakelist已经可以对工程进行编译。但对于rt-thread来说,这份cmakelists还不够。
更换编译器带来的变化
MDK使用的是ARM_CC编译器,是一款收费的编译器。用cmake构建一般选择
arm-none-eabideveloper.arm.com该编译器使用的libc为newlib,rt-thread已经为newlib做了适配,编译的时候引入对应的文件,并开启RT_USING_NEWLIB
components/libc/compilers/newlib/libc.c
components/libc/compilers/newlib/libc.h
components/libc/compilers/newlib/libc_syms.c
components/libc/compilers/newlib/stdio.c
components/libc/compilers/newlib/syscalls.c
components/libc/compilers/newlib/termios.h
components/libc/compilers/newlib/time.c
components/libc/compilers/newlib/sys/dirent.h
components/libc/compilers/newlib/sys/mman.h
components/libc/compilers/newlib/sys/statfs.h
components/libc/compilers/newlib/sys/termios.h
更换编译器后,必须要更换对应的启动文件,HAL库中有对应gcc的启动文件
Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc
rt-thread对应的内核port也应切换到gcc版本
libcpu/arm/cortex-m4/context_gcc.S
3.修改部分源码,修改链接脚本(可选)
为什么要修改源码?因为编译器修改后,如果用到了编译器的一些特定的功能,则可能需要修改源码。
比如我这个项目中,正好使用到了外部SRAM,之前在MDK中是这样定义的:
uint8_t
这个是ARM_CC的用法,在gcc需要做如下修改:
uint8_t nodeDataBlockBuff[DATA_BLOCK_BUFF_SIZE] __attribute__((section(".sram")));
并且在链接脚本中创建这个section
MEMORY
{
CODE (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */
RAM1 (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128K sram */
RAM2 (rw) : ORIGIN = 0x10000000, LENGTH = 64k /* 64K sram */
RAM3 (rw) : ORIGIN = 0x68000000, LENGTH = 1024k /* 1024KB sram */
}
SECTIONS
{
...
...
...
/* sram */
.sram :
{
. = ALIGN(4);
*(.sram) /* Startup code */
. = ALIGN(4);
} >RAM3
...
...
...
}