http://github.com/dwelch67
özellikle stm32f4 ve stm32vld, ancak diğerleri sizin için de yararlı olabilir. mbed ve mzero dizini mbed altında (cortex-m0).
Basit aptal yaklaşımı, minimal linker komut dosyalarını, minimum başlangıç kodunu vb.Gibi seviyorum. İş, herhangi bir belirli araç zinciri tarafından değil kodla yapılır.
Çoğu gcc ve binutils biçimi (başparmak yeteneğine sahip) bu örneklerle biraz çalışacak, çünkü derleyici kütüphane çağrıları için bir kaynak olarak değil derlemek için kullanıyorum, stok bağlayıcı komut dosyalarını vb. Kullanmıyorum. Eski gcc ve binutils yeni başparmak2 bölümleri, bu nedenle bazı değişiklikler gerekli olabilir.
Kendi gcc, binutils ve llvm / clang'ımı oluşturmanın yanı sıra örneğin codeurcery kullanıyorum (şimdi akıl hocası grafikleri ama yine de ücretsiz / lite sürümünü alabilirsiniz).
Esp yeni bir hedef için bir proje oluşturmaya başlarken bazı sökme yapmanız gerekir. Özellikle, öğelerin istediğiniz yerde olduğundan emin olmak için, örneğin vektör tablosu.
Örneğin stm32f4d / blinker02 öğesine bakın. Vektörlerle başlar. S istisna / vektör tablosu artı bazı asm destek rutinleri:
/* vectors.s */
.cpu cortex-m3
.thumb
.word 0x20002000 /* stack top address */
.word _start /* 1 Reset */
.word hang /* 2 NMI */
.word hang /* 3 HardFault */
.word hang /* 4 MemManage */
.word hang /* 5 BusFault */
.word hang /* 6 UsageFault */
.word hang /* 7 RESERVED */
.word hang /* 8 RESERVED */
.word hang /* 9 RESERVED*/
.word hang /* 10 RESERVED */
.word hang /* 11 SVCall */
.word hang /* 12 Debug Monitor */
.word hang /* 13 RESERVED */
.word hang /* 14 PendSV */
.word hang /* 15 SysTick */
.word hang /* 16 External Interrupt(0) */
.word hang /* 17 External Interrupt(1) */
.word hang /* 18 External Interrupt(2) */
.word hang /* 19 ... */
.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 GET16
GET16:
ldrh r0,[r0]
bx lr
.end
Bu örnekte kesinti yok, ancak ihtiyacınız olan diğer şeyler burada.
blinker02.c, ana kodu çağırmamak için notmain () olarak adlandırdığım C giriş noktasıyla birlikte C kodunun ana gövdesini içerir (bir main () olduğunda bazı derleyiciler ikilinize önemsiz ekler).
size kesip yapıştıracak. thefilefile derleme ve bağlama hakkında bir hikaye anlatır. Bazı örneklerimin aynı koddan iki veya daha fazla ikili dosya derlediğini unutmayın. gcc derleyici, llvm'nin clang derleyicisi, yalnızca başparmak ve başparmak2, farklı optimizasyonlar, vb.
Kaynak dosyalardan nesne dosyaları yaparak başlayın.
vectors.o : vectors.s
$(ARMGNU)-as vectors.s -o vectors.o
blinker02.gcc.thumb.o : blinker02.c
$(ARMGNU)-gcc $(COPS) -mthumb -c blinker02.c -o blinker02.gcc.thumb.o
blinker02.gcc.thumb2.o : blinker02.c
$(ARMGNU)-gcc $(COPS) -mthumb -mcpu=cortex-m3 -march=armv7-m -c blinker02.c -o blinker02.gcc.thumb2.o
blinker02.gcc.thumb.bin : memmap vectors.o blinker02.gcc.thumb.o
$(ARMGNU)-ld -o blinker02.gcc.thumb.elf -T memmap vectors.o blinker02.gcc.thumb.o
$(ARMGNU)-objdump -D blinker02.gcc.thumb.elf > blinker02.gcc.thumb.list
$(ARMGNU)-objcopy blinker02.gcc.thumb.elf blinker02.gcc.thumb.bin -O binary
blinker02.gcc.thumb2.bin : memmap vectors.o blinker02.gcc.thumb2.o
$(ARMGNU)-ld -o blinker02.gcc.thumb2.elf -T memmap vectors.o blinker02.gcc.thumb2.o
$(ARMGNU)-objdump -D blinker02.gcc.thumb2.elf > blinker02.gcc.thumb2.list
$(ARMGNU)-objcopy blinker02.gcc.thumb2.elf blinker02.gcc.thumb2.bin -O binary
linker, ld, memmap olarak adlandırdığım bir linker betiği kullanır, bunlar son derece acı verici olabilir, bazen iyi bir nedenden dolayı, bazen değil. Ben daha az tek beden herkese uyar daha fazla yaklaşım, mutfak lavabo yaklaşım dışında her şeyi tercih ederim.
Ben tipik olarak .data kullanmıyorum (neredeyse hiç asla) ve bu örnek .bss için bir ihtiyaç yok bu yüzden burada linker komut dosyası, sadece bu işlemci için olması gereken yere program (.text) yerleştirmek için yeterli konum kullanarak.
MEMORY
{
ram : ORIGIN = 0x08000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
}
Ben tanımlamak için bir bellek bölgesi var, adı ram hakkında foo veya bar veya bob diyebilirsiniz özel bir şey yok ya da sadece bellek öğeleri bölümlere bağlar önemli değil ted. Bölümler .text, .data, .bss, .rodata ve bellek haritasında nereye gittiklerini tanımlar.
Bunu inşa ettiğinde, her şeyi söktüğümü görüyorsun (objdump -D) bunu görüyorsun
Disassembly of section .text:
08000000 <_start-0x50>:
8000000: 20002000 andcs r2, r0, r0
8000004: 08000051 stmdaeq r0, {r0, r4, r6}
8000008: 08000057 stmdaeq r0, {r0, r1, r2, r4, r6}
800000c: 08000057 stmdaeq r0, {r0, r1, r2, r4, r6}
8000010: 08000057 stmdaeq r0, {r0, r1, r2, r4, r6}
Dikkat edilmesi gereken en önemli şey, soldaki adresin istediğimiz yer olmasıdır, vectors.s kodu ilk olarak ikiliktir (çünkü ld komut satırında ilk olduğu için, linker komut dosyasında bir şey yapmazsanız öğeler gösterecektir ld komut satırındaki sırayla ikili dosyada). Düzgün önyükleme için vektör tablonuzun doğru yerde olduğundan emin olmalısınız. İlk öğe benim yığın adresim, bu iyi. İkinci öğe _start adresidir ve tek bir sayı olmalıdır. bir etiketten önce .thumb_func kullanımı bunun olmasına neden olur, bu yüzden başka çirkin görünümlü şeyler yapmak zorunda kalmazsınız.
08000050 <_start>:
8000050: f000 f822 bl 8000098 <notmain>
8000054: e7ff b.n 8000056 <hang>
08000056 <hang>:
8000056: e7fe
0x08000051 ve 0x08000057 _start ve hang için uygun vektör girişleridir. çağrıları başlat notmain ()
08000098 <notmain>:
8000098: b510 push {
Bu iyi görünüyor (Demontajda tek numaralı adresi göstermiyorlar).
Herşey iyi.
Örnek blinker05'e atlayın, bu kesintileri destekler. ve bazı koçlara ihtiyaç duyar, bu nedenle .bss tanımlanır.
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x100000
ram : ORIGIN = 0x20000000, LENGTH = 0x1C000
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram
}
koç ve rom'un rastgele isimler olduğunu unutmayın, bob ve ted, foo ve bar iyi çalışır.
Tüm vektörleri göstermeyecektir. Çünkü tam bir tane yaparsanız korteks-m3 vektör tablosunda bir milyon girişe sahiptir (çip satıcısı tarafından seçilen seçeneklere bağlı olarak çekirdekten çekirdeğe ve belki aynı çekirdek içinde değişir) İlgili bölümler sökme işleminden sonra buradadır:
08000000 <_start-0x148>:
8000000: 20020000 andcs r0, r2, r0
8000004: 08000149 stmdaeq r0, {r0, r3, r6, r8}
8000008: 0800014f stmdaeq r0, {r0, r1, r2, r3, r6, r8}
...
8000104: 0800014f stmdaeq r0, {r0, r1, r2, r3, r6, r8}
8000108: 08000179 stmdaeq r0, {r0, r3, r4, r5, r6, r8}
800010c: 0800014f stmdaeq r0, {r0, r1, r2, r3, r6, r8}
bu işleyiciyi tam olarak doğru noktaya yerleştirmek için biraz deneme yanılma alır, çipinize ihtiyaç duyduğu yerde kontrol edin, mutlaka bununla aynı yerde değildir ve çok fazla kesinti ile yine de farklı bir kesme arıyor olabilirsiniz. korteks-m işlemcileri, normal kollardan farklı olarak, kesmeler için trambolin kodu GEREKMEZ, böylece belirli sayıda kaydı korurlar ve bağlantı kayıt içeriği aracılığıyla işlemci modlarının değiştirilmesini yönetirler. derleyici için donanım ve abi yeterince yakın olduğu sürece hepsi işe yarıyor. Bu durumda işleyiciyi C'de yaptım, diğer platformların aksine ve geçmişin aksine derleyici / sözdizimi ile özel bir şey yapmanıza gerek yok sadece bir işlev yapın (ancak işlev / işleyicide aptalca şeyler yapmayın)
//-------------------------------------------------------------------
volatile unsigned int intcounter;
//-------------------------------------------------------------------
// CAREFUL, THIS IS AN INTERRUPT HANDLER
void tim5_handler ( void )
{
intcounter++;
PUT32(TIM5BASE+0x10,0x00000000);
}
// CAREFUL, THIS IS AN INTERRUPT HANDLER
//-------------------------------------------------------------------
Blinker05 için makefile blinker02 örneğine benzemelidir, çoğunlukla bunların çoğu için kes ve yapıştır. tek tek kaynak dosyaları nesnelere dönüştürün ve bağlayın. Ben başparmak, gcc ve clang kullanarak thumb2 için inşa. all: satırını, glang öğelerini yalnızca clang (llvm) içermiyorsa / istemiyorsanız değiştirebilirsiniz. Ben clang çıkış btw birleştirmek ve bağlamak için binutils kullanın.
Tüm bu projeler ücretsiz, rafta, açık kaynak, araçlar kullanıyor. IDE yok, sadece komut satırı. Evet, sadece Windows ile değil Linux ile uğraşıyorum, ancak bu araçlar Windows kullanıcıları için de mevcut, rm gibi şeyleri değiştir - makefile'da bir şey yapmak için bir şey, pencereler üzerinde inşa ederken böyle şeyler. Bu veya linux'u vmware, virtualbox veya qemu üzerinde çalıştırın. IDE kullanmamak, metin düzenleyicinizi de seçtiğiniz anlamına gelir, buna girmeyeceğim, favorilerim var. GNU make programının son derece can sıkıcı bir özelliği, makefile gerçek sekmeler gerektirdiğini unutmayın, görünmez sekmelerden bir tutkuyla nefret ediyorum. Yani sekmelerden ayrılan makefiles için bir metin düzenleyicisi, boşluk oluşturan kaynak kodu için diğeri. Pencereleri bilmiyorum,
Umarım bu yardımcı olur, tam yonga / tahta değil, bu tartışma için yeterince yakın bir korteks-m4 kuyusu m4 m3 değildir. gerçek bir korteks-m3 için mbed veya stm32vld dir'e bakın (makefiles ve boot kodu vb. için m4'ten yeterli fark yok), ancak st. Korteks-m3 çekirdeği satıcılar arasında aynı olmalıdır, korteks-m3 ve korteks-m4'ün ikisi de ARMv7m'dir ve farklı olmaktan çok daha yakındır. Korteks-m0 bir ARMv6m, rahatsız etmek için yeterince başparmak2 talimatı yok, derleyiciler onunla yakalanmadı, bu yüzden sadece başparmak kullanın (gerekirse bir ARMv4T (sadece başparmak) için inşa ediyormuş gibi yapın). Benim simülatör simülatör sadece başparmak, hiçbir başparmak2, sizin için de yararlı olabilir, sanırım bazı şekillerde veya moda kesmeler yaptım.