1) 编译STM32源代码的gcc-arm编译器是32位的(我用的gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2),交叉编译 执行时需要需要32位的glibc库, CentOS安装光盘中有相应的库,下面的命令可以安装
# rpm -ivh glibc-2.12-1.192.el6.i686.rpm nss-softokn-freebl-3.14.3-23.el6_7.i686.rpm
或: yum install glibc.i686 ---nss-softokn
2) eclipse luna和CDT都是从eclipse官方网站下载的64位版本,
eclipse luna本来有CDT插件了, 但是安装的不完全,缺少安装armgun插件需要的依赖组件
所以重新安装CDT插件(cdt-8.6.0.zip),安装全部能够安装的组件
wget http://mirrors.neusoft.edu.cn/eclipse/tools/cdt/releases/8.6/cdt-8.6.0.zip
然后在eclipse的help菜单中安装
help->install new software...->
3) 安装支持STM32开发的插件armgun插件ilg.gnuarmeclipse.repository-2.12.1-201604190915.zip,插件内置STM32F1x的工程模板,使用了ST提供的V3.5固件库
插件安装后,新建C项目时, 就可以选择相应的模板了
值得一提的是,尽管模板使用了ST官方的V3.5固件库, 但是启动文件和Keil MDK 的启动文件是不同的,armgun插件的启动文件更多地使用了的C语言代码来实现程序的启动,基本未用汇编
代码中程序的真正入口为 _start, 位于_startup.c文件中, main函数在_start中被调用
_start在哪里被调用呢?
-------- 在exception_handlers.c文件中, Reset_Handler将调用_start, 在非nake模式(调试版本)下, 直接调用_start(), 在Release版本下,嵌入汇编跳转到_start
Reset_Handler又是在哪里被调用呢?
------ 文件vectors_stm32f0xx.c中提供了一个中断向量表:pHandler g_pfnVectors[], 摘录部分代码如下, Reset_Handler正是位于终端向量表中的复位向量:
************************************************************************************************************
__attribute__ ((section(".isr_vector"),used))
pHandler g_pfnVectors[] =
{
// Core Level - CM0
(pHandler) &_estack, // The initial stack pointer
Reset_Handler, // The reset handler
NMI_Handler, // The NMI handler
*******************************************************************************************************
------ 在连接脚本 mem.ld 给出了存储器资源的配置
------ 在连接脚本 sections.ld 给出了代码中各种section的链接位置
在非nake模式(支持在线调试调试, GDB估计会先行提供一段启动代码)下,程序入口被指定为ENTRY(_start)
在Release版本中(nake), 连接脚本section当中, Reset_Handler向量被放在 .after_vectors 代码段的第一项, 以下为摘录的SECTIONS配置片段
*******************************************************************************************************************************
SECTIONS
{
/*
* For Cortex-M devices, the beginning of the startup code is stored in
* the .isr_vector section, which goes to FLASH.
*/
.isr_vector : ALIGN(4)
{
FILL(0xFF)
__vectors_start = ABSOLUTE(.) ;
__vectors_start__ = ABSOLUTE(.) ; /* STM specific definition */
KEEP(*(.isr_vector)) /* Interrupt vectors */ ===============这里就算上面中断向量表的安装位置===========
KEEP(*(.cfmconfig)) /* Freescale configuration words */
/*
* This section is here for convenience, to store the
* startup code at the beginning of the flash area, hoping that
* this will increase the readability of the listing.
*/
*(.after_vectors .after_vectors.*) /* Startup code and ISR */
} >FLASH
*******************************************************************************************************************************
4) zylincdt-3005ca1是一个嵌入式开发插件(zylincdt-3005ca1.zip), 负责与嵌入式gdbserver沟通, 插件安装时需要先解压,然后使用eclipse 的local直接定位到目录com.zylin.cdt.updatesite进行安装
***其实
(1)CDT插件已经自带了用于嵌入式调试的组建 GDB Hardware Debugging的组建,可以支持嵌入式调试了
(2)ilg.gnuarmeclipse.repository-2.12.1-201604190915.zip插件中也携带了更好的GDB OPENOCD Debugging 用于与OPENOCD作为gdbserver配合进行调试
(2)ilg.gnuarmeclipse.repository-2.12.1-201604190915.zip插件中还携带了更好的GDB Segger J-link Debugging 用于与Segger J-link server作为gdbserver配合进行调试
5) Openocd编译安装,向下指挥J-link下载器的工作,向上提供4444端口与telnet沟通或者与gdb程序沟通
https://github.com/corecode/openocd-swd 增加了补丁, 支持SWD方式下载器
程序在线调试时,它实际上就是一个gdbserver的角色(因为嵌入式开发中, 如果是不带嵌入式linux的系统, 那就没有对应的gdbserver)
----------------------------------------------------------安装与测试
#!/bin/sh
rpm -ivh telnet-0.17-48.el6.x86_64.rpm
rpm -ivh libusb1-devel-1.0.9-0.7.rc1.el6.x86_64.rpm
tar -zxvf openocd-0.10.0.tgz
cd openocd-0.10.0
./configure --enable-jlink
make
make install
openocd -f /usr/local/share/openocd/scripts/interface/jlink.cfg -f /usr/local/share/openocd/scripts/target/stm32f1x.cfg
#使用telnet连接到openocd, 执行命令
#gdb调试器就是通过4444端口向openocd发送控制命令的
tenet 127.0.0.1 4444
>halt
>flash write image erase stm32_.hex # 变成操作
>reset
-------------------------------------------------------------
6) org.eclipse.cdt.embsysregview_update_site.zip是一个用于在线调试查看MCU内部IO寄存器的插件, 在线调试时可以查看并修改寄存器的值
在eclipse->window->show view->other->debug->embsys registers中打开窗口
窗口左上角的按钮可以选择芯片类型---------------------就像keil 51中查看/修改端口寄存器的功能
7) 创建工程向导中,高级设置,可以指定工具链的位置, 也可以在工程属性中去设置, 过程如下:
1> 新建工程: new->C Project->Excuteable->STM32Fxxx C/C++ Project //根据你的芯片型号选择对应的工程模板就可以了
2> 环境变量设置: 鼠标右击工程节点->Properties->c/c++ Build->Evironment //修改PATH环境变量, 添加指向交叉编译器gcc-arm-none-eabi-5_4-2016q3-20160926-linux的bin目录位置
3> 是指makefile的命令解释器(工程模板自动生成的解释器,找不到,无法编译): 鼠标右击工程节点->Properties->c/c++ Build->Builder settins, 去掉Use default build command勾,填写make,使用主机自带的make
4> 编译: 鼠标右击工程节点->Build Project 就完成了工程编译
--使用c++工程向导生成的工程向导,生成工程, Build Project是灰色的, 不能编译, 不知道啥原因
5)调试: 鼠标右击工程节点->Properties->Debug As->Debug Configrations->GDB openOCD Debugging->new 新建一个调试配置项, 系统已经帮你配置好了默认的openOCD命令参数了, 除非你了解个参数意义,否则建议不要动
对于STM32F1xx芯片, 使用如下命令启动: 不过我在虚拟机下启动失败! 在飞虚拟机下成功!(CentOS6.8_x64)
在openocd -f /usr/local/share/openocd/scripts/interface/jlink.cfg -f /usr/local/share/openocd/scripts/target/stm32f1x.cfg
我在https://www.segger.com/downloads/jlink/jlink-5.0.12.x86_64.rpm
下载rpm安装包, 安装后, 虚拟机player->可移动设备->segger jlink 连接后, jlink-OB将从windows断开,被虚拟机centos接管
执行: JLinkGDBServer -select USB -device STM32F103C8 -if SWD -speed 1000 -noir
命令行参数是从windows下jlink debug server 图形界面上抄的, 运行结果如下:
SEGGER J-Link GDB Server V5.00l Command Line Version
JLinkARM.dll V5.00l (DLL compiled Aug 7 2015 15:47:21)
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 2331
SWO raw output listening port: 2332
Terminal I/O port: 2333
Accept remote connection: yes
Generate logfile: off
Verify download: off
Init regs on start: off
Silent mode: off
Single run mode: off
Target connection timeout: 0 ms
------J-Link related settings------
J-Link Host interface: USB
J-Link script: none
J-Link settings file: none
------Target related settings------
Target device: STM32F103C8
Target interface: SWD
Target interface speed: 1000kHz
Target endian: little
Connecting to J-Link...
J-Link is connected.
Firmware: J-Link ARM-OB STM32 compiled Aug 22 2012 19:52:04
Hardware: V7.00
S/N: 20090928
Feature(s): RDI,FlashDL,FlashBP,JFlash,GDBFull
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 2331
Connecting to target...Connected to target
Waiting for GDB connection...
使用telnet 127.0.0.1 2331 可以连接
********* 可以用JLinkExe.只能烧写二进制 .bin文件。用的是loadbin指令
**** arm-none-eabi-gdb 是32位系统, 需要安装一个依赖包如下, 这个我搞了好久才找到原因
# yum install ncurses-libs.i686
配图说明, 为了避免麻烦, 我在终端窗口始终运行一个GDBserver'
JLinkGDBServer -select USB -device STM32F103C8 -if SWD -speed 1000 -noir
debug配置中, 就不用再启动JLinkGDBServer了:
注意RAM application 打勾, 表示在内存中调试程序 (DEBUG 版本)