2016-07-18 95 views
2

我有一些使用Keil在Windows上编程stm32 arm cortex m3微控制器的经验。我现在想转向Linux环境,并使用开源工具编写STM32 cortex m3器件。如何在ubuntu上编译STM32f103程序?

我研究了一下,发现我可以使用OpenOCD或Texane的ST链接来刷新芯片。我还发现我需要一个交叉编译器来编译代码。 gcc-arm-none-eabi工具链。

我想知道需要什么基本的源文件和头文件?制作简单闪烁程序需要哪些核心和系统文件。

我不打算现在使用HAL库。我正在使用stm32f103zet6单片机(一个非常通用的主板)。我去了http://regalis.com.pl/en/arm-cortex-stm32-gnulinux/,但无法准确找出文件。

如果有任何教程在linux环境下启动stm32编程,请告诉我。

任何帮助表示赞赏。谢谢!

+0

有很多使用HAL和裸机的例子。你可以制作你自己的标题,你不需要使用stm hal或者cmsis,或者如果你想要的话,你可以去获取这些标题并使用你想要的百分比。 –

回答

-1

http://gnuarmeclipse.github.io/

在那里,你会发现一切,包括一个IDE(Eclipse中),工具链,调试器,标头。

+0

感谢您的回复!对此,我真的非常感激。但是,我不在寻找一个IDE。事实上,我不想使用IDE。我只想使用工具链和Makefiles。对不起,我的问题还不够清楚。我想从命令行执行所有操作。我现在想知道它是否可能。? – Navin

+0

您可以使用eclipse和上述站点上的插件创建示例项目,然后将生成的生成文件和目录结构作为起点。 – berendi

-1

看看这个package。这是IDE +工具链+调试器,可用于Linux平台。你可以研究它,并得到任何想法做你想做的。我希望大部分的linux程序都有线路接口。

另外我可以建议你:尝试使用LL API如果它已经可用于你的单片机。

2

这是一个非常简单的例子,它在stm32系列中相当便携。没有做任何有用的事情,你必须填写空白闪烁一个LED或什么东西(阅读原理图,手册,启用时钟到GPIO,按照说明使其成为推/拉输出等,设置位或清除位等)。

我有我的理由,我怎么做别人有他们的,我们都有这些意见背后的几年或几十年的经验。但在他们一天结束时,他们是意见,许多不同的解决方案将起作用。

在Ubuntu的最后这么多的版本,你可以简单地这样做是为了得到一个工具链:

apt-get install gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi 

或者你可以去这里,并获得预建于您的操作系统

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

flash.s

.cpu cortex-m0 
.thumb 
.thumb_func 
.global _start 
_start: 
stacktop: .word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.thumb_func 
reset: 
    bl notmain 
    b hang 
.thumb_func 
hang: b . 
.align 
.thumb_func 
.globl PUT16 
PUT16: 
    strh r1,[r0] 
    bx lr 
.thumb_func 
.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr 
.thumb_func 
.globl GET32 
GET32: 
    ldr r0,[r0] 
    bx lr 
.thumb_func 
.globl dummy 
dummy: 
    bx lr 
.end 

flash.ld

MEMORY 
{ 
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

sram.s

.cpu cortex-m0 
.thumb 
.thumb_func 
.global _start 
_start: 
    ldr r0,stacktop 
    mov sp,r0 
    bl notmain 
    b hang 
.thumb_func 
hang: b . 
.align 
stacktop: .word 0x20001000 
.thumb_func 
.globl PUT16 
PUT16: 
    strh r1,[r0] 
    bx lr 
.thumb_func 
.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr 
.thumb_func 
.globl GET32 
GET32: 
    ldr r0,[r0] 
    bx lr 
.thumb_func 
.globl dummy 
dummy: 
    bx lr 
.end 

sram.ld

MEMORY 
{ 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 
SECTIONS 
{ 
    .text : { *(.text*) } > ram 
    .rodata : { *(.rodata*) } > ram 
    .data : { *(.data*) } > ram 
    .bss : { *(.bss*) } > ram 
} 

notmain。ç

void PUT32 (unsigned int, unsigned int); 
unsigned int GET32 (unsigned int); 
void dummy (unsigned int); 
#define STK_CSR 0xE000E010 
#define STK_RVR 0xE000E014 
#define STK_CVR 0xE000E018 
#define STK_MASK 0x00FFFFFF 
int delay (unsigned int n) 
{ 
    unsigned int ra; 
    while(n--) 
    { 
     while(1) 
     { 
      ra=GET32(STK_CSR); 
      if(ra&(1<<16)) break; 
     } 
    } 
    return(0); 
} 
int notmain (void) 
{ 
    unsigned int rx; 
    PUT32(STK_CSR,4); 
    PUT32(STK_RVR,1000000-1); 
    PUT32(STK_CVR,0x00000000); 
    PUT32(STK_CSR,5); 
    for(rx=0;;rx++) 
    { 
     dummy(rx); 
     delay(50); 
     dummy(rx); 
     delay(50); 
    } 
    return(0); 
} 

的Makefile

​​

您也可以尝试/如果你喜欢使用这种方法。我有我的理由不,TL; DW。

void dummy (unsigned int); 
#define STK_MASK 0x00FFFFFF 
#define STK_CSR (*((volatile unsigned int *)0xE000E010)) 
#define STK_RVR (*((volatile unsigned int *)0xE000E014)) 
#define STK_CVR (*((volatile unsigned int *)0xE000E018)) 
int delay (unsigned int n) 
{ 
    unsigned int ra; 
    while(n--) 
    { 
     while(1) 
     { 
      ra=STK_CSR; 
      if(ra&(1<<16)) break; 
     } 
    } 
    return(0); 
} 
int notmain (void) 
{ 
    unsigned int rx; 
    STK_CSR=4; 
    STK_RVR=1000000-1; 
    STK_CVR=0x00000000; 
    STK_CSR=5; 
    for(rx=0;;rx++) 
    { 
     dummy(rx); 
     delay(50); 
     dummy(rx); 
     delay(50); 
    } 
    return(0); 
} 

这在一定程度ST公布为您衍生物(不是每个人都做,你还是应该去ARM)手臂文档之间。加上st文件。

这里有基于uart的bootloader(可能是usb等),它非常易于界面,让我们看看...我的主机代码下载程序是在数百行代码中,可能需要一个晚上或者一个下午写。因人而异。你可以得到,如果你还没有,发现或核心板之一,我推荐那些,你可以使用它的调试结束编程其他STM32甚至其他非ST ARM芯片(不是所有,取决于什么openocd支持等),但一些)可以得到那些比专用stlink USB加密狗便宜30%,你不需要扩展USB电缆等,等等。正如您已经提到的,当然可以使用带有openocd或texane stlink的stlink。

由于cortex-m靴子的方式,我提供了两个示例,一个用于通过openocd将内容下载到另一个用于下载并以此方式运行,另一个可能会使用闪存,但您必须调整运行时的起始地址。我更喜欢这种方法。因人而异。

这种方法是可移植的,完全不受HAL限制或要求,构建环境等的影响。但我建议您尝试各种方法。像这样的裸金属是带有一个或多个st解决方案和cmsis方法的裸金属的HAL类型。每年都会再试一次,看看你选的那个还是你喜欢的那个。

虽然这个例子并不需要很多,我选择了cortex-m0只是为了避免armv7m thumb2扩展。没有这些扩展的拇指是最便携的手臂指令集。所以代码几乎不做任何事情,但是在任何stm32 cortex-m上都不会执行任何操作。

编辑

这伴随着任何你需要养活的连接将是最小的非C代码。

.global _start 
_start: 
.word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 

,这是取决于芯片的供应商和核心可以有几十到几百载体为每一件小事每个小的中断缩写。在这种情况下,重置和挂起的标签将是用于处理这些向量的C函数的名称(芯片和内核的文档确定哪些向量处理什么)。第一个向量始终是堆栈指针的初始化值。第二个总是重置,接下来的几个是常见的,之后它们是芯片厂商连接的核心上的通用中断引脚,因此您必须查看芯片供应商文档。

核心设计是这样的寄存器保存为你,所以你不需要一点点的组装。如果没有任何引导程序,那么你认为没有.bss归零,也没有.data初始化,并且你不能从reset函数返回,在实际的实现中,你不会但是对于演示测试,你可能(闪烁一次led,然后程序是完成)。

您的工具链可能有其他方式来执行此操作。由于所有的工具链都应该有一个汇编程序,并且汇编程序可以生成词表,所以总是有这种选择,对于为此创建另一种工具和语言并没有什么意义,但有些人认为需要。您的工具链可能不需要名为_start的入口点和/或它可能具有不同的入口点名称要求。

即使你使用基尔,你也应该尝试gnu工具,更容易(更容易)获得,显着更多的支持和体验比基尔。可能不会像基尔,表现明智或其他产品那样产生“良好”的代码,但是应该始终将其放在后面的口袋中,因为您总能找到gnu工具的帮助。

+0

感谢回复dwelch!我看到你在这里使用汇编语言,我想这些是拇指指示。我对ARM上的汇编编程完全天真。我想用C语言编程。在Keil中,它包含了几个文件,如cortex m3的核心头文件,系统启动文件(唯一一个用汇编语言编写),设备头文件和其他几个文件。我希望能够包含和使用这些文件,并从那里继续使用Makefile和交叉编译器(裸机)。我希望我清楚地解释自己。请问我是否有任何澄清。感谢你的宝贵时间。 – Navin

+0

是的,如果你从闪存启动,唯一不需要C的东西,cortex-m就是一个向量表(以及某种链接器脚本或某种命令)。在我上面的flash代码中,带有.word的部分对于这个工具链来说是最小的,并且在后面的例子中使用volatile指针。 –

+0

cortex-m是拇指专用机器,它们不支持全尺寸手臂指令。 m0,m0 +是armv6-m,除拇指外还有少量的thumb2扩展,m3和m4和m7都有大量的thumb2扩展支持它们。没有thumb2的Thumb是从arm7tdmi到现在的所有arm核心中唯一的指令集,并且更容易学习。 –