STM32F2: मेकफाइल, लिंकर स्क्रिप्ट और वाणिज्यिक आईडीई के बिना स्टार्ट-अप फ़ाइल संयोजन


16

मैं एक STM32F2 (विशेष रूप से, STM32F217IGH6 एक विकास बोर्ड पर) लगभग दो महीने से काम कर रहा हूँ। अब तक मेरी सबसे बड़ी समस्या "सेटअप" के साथ थी, जिसमें मेकफाइल, लिंकर स्क्रिप्ट और स्टार्ट-अप फ़ाइल शामिल हैं।

विशेष रूप से, मैं अपनी रुकावट वेक्टर तालिका को ठीक से स्थापित करने में असमर्थ रहा हूं और बाधित हैंडलर कहा जाता है। ST वाणिज्यिक IDEs के अनुरूप उदाहरण प्रदान करता है। इसके बजाय, मैं जीसीसी टूलचैन (और ओटीओसीडी को जेटीएजी के माध्यम से छवि को लोड करने के लिए) का मुफ्त यागार्टो पुनर्संयोजन का उपयोग कर रहा हूं।

क्या मेरे बोर्ड के लिए उदाहरण परियोजनाएं हैं (या इसके एक करीबी चचेरे भाई) जिसमें उपयुक्त मेकफाइल, लिंकर स्क्रिप्ट और गैर-वाणिज्यिक आईडीई के लिए स्टार्ट-अप फ़ाइल संयोजन शामिल हैं जिन्हें बाधित हैंडलर कहा जाता है?


2
आपको कॉर्टेक्स एम 3 उदाहरणों के लिए देखना चाहिए, सटीक बोर्ड और प्रोसेसर उन चीजों के लिए महत्वपूर्ण नहीं हैं जो आप पूछते हैं। आपको संभवतः लिंकर स्क्रिप्ट में मेमोरी लेआउट और मेकफाइल में फ्लैश करने की विधि को संशोधित करना होगा, लेकिन यह सब होना चाहिए।
स्टारब्लू

1
क्या आप इस सब को एक git रेपो में डाल सकते हैं और इसे github या कुछ और पर डाल सकते हैं?
गुस्से में

1
यही कारण है कि जैसे ही मैंने कोशिश की, मैंने एसटीएम का उपयोग करना बंद कर दिया। यदि वे मेरे जीवन को कठिन टूलकिन के साथ बनाने जा रहे हैं, तो मैं कहीं और जा रहा हूं। जब मैंने PSoC3 और PSoC5 के लिए IDE की कोशिश की, तो यह अंतर की दुनिया थी।
रॉकेटमैग्नेट

क्या आप यगर्तो के लिए प्रतिबद्ध हैं? यह पूरी तरह से ठीक है और एक महान प्रश्न बनाता है, लेकिन मैं कोडसूररी लाइट टूलचैन से परिचित हूं । एक अलग टूलकिन के लिए एक उत्तर शायद अनुकूलित किया जा सकता है, लेकिन यह काम नहीं करेगा।
केविन वर्मियर

जवाबों:


20

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 नहीं है, यह आपके लिए भी उपयोगी हो सकता है, मुझे लगता है कि मैंने इसे किसी न किसी रूप में या फैशन में व्यवधान उत्पन्न किया।


मैं उत्तर पढ़ रहा था और मुझे लगता है कि इस उत्तर के लिए लेखक आप होंगे। आपके जवाबों ने मुझे बहुत मदद की और मुझे AVR और PIC Fanboy होने की बजाय ARM प्रोसेसर में जाने के लिए प्रेरित किया। धन्यवाद
MaNyYaCk

आपका स्वागत है ... इसे आगे
बढ़ाएँ

2

आप इस साइट पर एक नज़र डाल सकते हैं जहाँ यह कोड में लिंकर और low_level_init की मूल बातें समझाने की कोशिश करता है।

कृपया ध्यान दें कि पृष्ठ समस्या का वर्णन करने पर केंद्रित है, इसलिए एनवीसी वेक्टर न्यूनतम प्रकार का है।

फिर आपके पास "STM32F2xx मानक परिधीय पुस्तकालय" में अधिक पूर्ण उदाहरण हैं, बस gcc सेक्शन में देखें (क्योंकि Yagarto gcc आधारित है)। और वहाँ उदाहरण कोड है जो आपको एनवीआईसी (इंटरप्ट वेक्टर टेबल) के सही सेटअप में मदद करेगा।

तो भले ही यह एक पूर्ण जवाब नहीं है, मुझे आशा है कि यह वैसे भी मददगार है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.