历史上的今天
返回首页

历史上的今天

今天是:2025年04月26日(星期六)

2019年04月26日 | Linux环境开发STM32,从环境到调试

2019-04-26 来源:eefocus

首先简单地描述一下软硬件开发环境。


宿主机:

    操作系统:CentOS7 x86_64 ( grome桌面版 )

    IDE:Eclipse Luna

    JLink驱动:JLink_Linux_V434a

    工具链:GNU-ARM-Toolchains-4.9-2014q4

    GDB:arm-linux-gdb V7.8.1


硬件平台:

    CPU:STM32F103C8T6

    JLink:V8

    USB转串口:Silicon Labs CP2101


    环境的搭配都是比较简单的,编译工具链都比较容易装。这里就不再介绍了。下面就只附上工具链的下载链接。

    https://launchpad.net/gcc-arm-embedded

    IDE环境Eclipse Luna,可以直接在官网上下载。还有CDT,也可以在Eclipse官网上下载。

    有一个比较重要的 GNU ARM Eclipse开发插件,附上个链接。

    http://sourceforge.net/projects/gnuarmeclipse/

    还有一个Eclipse插件,用于GDB调试的,叫Zylin-embedded CDT。下载网址如下:

    http://opensource.zylin.com/zylincdt

    另外,是JLink的驱动,当中包含GDBServer,我用的是V434a的版本,是买其它教学视频的时候附上的。Segger官网上好像已经找不到这个下载链接了,可以百度一下,也可以在Segger官网上下载其它版本的。(只要有正版JLink的其实啥版本都没问题,不过用D版的就要注意一下了,不建议用那么高的版本,不然会用不了)这里就不附链接了。

    最后还有Arm-linux-GDB,可以从下面的官网上下载。编译和安装只要按照README去做就ok了。非常简单。

    http://lists.gnu.org/archive/html/info-gnu/2014-10/msg00018.html


    说了这么久的环境,一开始自己摸索的时候觉得配环境很麻烦,而且也装了很多不必要的东西,后来发现其实只要装上述的就够了,非常简单。希望能帮助大家少走点弯路。下面就用一个简单的示例程序来说一下怎么编译、下载、调试。在原来的windows环境中,我是用Keil uVision5进行开发的,也留了一些代码,所以就直接拿了个串口的发送程序作为这一次的示例,代码如下。


/*=====================================

Include headers

=====================================*/

#include "stm32f10x.h"

 

 

/*=====================================

Functions definition

=====================================*/

void UART_DefaultConfiguration( void );

 

 

/*=====================================

Implementation of functions

=====================================*/

 

/**

  * @brief  

 * Main program.

  * @parameter  

 * None

  * @returnvalue

 * None

  */

int main(void)

{

 UART_DefaultConfiguration();

 

  while(1)

  {

  if( USART_GetFlagStatus( USART1, USART_FLAG_TC ) == SET )

  {

   USART_SendData( USART1, 'A' );

  }

  }  

}

 

 

/**

  * @brief  

 * Initialize the UART with the default configuration.

  * @parameter  

 * None

  * @returnvalue

 * None

  */

void UART_DefaultConfiguration( void )

{

 GPIO_InitTypeDef GPIO_InitStruct;

 USART_InitTypeDef USART_InitStruct;

 

 

 /* Turn on the Clock for the UART and GPIO. */

 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA

            | RCC_APB2Periph_AFIO

            | RCC_APB2Periph_USART1, ENABLE );

 

 

 /* Configure the UART1. */

 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; /* TX */

 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;

 GPIO_Init( GPIOA, &GPIO_InitStruct );

 

 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;

 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; /* RX */

 GPIO_Init( GPIOA, &GPIO_InitStruct );

 

 USART_InitStruct.USART_BaudRate = 115200;

 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

 USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 USART_InitStruct.USART_Parity = USART_Parity_No;

 USART_InitStruct.USART_StopBits = USART_StopBits_1;

 USART_InitStruct.USART_WordLength = USART_WordLength_8b;

 USART_Init( USART1, &USART_InitStruct );

 

 USART_Cmd( USART1, ENABLE );

}


   代码很短,也就八十来行。整个工程的结构如下:

    说明整个工程在windows下是能编译通过的。至于在开发板上的测试就不贴出来了,测试的结果就是在串口上可以看到不断地有字母‘A'输出。


    下面说一下整个工程怎么搬到Linux的开发平台上。

    首先,在Linux上打开Eclipse。新建一个C Project.如果环境搭建成功的话,可以看到有如下选项,在Executable中选择STM32F10x C/C++ Project,工具链就选Cross ARM GCC,填写好工程名字TestSTM32后点击下一步:

    由于我的CPU是STM32F103C8T6,所以Chip family是选STM32f10x Medium Density,Flash大小是64KB,RAM大小是20KB。可以根据自己的硬件实际情况进行填写。其它的可以按图配置。点击下一步:

    其实之后两页都可以按下一步,直到最后这一页,一定要选好工具链是GN Tools for ARM Embedded Processors ( arm-none-eabi-gcc ),并且填好工具链位置。最后点击完成。


   工程建立后,可以看到Eclipse已经将工程建好在Project Explorer中了。


    然后把工程中的src、system、include三个文件夹去掉,只剩下ldscripts文件夹。把我们示例程序的代码复制过来。如下图所示:

    其实为什么要把之前说的三个文件夹删去而不是直接在模板上把代码复制过去呢?其实直接在模板上添代码也行,模板用的也是3.5版本的固件库,但是要是以后固件库升级了或者不想用固件库呢?删去的目的就是为了可以让我们构建的工程更具有自由性。所以我选择直接把原来的工程代码复制过来。

    接下来是比较重要的一步,把启动文件startup_stm32f10x_md.s替换掉,从ST官网上下载的固件库包中,把STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7/startup_stm32f10x_md.s复制到工程中,并把启动文件的后缀s改为大写的S。如下图所示:

    要这样替换的原因是在windows中,所用的启动文件是针对Keil MDK这个IDE环境的,而现在我们要用GNU的工具链,所以应该要用回针对GNU启动文件。不然链接的时候会有问题。


    接下来就要开始配置一些东西了,右键工程打开属性。首先在C/C++ Build->Settings->Tool Settings标签中,找到Target Processor,在右边找到Instruction set,选择Thumb。找到Endianness,选择Little endian。如下图所示。

    然后,在Cross ARM GNU Assembler、Cross ARM C Compiler和Cross ARM C++ Compiler中的Preprocessor中定义两个宏:STM32F10X_MD和USE_STDPERIPH_DRIVER。其它的全部删去,这一个很重要,关系到后面的编译问题。一开始Eclipse会帮你定义好多宏,但都不需要,只留这两个就行了。


    然后,还是在Cross ARM GNU Assembler、Cross ARM C Compiler和Cross ARM C++ Compiler中的Includes修改为你包含有头文件的路径。如下图所示。


    接下来,是在Cross ARM C++ Linker和General中,把原本工程里的链接脚本路径补全。如下图所示:


    好了,这些设置好了之后,可以编译了吗?理论上是可以的,不过还有些代码要修改。这是由于固件库写的地方有些问题,参考文章如下:

    https://answers.launchpad.net/gcc-arm-embedded/+question/217817

    修改如下:

    在core_cm3.c中,找到uint32_t __STREXB(uint8_t value, uint8_t *addr)和uint32_t __STREXH(uint16_t value, uint16_t *addr)。把这两个函数中的"=r"改为"=&r",如下图所示:

    好,现在编译可以编译了。



    可以看到最后是编译成功了,而且对比于在Keil MDK里编译的文件大小,代码段所占的大小更小。这个编译效率还是令人满意的。

    编译了程序之后,怎么样才能下载到板子里并且进行调试呢?下面开始说明一下。

    在调试按钮旁边有个下拉箭头,点击箭头后点击Debug Configurations。然后双击Zylin Embedded debug( Native )。这样就会生成一个名称和工程名字相同的调试配置界面。如下图所示。



    在界面中点击Debugger标签。找到GDB debugger的文本框,通过浏览定位到上面提到要安装的arm-linux-gdb,然后点击应用。如下图所示。


    接着点击Commands标签。在'Initalize' commands里输入对JLink的初始化命令。点击应用。如下图所示。


    好了,问题就来了,这个初始化命令是怎么呢?究竟要怎么写呢?在这里我先给出我自己的初始化命令脚本。大家可以根据自己的实际情况进行修改。


target remote localhost:2331

monitor halt

monitor interface JTAG

monitor speed 1000

monitor endian little

monitor flash cpuclock = 72000000

monitor flash device = STM32F103C8

monitor flash download = 1

monitor flash breakpoints = 1

load Debug/TestSTM32.elf

monitor reg r13 = (0x00000000)

monitor reg pc = (0x00000004)


    这个脚本做了些什么呢?首先定义了gdb server的端口,接下来不断地往stm32和jlink下达命令:让stm32停机、设置使用JTAG接口,速度设置为1000kHz等等。最后下载程序并复位stm32。

    一开始的时候我也不知道要写怎么样的初始化脚本以及初始化命令。后来在Segger官网上找到了关于JLinkGDBServer的用户手册,其官网页面及下载地址如下:

官网页面:https://www.segger.com/jlink-gdb-server.html

用户手册下载地址:https://www.segger.com/admin/uploads/productDocs/UM08005_JLinkGDBServer.pdf

   重点参考3.4 Debugging on Cortex-M Devices和3.5 Supported remote commands这两节,脚本模板和命令解析都在这里了。

   设置好了这个页面之后不要急着关掉,一会调试就从这个页面开始的。插上JLink,连接好硬件到PC里。现在要手动启动gdb server。在JLink的驱动包里面,有一个可执行文件叫JLinkGDBServer。通过命令行启动它(最好就直接用root用户启动)。如下图所示。如果你硬件已经连接好了,驱动什么的都连接好了之后,就会提示你找到了Cortex-M3的设备。这样就正常了。注意,在调试的过程中不能关闭JLinkGDBServer,就让它这样开着就ok了。不然会调试不了的。

    接下来,在刚才Eclipse的Debug Configurations页面里,点击Debug。开始调试。这样就会跳到Eclipse的调试视图里,并且调试停留在启动文件的第一行汇编指令里。这样就说明调试已经成功了,之后怎么样调试程序就和在eclipse里调试其它pc程序一样。这里就不多说了。


    好了,在Linux环境里开发STM32的整个流程就已经介绍完了。写这一篇文章的目的只是为了记录一下过程,方便日后忘了步骤的时候进行查看,也希望能够帮助其他想在linux环境下开发stm32的人少走些弯路。

推荐阅读

史海拾趣

CAROLCABLE公司的发展小趣事

在激烈的市场竞争中,CAROLCABLE公司深知技术创新是企业发展的核心动力。因此,公司不断加大研发投入,引进先进的生产设备和技术人才,推动技术创新和产业升级。经过多年的努力,CAROLCABLE成功研发出了一系列具有自主知识产权的高性能线缆产品,这些产品在传输速度、稳定性和耐用性等方面均达到了行业领先水平。

随着产品技术的不断升级,CAROLCABLE开始积极拓展国内外市场。公司参加了多个国际电子线缆展会,与全球同行交流学习,寻找合作机会。同时,CAROLCABLE还加强与国内大型电子企业的合作,为其提供定制化的线缆解决方案。这些举措不仅为公司带来了更多的商机,也进一步巩固了CAROLCABLE在电子线缆行业的领先地位。

这两个故事仅是对CAROLCABLE公司发展起来的简要描述,实际上,公司的成长历程中还有许多值得探讨的细节和里程碑事件。如需了解更多关于CAROLCABLE公司的故事,建议查阅相关新闻报道或公司官方资料。

Cermetek Microelectronics公司的发展小趣事

Cermetek Microelectronics公司在创立之初,便专注于微电子技术的研发与创新。创始人凭借在半导体领域的深厚背景,带领团队攻克了一系列技术难题,成功开发出具有高性能和稳定性的微电子产品。这些产品不仅满足了市场对微型化、高集成度的需求,更在多个关键领域实现了技术突破,为公司赢得了市场的初步认可。

Global Components & Controls公司的发展小趣事
选择质量可靠、性能稳定的元件,以确保电路的稳定性和可靠性。
锋鸣电子(Fengming)公司的发展小趣事

随着新能源和储能市场的快速发展,福斯特公司也积极拓展相关业务领域。公司不仅关注光伏材料的研发和生产,还将目光投向了动力电池及储能领域。例如,公司推出的铝塑复合膜产品已完成一期2000万平米扩产项目,并计划未来进一步拓展至动力电池及储能领域。这一举措不仅丰富了公司的产品线,还为公司带来了新的增长点和发展机遇。同时,福斯特还加强与新能源产业链上下游企业的合作,共同推动新能源和储能产业的发展。

Crystek公司的发展小趣事

为了更好地满足客户需求和推动业务发展,Crystek公司设立了专门负责频率控制的部门——Crystek Crystals和Crystek Microwave。这两个部门分别致力于开发和制造使用石英谐振器的频率产品以及为微波行业开发频率控制和支持产品。这种专业化的分工不仅提高了公司的运营效率,也使得Crystek公司能够更好地为客户提供定制化的解决方案和优质的服务。

地博电子(DIBO)公司的发展小趣事

为了进一步拓展市场,地博电子在2016年成立了湖南地博光学材料有限公司,并建立了覆盖全国的营销网络。这一举措使得地博电子的产品能够更快速地触达目标客户,提高了市场占有率和品牌影响力。同时,全国营销网络的建立也为地博电子的未来发展提供了更广阔的空间。

问答坊 | AI 解惑

论坛资料重复太多了,有办法解决吗?

本人在论坛下载下来的时候发现,竟然有很多资料内容都是一样的,只改头换面而已,既浪费芯币又浪费时间,可怜我辛苦攒来的芯币呀!晕…希望管理员重视。…

查看全部问答>

源程序--我用逻辑分析仪测试时隙,调试出的18b20

我用逻辑分析仪测试出的1820时隙,源代码 …

查看全部问答>

WWDG进不了中断

我用一个灯监视WWG中断,正常的话每进20次中断改一次灯的状态,(主要是因为看门狗58.25MS喂一次狗,想让LED大约1S闪一次),但是不知哪里出现问题,灯从没闪烁过,说明WWDG中断没有进入,我将断点设在WWDG中断程序中,结果也没有跑到中断程序 ...…

查看全部问答>

请教大家下面IC的型号和厂商?

请各位大侠和兄弟姐妹帮忙,先在此谢过了。…

查看全部问答>

Stm32之寄存器汇总

很全的stm32寄存器表格,借以了解分析库函数。。。。。。 [ 本帖最后由 xinjitmzy 于 2012-4-17 21:26 编辑 ]…

查看全部问答>

低版本IAR简易开发LaunchPad的歪道

    (写得很认真,先留着,等板子来了就可以耍了!感谢作者)    故事的起因是这样滴。。。LaunchPad包装盒中并没有附带资料光盘(至少我收到的是这样的),只有一张纸的简单介绍,即TI网站上的文档MSP-EXP430G2 LaunchPa ...…

查看全部问答>

电源专用高压固态电容22UF/160V

6.8uf/160v 1、额定电压=160V; 2、浪涌电压=172.5V;3、容量=6.8UA;4、漏电流=217UA; 5、损耗=12%;6、ESR≤150毫欧 ;  7、纹波电流=420MA ;8、外形尺寸=¢8*12 12UF/160V      1、额定电压=160V; 2 ...…

查看全部问答>

为什么我的 INA CMRR 不随增益变化?

转自:deyisupport 前面有两篇关于仪表放大器 (INA) 电源及共模抑制比 (PSRR & CMRR) 的极好博客文章。(参见“处理抑制问题:仪表放大器 PSRR 与 CMRR”第 I 部分 和 第 II 部分)。 准确指出了大多数 INA 器件的 CMRR 与 PSRR 性能会随增益变化 ...…

查看全部问答>

如何设计基于DS18B20温度计

要求基于DS18B20的温度计,按键切换显示华氏和摄氏度。…

查看全部问答>

模数转换器中的混叠:并不是所有的信号都像其看上去那样

转自deyisupport 你看没看到过汽车向前行驶,而车的轮子实际上是向后转呢?如果不是在表演高难度特技的话,我打赌你一定在汽车广告中看到过。你想没想过这是为什么呢?真实的生活如流水般不可中断,而视频摄像头每秒钟只记录了有限数量的画面。每 ...…

查看全部问答>