使用Eclipse IDE for GNU ARM搭建STM32的开发环境

01:下载必要的文件

1.1 安装java运行环境,这一步比较简单,就不细说了。

1.2 需要下载四个文件gnumcueclipse、gcc-arm-none-eabi、xpack-windows-build-tools、jlink



gnumcueclipse:是在Eclipse + CDT的基础上集成了Arm和RISC-V处理器开发的插件(GNU MCU Eclipse),对STM32F0、STM32F1、STM32F2等支持比较完善,official site在这里:Eclipse Embedded CDT | Eclipse Embedded CDT (C/C++ Development Tools)™

gcc-arm-none-eabi:这个没啥好说的,gcc arm工具链。

xpack-windows-build-tools:windows下的make工具,如果在windows下需要使用linux版本的make,需要安装cygwin或者mysys2虚拟环境。

jlink:这个不是必须的,对于STM32如果你没有jlink的话,也可以使用flymcu这类工具从串口1下载程序,或者使用DAP Link这类开源的调试器。

以上需要的文件已存至天翼云盘(下载不限速),有需要的可直接下载:天翼云盘 珍藏美好生活 家庭云|网盘|文件备份|资源分享 (访问码:fu2a)。

02:软件安装

2.1 这一步比较简单,这三个都是绿色软件,直接解压到想要存放的路径即可,如果想要在任意地方使用make和arm-none-eabi-gcc还可以把他俩安装目录的bin文件夹添加到path。
!!! 添加环境变量不是必须的,因为即使配置了PATH,Eclipse里面还是需要再配置一遍。!!!



如果添加了环境变量,可以使用make和arm gcc的 --version输出下版本信息,以判断是否成功添加。


2.2 eclipse安装完成后,还可以根据自己的电脑配置修改下启动配置文件“eclipse.ini”(以下是8G内存的配置参数,仅供参考),如果对java虚拟机不了解的话也可以跳过这一步。

-Xms1024m
-Xmx2048m
-XX:PermSize=256m
-XX:MaxPermSize=256m
-Xverify:none

2.3 eclipse的基本配置,这一步是将步骤(2.1),安装的编译工具配置到eclipse,
选择Window -> Preference打开eclipse的设置窗口。



切换到MCU列表,对带有全局(Global)属性的配置项目进行修改。
在ARM Toolchains Paths中,Default toolchain可以选择任意的,前提是下回创建工程时需要选择被配置的那个,
因此为了方便可以配置下拉列表的第一个,“GNU MCU Eclipse ARM Enbedded GCC”。
Toolchain name 无法修改,保持默认即可。
Toolchain folder 设置到arm-gcc安装目录的bin文件夹。


切换至Global Build Tools Path,此处填入make工具安装路径下的bin文件夹。
如果安装了MinGW,可以把/mingw64/bin/mingw32-make.exe复制一份并重命名成make.exe,这里的路径就可以填写MinGW的bin目录:/mingw64/bin/。


如果安装了jlink,还可以配置下jlink gdb路径,切换至 Global SEGGER J-Link Path,在Executable中填入JLinkGDBServerCL.exe,在Folder中填入你的jlink安装路径。

03:建立项目

3.1 打开eclipse,选择File -> new -> C/C++ Project -> C Managed Build,如果想使用C++开发的话,也可以选择下面一行的C++ Managed Build,
(但是需要考虑的是这个C++标准支持的不是很全,且生成的二进制文件较大),然后点击Next即可进入工程建立界面。




3.2 这里是对工程的基本信息进行配置,例如工程名称,保存路径,模板代码等。
Project name:可以按照需求填写;
Location:可以选择default location(即设置的工作区文件夹)或者自定义的路径;
Project type:该列表下有很多ST系列MCU的模板代码,可以按照自己的设备平台选择,这里指定了平台后,会有对应的STD库或者HAL库被自动添加;
Toolchains:这里使用ARM Cross GCC交叉编译器即可,然后点击NEXT


3.3 对芯片配置进行修改。
Chip family 选择所使用的芯片系列即可。
Flash size(KB) 芯片的Flash容量,这后期在里根据芯片设置,如果不清楚可以任意写,ldscript中还是可以修改的。
RAM size(KB) 芯片的RAM大小,同上。
Clock(Hz): 有晶振的填HSE时钟,没晶振的填HSI时钟,该配置实际上没啥卵用,在STM32的初始化文件system_stm32f0xx.c中可以修改,即使在此处配置了,也不会同步更新到模板代码中。
Content:提供了Blinky 和Empty两个demo,一个是闪灯程序,另一个则是空项目,第一次开始可以选择Blinky熟悉下工程结构。
Use system calls: 这里是标准库的系统调用,主要为fopen,stdin,stdout等标准库函数,如果需要在eclipse console中打印log,可以选择Semihosting;如果习惯使用Jlink RTT也可以选择POSIX或者Freestanding。
Trace output:如果在Use system calls中没有选择Semihosting,这一部分的修改是不生效的,前一步选择了Semihosting后这里可以选择STDOUT和DEBUG通道,功能上二者没有区别(一个是RUN的输出,另一个是DEBUG的输出)。
下面的勾选框中,可以把Enable -Werror去除,因为ST的标准库有些编码不规范的地方,去除Werror避免编译报错。


点击NEXT后可以对项目的文件夹名称进行修改,这里也可以使用默认的。


再次点击NEXT后可以选择创建的版本,一般而言会有debug和release两个版本,同时勾选Debug和release会创建一条宏定义,用以切换代码版本,这里只选个release即可。


接下来选择arm工具链,使用之前配置好的,最后点击Finish即可创建工程。
 

04:修改项目

4.1 打开main.c,屏蔽掉trace_puts、puts、fprintf、trace_printf打印函数。




4.2 修改连接脚本,打开ldscripts/mem.ld,在MEMORY中仅保留RAM和FLASH(根据你的芯片决定)

4.3 打开sections.ld,删除SECTIONS中之前在MEMORY中移除的段,堆栈大小也可以在此修改。

__stack = ORIGIN(RAM) + LENGTH(RAM);

_estack = __stack; 	

__Main_Stack_Size = 1024 ;

PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;

__Main_Stack_Limit = __stack  - __Main_Stack_Size ;

PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;

_Minimum_Stack_Size = 256 ;

PROVIDE ( _Heap_Begin = _end_noinit ) ;
PROVIDE ( _Heap_Limit = __stack - __Main_Stack_Size ) ;

ENTRY(_start)

SECTIONS
{
    .isr_vector : ALIGN(4)
    {
        FILL(0xFF)

        __vectors_start = ABSOLUTE(.) ;
        __vectors_start__ = ABSOLUTE(.) ; /* STM specific definition */
        KEEP(*(.isr_vector))     	/* Interrupt vectors */
          
        *(.after_vectors .after_vectors.*)	/* Startup code and ISR */
    } >FLASH

    .inits : ALIGN(4)
    {
        __data_regions_array_start = .;
        
        LONG(LOADADDR(.data));
        LONG(ADDR(.data));
        LONG(ADDR(.data)+SIZEOF(.data));

        __data_regions_array_end = .;
        
        __bss_regions_array_start = .;
        
        LONG(ADDR(.bss));
        LONG(ADDR(.bss)+SIZEOF(.bss));
        
        
        __bss_regions_array_end = .;

		KEEP(*(.init))
		KEEP(*(.fini))

		. = ALIGN(4);


		PROVIDE_HIDDEN (__preinit_array_start = .);
        
		KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))

		KEEP(*(.preinit_array_platform .preinit_array_platform.*))
        
		KEEP(*(.preinit_array .preinit_array.*))

		PROVIDE_HIDDEN (__preinit_array_end = .);

		. = ALIGN(4);

		PROVIDE_HIDDEN (__init_array_start = .);
		KEEP(*(SORT(.init_array.*)))
		KEEP(*(.init_array))
		PROVIDE_HIDDEN (__init_array_end = .);

		. = ALIGN(4);

		PROVIDE_HIDDEN (__fini_array_start = .);
		KEEP(*(SORT(.fini_array.*)))
		KEEP(*(.fini_array))
		PROVIDE_HIDDEN (__fini_array_end = .);

    } >FLASH

    .text : ALIGN(4)
    {
        *(.text .text.*)			
 
        *(.rodata .rodata.* .constdata .constdata.*) 		

        *(vtable)					/* C++ virtual tables */

            KEEP(*(.eh_frame*))


        *(.glue_7)
        *(.glue_7t)

    } >FLASH


	.ARM.extab : ALIGN(4)
   	{
       *(.ARM.extab* .gnu.linkonce.armextab.*)
   	} > FLASH
   	
    . = ALIGN(4);
   	__exidx_start = .;   	
   	.ARM.exidx : ALIGN(4)
   	{
       *(.ARM.exidx* .gnu.linkonce.armexidx.*)
   	} > FLASH
   	__exidx_end = .;
   	
    . = ALIGN(4);
    _etext = .;
    __etext = .;
    
    _sidata = LOADADDR(.data);

    .data : ALIGN(4)
    {
    	FILL(0xFF)

        _sdata = . ;        	/* STM specific definition */
        __data_start__ = . ;
		*(.data_begin .data_begin.*)

		*(.data .data.*)
		
		*(.data_end .data_end.*)
	    . = ALIGN(4);

        _edata = . ;        	/* STM specific definition */
        __data_end__ = . ;

    } >RAM AT>FLASH

    .bss (NOLOAD) : ALIGN(4)
    {
        __bss_start__ = .;     	/* standard newlib definition */
        _sbss = .;              /* STM specific definition */
        *(.bss_begin .bss_begin.*)

        *(.bss .bss.*)
        *(COMMON)
        
        *(.bss_end .bss_end.*)
	    . = ALIGN(4);
        __bss_end__ = .;        /* standard newlib definition */
        _ebss = . ;             /* STM specific definition */
    } >RAM
    
    .noinit (NOLOAD) : ALIGN(4)
    {
        _noinit = .;
        
        *(.noinit .noinit.*) 
        
         . = ALIGN(4) ;
        _end_noinit = .;   
    } > RAM
    
    PROVIDE ( end = _end_noinit ); /* was _ebss */
    PROVIDE ( _end = _end_noinit );
    PROVIDE ( __end = _end_noinit );
    PROVIDE ( __end__ = _end_noinit );
    
    ._check_stack : ALIGN(4)
    {
        . = . + _Minimum_Stack_Size ;
    } >RAM

    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
    .stab.excl     0 : { *(.stab.excl) }
    .stab.exclstr  0 : { *(.stab.exclstr) }
    .stab.index    0 : { *(.stab.index) }
    .stab.indexstr 0 : { *(.stab.indexstr) }
    .comment       0 : { *(.comment) }
} 

4.4 编译前的相关配置,点击下Project Explorer中的项目名称,在Project -> Properties -> C/C++ Build Settings中做出如下配置:



在Create Flash Image中可以选择输出Hex或者bin文件。


在C/C++ Build -> Behavior 中将并行编译打开(链接还是单线程的),这样可以提高编译速度,一般项目配合8线程处理器,4~5秒即可完成。


以上配置完成后,基本可以进行编译了(makefile由eclipse根据配置自动生成),编译完成后有可执行文件各个段的占用空间信息。
 

05:程序下载




 

06:基于标准库(StdPeriph_Lib)(HAL库也同样适用)建立工程

6.1 一些准备工作。
基于标准库在eclipse下建立项目需要STM32F0xx_StdPeriph_Lib_V1.5.0 1.zip,
没有的话可以在这里下载,链接:天翼云盘 珍藏美好生活 家庭云|网盘|文件备份|资源分享 (访问码:fu2a)。



解压后的目录应该与下图一致


6.2 eclipse创建项目
打开eclipse,选择File -> new -> Project...


这里以c语言工程为例,选择C Project,然后点击Next。


第一步:在“Project name”中输入项目的名称;第二步:在“Toolchains”选择合适的编译工具,这里选择ARM Cross GCC
第三步:在“Project type”中选择Hello World ARM C Project;第四步:点击Next进入下一步骤。(这里需要注意的是一定要先选择Toolchains,再选择Project type,否则下面的Finish按钮到后面的最后一步时还是不可用的灰色)


基本设置,把“Linker semi-hosting options”清空(这里不使用semihosting提供的stdin stdout重定向(且hello world工程也缺少相关文件),如需打印log可以使用RTT或者串口),其他的默认即可,点击Next进入下一步骤。


项目分支设置,可配置debug和release,二者在编译/生成bin文件无明显差别(在makefile中通过if DEBUG指定优化等级),这里我仅勾选Release,实际中可根据需要决定。


最后看下编译工具链路径是否正确,如果OK,那么下面的Finish按钮就变成可点击状态,点击Finish即可。


主界面左侧出现项目树,并且main.c如下所示,那么基本的项目框架就有了,下面就是一些简单的参数配置。


新建startup文件夹,复制STM32F0xx_StdPeriph_Lib_V1.5.01库中的启动文件进去,具体的路径如下(以STM32F072系列的MCU为例),同时将startup_stm32f072.s的后缀名改成大写的S,变成startup_stm32f072.S:
\Libraries\CMSIS\Device\ST\STM32F0xx\Source\Templates\gcc_ride7\startup_stm32f072.s

需要改成大写.S的原因在这里window -> preference -> c/c++ ->file types,eclipse默认的file types只有大写的.S文件作为汇编文件类型,但你也可以点击“new”,新建一个小写.s的汇编文件类型。


新建ldscript文件夹,复制STM32F0xx_StdPeriph_Lib_V1.5.01库中的链接脚本进去,具体的路径如下(以STM32F072系列的MCU为例):
\Projects\STM32F0xx_StdPeriph_Templates\TrueSTUDIO\STM32F072\STM32F072VB_FLASH.ld


在项目下新建include文件夹。

添加初始化代码和必要的外设支持库,在src目录新建cmsis文件夹,复制system_stm32f0xx.c进入,该文件在std库中的路径:\Projects\STM32F0xx_StdPeriph_Templates\system_stm32f0xx.c。
在include目录下新建cmsis文件夹,复制以下文件进入:
core_cm0.h 源路径\Libraries\CMSIS\Include\core_cm0.h
stm32f0xx.h 源路径\Libraries\CMSIS\Device\ST\STM32F0xx\Include\stm32f0xx.h
system_stm32f0xx.h 源路径\Libraries\CMSIS\Device\ST\STM32F0xx\Include\stm32f0xx.h\system_stm32f0xx.h
stm32f0xx_conf.h 源路径\Projects\STM32F0xx_StdPeriph_Templates\stm32f0xx_conf.h 这个文件也可以不加,自己在项目中按需include也很好。
以下两个文件有部分修改,以网盘链接形式提供,链接:天翼云盘 珍藏美好生活 家庭云|网盘|文件备份|资源分享 (访问码:fu2a)。
arm_asm.h
cmsis_gcc.h

在src目录创建stm32f0-stdperiph文件夹,复制标准库中\Libraries\STM32F0xx_StdPeriph_Driver\src下所有.c文件进入。
在include目录创建stm32f0-stdperiph文件夹,复制标准库中\Libraries\STM32F0xx_StdPeriph_Driver\inc下所有.h文件进入。
添加一些日志输出的组件,以便打印“Hello World”,这里我使用了SEGGER RTT,最终的项目结构如下图所示。


从上一步的项目树可以看到一些打红色叉的警告信息,这就需要修改include path等配置项以消除这些错误。
点击左侧项目树的项目名称,保证选中当前项目,选择Project -> Properties


在Resource中,将Text file encoding改成Other:UTF-8,点击右下角Apply,如果之前配置过全局编码,这一步可以省略。(每一步骤完成或页面切换时,建议点击右下角的Apply保存配置项)


在C/C++ Build -> Behavior -> Build settings中,勾选Enable parallel build 选择Use paralleljobs,使用并行编译。


同时也需要留意Configuration选择为需要被配置的项目,由于先前仅创建了Release,因此这里只有一个选项。

Logging -> Enable build logging 可以关掉,没啥用处。


接下来是关于MCU ARM核基本信息设置,这里比较重要,不能选择“Toolchain default”;如果不清楚需要查询自己所用芯片的手册,这里以stm32f072为例,cortex m0的arm核心,架构armv6-m,只支持thumb/2指令集,不支持非对其访问;那么
C/C++ Build -> Settings Tool Settings -> Target Processor 需要按如下参数配置。


如果跳出需要重新编译工程的对话框,选择“NO”即可,因为没配置完成,编译也会有很多Error或Warning。


C/C++ Build -> Settings Tool Settings -> Optimization 为一些优化选项,可以按照需求配置,


C/C++ Build -> Settings Tool Settings -> Warnings 为一些编译警告,推荐设置如下图:


C/C++ Build -> Settings Tool Settings -> Debuging 是一些调试信息,只会存在于elf文件中,objcpy后的bin文件是没有这些信息的,使用jlink的话,Debug format选择gdb即可,Debug level选项下的区别可以自行网络查找,我这里就不使用debug信息了。


C/C++ Build -> Settings Tool Settings -> GNU ARM Cross Assember 汇编选项全部保持默认即可。


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Compiler -> Preprocessor 添加必要的宏定义

STM32F072
USE_STDPERIPH_DRIVER
HSE_VALUE=16000000

这三个宏定义都在stm32f0xx.h是被使用,其中'STM32F072'是必须的,另外两个可选。



C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Compiler -> Includes 添加include path


这里也可以使用相对路径。


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Compiler -> Optimization 语言标准选择c99或者c11都可以,在gnu编译器里,选择gnu99或gnu11


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Compiler -> warnings 这三个建议打开,编译时的warning可能会在运行时变成error,有必要提前处理。


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Linker -> General
Script files 添加先前复制进项目的STM32F072VB_FLASH.ld文件,只需输入文件名即可。
链接选项 -nostartfiles -Xlinker --gc-sections也需要勾选下。


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Linker -> Libraries
只需要修改 Library search path,设置之前新建的ldscript文件夹,使用相对路径"../ldscript"或者eclispe定义的宏${workspace_loc:/${ProjName}/ldscript}都可,Libraries栏下其他项目保持默认。


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross C Compiler -> Miscellaneous
勾选newlib-nano


C/C++ Build -> Settings Tool Settings ->GNU ARM Cross Create Flash Image -> General
这里可以选择生成bin文件orhex文件,我这里使用bin文件。(jlink下载时使用的是elf文件,因此这里选择bin文件或hex文件取决于其他烧写工具的要求), C/C++ Build栏的修改就此完成了,其他的保持默认即可。


C/C++ General -> Paths and Symbols -> Source Location
点击Add Folder,把我们的启动文件所在的文件夹也添加进来。

可以添加.c文件编译的过滤器,可以屏蔽掉当前用不到的c文件,增加编译速度。

按照如下步骤点击鼠标

选择需要屏蔽的文件,对于Hello World工程来说,用不到外设库,可以全部屏蔽(以后用到需要到这里解除过滤)。

最后保存即可,可以看到Includes增加了我们自定义的路径,src目录下红色的叉也消失了(如果未消失,可按F5刷新)。


最后点击Project -> Build Project

可以看出,开启并行编译后速度飞快。

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一百编程网朱老师

谢谢大爷谢谢大爷谢谢大爷谢谢大

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

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

打赏作者

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

抵扣说明:

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

余额充值