http://github.com/dwelch67
stm32f4 और stm32vld विशेष रूप से, लेकिन अन्य आपके लिए भी उपयोगी हो सकते हैं। mbed और mzero निर्देशिका mbed (कोर्टेक्स- m0) के तहत।
मैं इसे सरल बेवकूफ दृष्टिकोण, न्यूनतम लिंकर स्क्रिप्ट, न्यूनतम स्टार्टअप कोड आदि रखना पसंद करता हूं। कार्य किसी विशेष टूलकिन द्वारा नहीं कोड द्वारा किया जाता है।
जीसीसी और बिन्यूटिल्स के अधिकांश रूप (अंगूठे में सक्षम) इन उदाहरणों के साथ कुछ हद तक काम करेंगे क्योंकि मैं संकलक का उपयोग पुस्तकालय कॉल के लिए संसाधन के रूप में नहीं करने के लिए करता हूं, मैं स्टॉक लिंकर स्क्रिप्ट का उपयोग नहीं करता हूं, आदि पुराने जीसीसी और बिनुटिल के बारे में पता नहीं होगा। नए थंब 2 भागों में कुछ बदलावों की आवश्यकता हो सकती है।
मैं अपनी खुद की जीसीसी, बिनुटिल्स और एलएलवीएम / क्लैंग का निर्माण करता हूं और साथ ही उदाहरण के लिए कोडसॉररी का उपयोग करता हूं (अब संरक्षक ग्राफिक्स लेकिन आप अभी भी मुफ्त / लाइट संस्करण प्राप्त कर सकते हैं)।
Esp जब एक नए लक्ष्य के लिए एक परियोजना को एक साथ रखना शुरू करते हैं, तो आपको कुछ डिसएफ़ीड करने की आवश्यकता होती है। विशेष रूप से यह सुनिश्चित करने के लिए कि आइटम आप उन्हें कहाँ चाहते हैं, उदाहरण के लिए वेक्टर टेबल।
उदाहरण के लिए stm32f4d / blinker02 देखें। यह vectors.s के अपवाद के साथ शुरू होता है / सदिश तालिका प्लस कुछ 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
इस उदाहरण पर कोई हस्तक्षेप नहीं करता है, लेकिन आपकी ज़रूरत की दूसरी चीज़ें यहाँ हैं।
blinker02.c में C एंट्रीपॉइंट के साथ C कोड का मुख्य निकाय होता है, जिसे मैं मुख्य (कुछ कंपाइलर जोड़ते समय आपके पास बाइनरी जोड़ते हैं) को मुख्य कहने के लिए notmain () कहता हूं।
आपको एक कट और पेस्ट बचेगा। मेकफाइल संकलन और लिंकिंग के बारे में कहानी कहता है। ध्यान दें कि मेरे कई उदाहरण एक ही कोड से दो या अधिक बायनेरी संकलित करते हैं। gcc कंपाइलर, llvm का क्लैंग कंपाइलर, केवल थंब और थंब 2, विभिन्न ऑप्टिमाइज़ेशन इत्यादि।
स्रोत फ़ाइलों से ऑब्जेक्ट फ़ाइलें बनाकर प्रारंभ करें।
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
लिंकर, ld, एक लिंकर स्क्रिप्ट का उपयोग करता है जिसे मैं मेममैप कहता हूं, ये बेहद दर्दनाक हो सकते हैं, कभी-कभी अच्छे कारण के लिए, कभी-कभी नहीं। मैं पसंद करता हूं कि कम एक दृष्टिकोण के लिए अधिक दृष्टिकोण है सब कुछ फिट बैठता है, लेकिन रसोई सिंक दृष्टिकोण।
मैं आमतौर पर .data का उपयोग नहीं करता (अच्छी तरह से लगभग कभी नहीं) और इस उदाहरण के लिए .bs की आवश्यकता नहीं है, इसलिए यहाँ लिंक स्क्रिप्ट है, बस प्रोग्राम (.text) को रखने के लिए पर्याप्त है जहां इसे इस प्रोसेसर के लिए होना चाहिए, जिस तरह से मैं हूं। उसका इस्तेमाल कर रहे हैं।
MEMORY
{
ram : ORIGIN = 0x08000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
}
मेरे पास यह परिभाषित करने के लिए एक मेमोरी क्षेत्र है कि, राम नाम के बारे में कुछ विशेष नहीं है जिसे आप फू या बार या बॉब कह सकते हैं या टेड यह महत्वपूर्ण नहीं है कि यह मेमोरी आइटम को अनुभागों से जोड़ता है। खंड .text, .data, .bs, .rodata जैसी चीजों को परिभाषित करते हैं और वे मेमोरी मैप में कहां जाते हैं।
जब आप इसका निर्माण करते हैं, तो आप देखते हैं कि मैं सब कुछ (objdump -D) को अलग करता हूं
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}
ध्यान देने योग्य बात यह है कि बाईं ओर का पता वह जगह है जहां हम इसे चाहते थे। vectors.s कोड पहले बाइनरी में है (क्योंकि यह पहले ld कमांड लाइन पर है, जब तक आप लिंकर स्क्रिप्ट में कुछ नहीं करते हैं, आइटम दिखाए जाएंगे। इस क्रम में बाइनरी में वे ld कमांड लाइन पर हैं)। ठीक से बूट करने के लिए आपको यह सुनिश्चित करना होगा कि आपकी वेक्टर टेबल सही जगह पर है। पहला आइटम मेरा स्टैक पता है, जो ठीक है। दूसरा आइटम _start का पता है और यह एक विषम संख्या होनी चाहिए। लेबल से पहले .thumb_func के उपयोग से ऐसा होता है, इसलिए आपको अन्य बदसूरत दिखने वाली चीजें नहीं करनी चाहिए।
08000050 <_start>:
8000050: f000 f822 bl 8000098 <notmain>
8000054: e7ff b.n 8000056 <hang>
08000056 <hang>:
8000056: e7fe
तो 0x08000051 और 0x08000057 _start और हैंग के लिए उचित वेक्टर प्रविष्टियाँ हैं। कॉल नॉटमैन शुरू करें ()
08000098 <notmain>:
8000098: b510 push {
यह अच्छा लग रहा है (वे disassembly में विषम संख्या वाला पता नहीं दिखाते हैं)।
सब ठीक हैं।
Blinker05 उदाहरण पर जाएं, यह एक इंटरप्ट का समर्थन करता है। और कुछ राम की जरूरत है, इसलिए .bs को परिभाषित किया गया है।
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x100000
ram : ORIGIN = 0x20000000, LENGTH = 0x1C000
}
SECTIONS
{
.text : { *(.text*) } > rom
.bss : { *(.bss*) } > ram
}
याद रखें कि राम और रोम मनमानी नाम हैं, बॉब और टेड, फू और बार सभी ठीक काम करते हैं।
पूरे वैक्टर को दिखाने के लिए नहीं जा रहा है क्योंकि कॉर्टेक्स-एम 3 में वेक्टर तालिका में एक ज़िलिन प्रविष्टियां हैं यदि आप एक पूर्ण बनाते हैं (चिप कोर द्वारा चुने गए विकल्पों के आधार पर कोर से कोर और शायद एक ही कोर के भीतर भिन्न हो सकते हैं) संबंधित भाग disassembly के बाद यहाँ हैं:
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}
उस हैंडलर को सही स्थान पर रखने के लिए कुछ परीक्षण और त्रुटि होती है, अपनी चिप की जांच करें जहां यह होना जरूरी है कि यह एक ही स्थान पर जरूरी नहीं है, और इतने सारे व्यवधानों के साथ आप एक अलग बाधा की तलाश में हैं। कॉर्टेक्स-एम प्रोसेसर, सामान्य हथियारों के विपरीत, इसे बनाते हैं ताकि आप बाधित होने के लिए ट्रैपोलिन कोड की आवश्यकता न करें, वे रजिस्टर की एक निश्चित संख्या को संरक्षित करते हैं और लिंक रजिस्टर सामग्री के माध्यम से प्रोसेसर मोड के स्विचिंग का प्रबंधन करते हैं। इसलिए जब तक हार्डवेयर और कंपाइलर के लिए अबी पर्याप्त नहीं है, यह सब काम करता है। इस मामले में मैंने अन्य प्लेटफार्मों के विपरीत सी में हैंडलर किया था और अतीत में आपको कंपाइलर / सिंटैक्स के साथ कुछ विशेष करने की आवश्यकता नहीं है, बस एक फ़ंक्शन करें (लेकिन फ़ंक्शन / हैंडलर में बेवकूफ चीजें न करें)
//-------------------------------------------------------------------
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 के लिए मेकफाइल Blinker02 उदाहरण से मिलता-जुलता होना चाहिए, इनमें से ज्यादातर के लिए कट और पेस्ट करना चाहिए। वस्तुओं में व्यक्तिगत स्रोत फ़ाइलों को तब लिंक करें। मैं gcc और क्लैंग का उपयोग करके अंगूठे, थंब 2 के लिए निर्माण करता हूं। आप सभी को बदल सकते हैं: यदि आप नहीं चाहते हैं कि क्लच (llvm) को शामिल करने के लिए केवल gcc आइटम को शामिल करें। मैं clut आउटपुट btw को इकट्ठा करने और लिंक करने के लिए Binutils का उपयोग करता हूं।
ये सभी परियोजनाएँ निशुल्क, बंद स्रोत, खुले स्रोत, औजारों का उपयोग करती हैं। कोई आईडीई नहीं, केवल कमांड लाइन। हां, मैं केवल लिनक्स के साथ गड़बड़ करता हूं और विंडोज नहीं, लेकिन ये उपकरण विंडोज उपयोगकर्ताओं के लिए भी उपलब्ध हैं, आरएम-एफ जैसी चीजों को बदलने के लिए, मेकफाइल में कुछ डेल करने के लिए, विंडोज जैसी चीजों को बनाते समय। कि vmware या virtualbox या qemu पर लिनक्स चलाएं। आईडीई का उपयोग न करने का मतलब है कि आप अपना टेक्स्ट एडिटर चुनें, मैं अभ्यस्त हो जाऊंगा, मेरे पास मेरा पसंदीदा है। ध्यान दें कि ग्नू मेक प्रोग्राम की एक अत्यंत कष्टप्रद विशेषता यह है कि इसे मेकफाइल में वास्तविक टैब की आवश्यकता होती है, मैं एक जुनून के साथ अदृश्य टैब से नफरत करता हूं। तो मेकफाइल्स के लिए एक टेक्स्ट एडिटर जो टैब छोड़ता है, दूसरा सोर्स कोड के लिए जो स्पेस बनाता है। मैं खिड़कियों के बारे में नहीं जानता,
मुझे उम्मीद है कि यह मदद करता है, यह सटीक चिप / बोर्ड नहीं है, लेकिन एक कोर्टेक्स-एम 4 अच्छी तरह से एम 4 एम 3 नहीं है, इस चर्चा के लिए पर्याप्त है। वास्तविक कॉर्टेक्स-एम 3 (मेकफाइल्स और बूट कोड, आदि के लिए एम 4 से पर्याप्त अंतर नहीं) के लिए मीड या स्टम 32 डीएलआर देखें, लेकिन सेंट द्वारा नहीं बनाया गया। कॉर्टेक्स-एम 3 कोर को विक्रेताओं के समान होना चाहिए, कॉर्टेक्स-एम 3 और कॉर्टेक्स-एम 4 दोनों एआरएमवी 7 एम हैं और अलग-अलग होने के बजाय करीब हैं। कोर्टेक्स- m0 एक ARMv6m है, मुश्किल से परेशान करने के लिए थंब 2 निर्देश हैं, कंपाइलर इसके साथ नहीं पकड़े गए हैं, इसलिए केवल अंगूठे का उपयोग करें (यदि आप की जरूरत है तो केवल ARMv4T (अंगूठे का केवल) के लिए निर्माण कर रहे हैं। मेरा थंबुलेटर सिम्युलेटर केवल थंब है, कोई थंब 2 नहीं है, यह आपके लिए भी उपयोगी हो सकता है, मुझे लगता है कि मैंने इसे किसी न किसी रूप में या फैशन में व्यवधान उत्पन्न किया।