http://github.com/dwelch67
stm32f4 dan stm32vld pada khususnya, tetapi yang lain mungkin berguna bagi Anda juga. mbed dan direktori mzero di bawah mbed (cortex-m0).
Saya suka pendekatan bodoh sederhana, skrip linker minimal, kode startup minimal, dll. Pekerjaan ini dilakukan oleh kode bukan oleh toolchain tertentu.
Sebagian besar bentuk gcc dan binutils (yang mampu diacungi jempol) akan bekerja agak dengan contoh-contoh ini karena saya menggunakan kompiler untuk mengkompilasi bukan sebagai sumber daya untuk panggilan perpustakaan, saya tidak menggunakan skrip penghubung stok, dll. Gcc dan binutils yang lebih tua tidak akan tahu tentang bagian thumb2 yang lebih baru sehingga beberapa perubahan mungkin diperlukan.
Saya membangun gcc, binutils dan llvm / clang saya sendiri dan juga menggunakan codesourcery misalnya (sekarang mentor grafik tetapi Anda masih bisa mendapatkan versi gratis / lite).
Terutama ketika mulai menyusun proyek untuk target baru yang perlu Anda lakukan beberapa pembongkaran. Khususnya untuk memastikan item berada di tempat yang Anda inginkan, tabel vektor misalnya.
Lihatlah stm32f4d / blinker02 misalnya. Itu dimulai dengan vektor.s tabel pengecualian / vektor ditambah beberapa rutinitas dukungan asm:
/* 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
Tidak ada interupsi pada contoh ini, tetapi hal-hal lain yang Anda butuhkan ada di sini.
blinker02.c berisi badan utama kode C dengan titik masuk C yang saya panggil notmain () untuk menghindari memanggilnya main (beberapa kompiler menambahkan sampah ke biner Anda ketika Anda memiliki main ()).
akan mengampuni Anda memotong dan menempel. makefile bercerita tentang kompilasi dan penautan. Perhatikan bahwa sejumlah contoh saya mengkompilasi dua atau lebih binari dari kode yang sama. gcc compiler, compiler clang llvm, ibu jari saja dan thumb2, optimasi berbeda, dll
Mulai dengan membuat file objek dari file sumber.
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, menggunakan skrip linker yang saya sebut memmap, ini bisa sangat menyakitkan, kadang-kadang karena alasan yang baik, kadang tidak. Saya lebih suka pendekatan yang lebih sedikit untuk satu ukuran cocok untuk semua, semuanya kecuali pendekatan wastafel dapur.
Saya tidak menggunakan data. Biasanya (well hampir tidak pernah) dan contoh ini tidak memiliki kebutuhan .bss jadi di sini adalah skrip linker, hanya cukup untuk menempatkan program (.text) di mana perlu untuk prosesor ini mereka seperti saya menggunakannya.
MEMORY
{
ram : ORIGIN = 0x08000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
}
Saya memiliki wilayah memori untuk mendefinisikan bahwa, tidak ada yang istimewa tentang ram nama Anda dapat menyebutnya foo atau bar atau bob atau ted itu tidak masalah itu hanya menghubungkan item memori ke bagian. Bagian menentukan hal-hal seperti .text, .data, .bss, .rodata dan kemana mereka pergi di peta memori.
ketika Anda membangun ini, Anda melihat saya membongkar semuanya (objdump -D) Anda melihat ini
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}
Hal utama yang perlu diperhatikan adalah alamat di sebelah kiri adalah tempat kami menginginkannya, kode vectors.s adalah yang pertama dalam biner (Karena itu adalah yang pertama di baris perintah ld, kecuali jika Anda melakukan sesuatu pada skrip linker, item akan ditampilkan di biner dalam urutan mereka berada di baris perintah ld). Untuk mem-boot dengan benar, Anda harus memastikan tabel vektor Anda ada di tempat yang tepat. Item pertama adalah alamat stack saya, itu bagus. Item kedua adalah alamat untuk memulai dan itu harus berupa angka ganjil. penggunaan .thumb_func sebelum label menyebabkan hal ini terjadi sehingga Anda tidak perlu melakukan hal-hal buruk lainnya.
08000050 <_start>:
8000050: f000 f822 bl 8000098 <notmain>
8000054: e7ff b.n 8000056 <hang>
08000056 <hang>:
8000056: e7fe
jadi 0x08000051 dan 0x08000057 adalah entri vektor yang tepat untuk _start dan hang. mulai panggilan notmain ()
08000098 <notmain>:
8000098: b510 push {
Itu terlihat bagus (Mereka tidak menunjukkan alamat bernomor ganjil dalam pembongkaran).
Semua baik-baik saja.
Lewati ke contoh blinker05, yang ini memang mendukung interupsi. dan membutuhkan ram, jadi .bss didefinisikan.
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x100000
ram : ORIGIN = 0x20000000, LENGTH = 0x1C000
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram
}
ingat ram dan rom adalah nama arbitrer, bob dan ted, foo dan bar semuanya berfungsi dengan baik.
Tidak akan menampilkan seluruh vektor.s karena korteks-m3 memiliki miliaran entri dalam tabel vektor jika Anda membuat yang lengkap (bervariasi dari inti ke inti dan mungkin dalam inti yang sama tergantung pada opsi yang dipilih oleh vendor chip) Bagian yang relevan ada di sini setelah pembongkaran:
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}
mengambil beberapa trial and error untuk menempatkan handler itu tepat di tempat yang tepat, periksa dengan chip Anda di mana ia perlu itu belum tentu di tempat yang sama seperti ini, dan dengan begitu banyak interupsi Anda mungkin mencari interupsi yang berbeda pula. Prosesor korteks-m, tidak seperti lengan normal, membuatnya sehingga Anda TIDAK PERLU kode trampolin untuk gangguan, mereka mempertahankan sejumlah register dan mengelola beralih mode prosesor melalui isi register tautan. selama perangkat keras dan abi untuk kompiler cukup dekat semuanya berfungsi. Dalam hal ini saya melakukan handler di C, tidak seperti platform lain dan di masa lalu Anda tidak perlu melakukan sesuatu yang khusus dengan kompiler / sintaks hanya membuat fungsi (tapi jangan melakukan hal-hal bodoh dalam fungsi / handler)
//-------------------------------------------------------------------
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
//-------------------------------------------------------------------
Makefile untuk blinker05 harus menyerupai contoh blinker02, kebanyakan dipotong dan ditempelkan untuk sebagian besar. ubah masing-masing file sumber menjadi objek lalu tautkan. Saya membangun untuk ibu jari, ibu jari2 menggunakan gcc dan dentang. Anda dapat mengubah semua: pada saat itu hanya menyertakan item gcc jika Anda tidak memiliki / ingin dentang (llvm) terlibat. Saya menggunakan binutils untuk merakit dan menghubungkan btw output dentang.
Semua proyek ini menggunakan alat gratis, bebas, sumber terbuka, dan peralatan. tidak ada IDE, hanya baris perintah. Ya saya hanya main-main dengan Linux dan bukan Windows, tetapi alat ini tersedia untuk pengguna windows juga, mengubah hal-hal seperti rm -f sesuatu untuk del sesuatu di makefile, hal-hal seperti itu ketika membangun di windows. Itu atau jalankan linux di vmware atau virtualbox atau qemu. Tidak menggunakan IDE berarti Anda memilih editor teks Anda juga, saya tidak akan masuk ke dalamnya, saya punya favorit saya. Perhatikan bahwa fitur yang sangat menyebalkan dari program gnu make adalah membutuhkan tab yang sebenarnya di makefile, saya benci tab yang tak terlihat dengan penuh gairah. Jadi satu editor teks untuk file makefile yang meninggalkan tab, yang lain untuk kode sumber yang membuat spasi. Saya tidak tahu tentang windows,
Saya harap ini membantu, ini bukan chip / board yang tepat tetapi juga korteks-m4 m4 bukan m3, cukup dekat untuk diskusi ini. lihat mbed atau stm32vld dir untuk cortex-m3 aktual (tidak cukup perbedaan dari m4 untuk makefile dan kode boot, dll), tetapi tidak dibuat oleh st. Inti korteks-m3 harus sama di semua vendor, korteks-m3 dan korteks-m4 keduanya ARMv7m dan lebih dekat daripada berbeda. Korteks-m0 adalah ARMv6m, hampir tidak memiliki instruksi thumb2 yang cukup mengganggu, kompiler belum menyusul sehingga hanya menggunakan ibu jari saja (berpura-pura Anda sedang membangun ARMv4T (hanya ibu jari) jika perlu). Simulator thumbulator saya hanya ibu jari, tidak ada thumb2, mungkin berguna bagi Anda juga, saya pikir saya membuatnya melakukan interupsi dalam beberapa bentuk atau mode.