簡體   English   中英

如何在Ubuntu上編譯STM32f103程序?

[英]How to compile STM32f103 program on ubuntu?

我在使用Keil在Windows上編程stm32 arm cortex m3微控制器方面有一些經驗。 我現在想轉到linux環境並使用開放源代碼工具對STM32 cortex m3設備進行編程。

經過研究,發現可以使用OpenOCD或Texane的ST Link來刷新芯片。 我還發現,我需要一個交叉編譯器來編譯代碼,即。 gcc-arm-none-eabi工具鏈。

我想知道需要哪些基本的源文件和頭文件? 哪個是制作簡單的眨眼程序所需的核心和系統文件。

到目前為止,我不打算使用HAL庫。 我正在使用stm32f103zet6單片機(非常通用的主板)。 我去了http://regalis.com.pl/en/arm-cortex-stm32-gnulinux/ ,但是無法精確地找到文件。

如果有任何教程可以在Linux環境上啟動stm32編程,請告訴我。

任何幫助表示贊賞。 謝謝!

這是一個非常簡單的示例,可以在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.c

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文件

#ARMGNU ?= arm-none-eabi
ARMGNU ?= arm-linux-gnueabi

AOPS = --warn --fatal-warnings -mcpu=cortex-m0
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mcpu=cortex-m0


all : notmain.gcc.thumb.flash.bin notmain.gcc.thumb.sram.bin

clean:
    rm -f *.bin
    rm -f *.o
    rm -f *.elf
    rm -f *.list
    rm -f *.bc
    rm -f *.opt.s
    rm -f *.norm.s
    rm -f *.hex

#---------------------------------

flash.o : flash.s
    $(ARMGNU)-as $(AOPS) flash.s -o flash.o

sram.o : sram.s
    $(ARMGNU)-as $(AOPS) sram.s -o sram.o

notmain.gcc.thumb.o : notmain.c
    $(ARMGNU)-gcc $(COPS) -mthumb -c notmain.c -o notmain.gcc.thumb.o

notmain.gcc.thumb.flash.bin : flash.ld flash.o notmain.gcc.thumb.o
    $(ARMGNU)-ld -o notmain.gcc.thumb.flash.elf -T flash.ld flash.o notmain.gcc.thumb.o
    $(ARMGNU)-objdump -D notmain.gcc.thumb.flash.elf > notmain.gcc.thumb.flash.list
    $(ARMGNU)-objcopy notmain.gcc.thumb.flash.elf notmain.gcc.thumb.flash.bin -O binary

notmain.gcc.thumb.sram.bin : sram.ld sram.o notmain.gcc.thumb.o
    $(ARMGNU)-ld -o notmain.gcc.thumb.sram.elf -T sram.ld sram.o notmain.gcc.thumb.o
    $(ARMGNU)-objdump -D notmain.gcc.thumb.sram.elf > notmain.gcc.thumb.sram.list
    $(ARMGNU)-objcopy notmain.gcc.thumb.sram.elf notmain.gcc.thumb.sram.hex -O ihex
    $(ARMGNU)-objcopy notmain.gcc.thumb.sram.elf notmain.gcc.thumb.sram.bin -O binary

如果願意,您也可以嘗試/使用此方法。 我有理由不這樣做,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文檔之間(並非每個人都這樣做,您仍然應該武裝)。 加上聖文檔。

有一個內置的基於uart的引導程序(可能是usb等),非常易於接口,讓我們看看...我的主機代碼下載程序位於數百行代碼中,可能花了一個晚上或一個下午寫。 因人而異。 如果您還沒有發現板或核板,您仍然可以得到,無論如何,我還是建議您使用它的調試端來對其他stm32甚至其他非st arm芯片進行編程(並非全部,取決於openocd支持的功能)等),但有些)可以比專用的stlink usb加密狗便宜30%,而且您不需要擴展usb電纜等。YMMV。 正如您已經提到的,當然可以將openlink或texane stlink用作stlink。

由於cortex-m引導的方式,我提供了兩個示例,一個用於刻錄以刷新Flash,另一個用於通過openocd下載到ram並以這種方式運行,可以說也可以使用Flash,但是您必須在調整起始地址時使用跑。 我更喜歡這種方法。 因人而異。

這種方法可移植,並且不受HAL限制或要求,構建環境等的限制。但是我建議您嘗試各種方法。 像這樣的裸機使用一種或多種標准解決方案以及cmsis方法的HAL類型的裸機。 每年大約重試一次,看看您選擇的那一個還是您想要的那個。

這個例子說明了它並不需要很多。 我選擇cortex-m0只是為了避免armv7m thumb2擴展。 沒有這些擴展名的thumb是最便攜式的arm指令集。 因此,代碼再次幾乎不執行任何操作,但是使用systick計時器在任何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閃爍10次,然后將程序完成)。

您的工具鏈可能還有其他方法可以做到這一點。 由於所有工具鏈都應該有一個匯編程序,並且匯編程序可以生成單詞表,因此總會有這種選擇,為此創建另一種工具和語言並不是很有意義,但是有些人感到有必要。 您的工具鏈可能不需要名為_start的入口點和/或可能具有不同的入口點名稱要求。

即使您使用Kiel,也應該嘗試使用gnu工具,比起Kiel,它更容易(更容易)獲得,在世界范圍內的支持和經驗明顯更多。 可能不會像Kiel,性能方面或其他方面那樣產生“好的”代碼,但應始終將其放在腰上,因為您將始終能夠使用gnu工具尋求幫助。

http://gnuarmeclipse.github.io/

在那里,您將找到所有內容,包括IDE(Eclipse),工具鏈,調試器和標頭。

看這個 這是IDE +工具鏈+調試器,可用於Linux平台。 您可以對其進行研究,並獲得任何想法以做您想要的。 我希望大多數linux程序都具有commnad行接口。

另外,我可以建議您:如果您的單片機已經使用LL api,請嘗試使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM