कॉर्टेक्स M0 के CMSIS में इंटरप्ट हैंडलर कैसे लागू किए जाते हैं?


9

मेरे पास LPC1114 किट है। पिछले कुछ दिनों से मैं देख रहा हूँ कि CMSIS कॉर्टेक्स M0 के कार्यान्वयन को यह जानने के लिए किया जाता है कि इसमें चीजें कैसे की जाती हैं। अब तक मैं समझ गया था कि प्रत्येक रजिस्टर को कैसे मैप किया जाता है और मैं इसे कैसे एक्सेस कर सकता हूं। लेकिन फिर भी मुझे नहीं पता कि इसमें कैसे दखल दिया जाता है। सीएमएसआईएस में व्यवधान के बारे में सभी जानते हैं कि स्टार्टअप फाइल में उल्लेखित कुछ बाधाएं हैं। और मैं अपने स्वयं के संचालकों को केवल स्टार्टअप फ़ाइल में उल्लिखित समान नामों के साथ सी फ़ंक्शन लिखकर लिख सकता हूं। मुझे क्या भ्रमित करता है कि उपयोगकर्ता गाइड में, यह बताया गया है कि सभी GPIO को बाहरी रुकावट स्रोतों के रूप में उपयोग किया जा सकता है। लेकिन स्टार्टअप फाइल में केवल 4 PIO इंटरप्ट का उल्लेख है। तो मुझे बताओ:

  1. मैं अन्य GPIO के लिए बाहरी व्यवधान संचालकों को कैसे लागू कर सकता हूं?
  2. CMSIS में इंटरप्ट टेबल कहां मैप की गई है?
  3. NVR और AVRs / PICs में बाधा कार्यान्वयन के बीच प्रमुख अंतर क्या हैं? (एनवीआईसी को छोड़कर फ्लैश में कहीं भी मैप किया जा सकता है)

जवाबों:


14

निम्नलिखित जानकारी इगोर के उत्कृष्ट उत्तर के अतिरिक्त है।

C प्रोग्रामिंग के नजरिए से, बाधित हैंडलर को cr_startup_xxx.c फ़ाइल (जैसे cr_startup_lpc13.c LPC1343 फ़ाइल के लिए) में परिभाषित किया गया है। सभी संभावित रुकावट संचालकों को WEAK उपनाम के रूप में परिभाषित किया गया है। यदि आप अपने स्वयं के XXX_हैंडलर () को एक रुकावट स्रोत के लिए परिभाषित नहीं करते हैं, तो इस फ़ाइल में परिभाषित डिफ़ॉल्ट व्यवधान हैंडलर फ़ंक्शन का उपयोग किया जाएगा। लिंकर अंतिम बाइनरी में cr_startup_xxx.c से बाधित वेक्टर तालिका के साथ कौन से फ़ंक्शन को शामिल करने के लिए हल करेगा

GPIO.c में पोर्ट फाइल्स में GPIO इंटरप्ट का उदाहरण दिखाया गया है। एनपीआईसी प्रति GPIO पोर्ट के लिए एक बाधा इनपुट है। पोर्ट में प्रत्येक व्यक्तिगत बिट को उस पोर्ट पर एक बाधा उत्पन्न करने के लिए सक्षम / अक्षम किया जा सकता है। यदि आपको उदाहरण के लिए पोर्ट PIO1_4, और PIO1_5 पर इंटरप्ट की आवश्यकता है, तो आप GPIO0IE में अलग-अलग PIO1_4 और PIO1_5 इंटरप्ट बिट्स को सक्षम करेंगे। जब आपका PIOINT0_Handler () इंटरप्ट हैंडलर फ़ंक्शन फायर करता है, तो यह निर्धारित करना है कि PIO1_4 या PIO1_5 (या दोनों) में से कौन सा व्यवधान GPIO0RIS रजिस्टर को पढ़कर और अंतरण को उचित रूप से हैंडल करके लंबित है।


10

(कृपया ध्यान दें कि अंक 1 और 2 कार्यान्वयन विवरण हैं न कि वास्तु सीमाएं।)

  1. NXP के बड़े चिप्स (जैसे LPC17xx) में कुछ ऐसे डेडिकेटेड पिंस (EINTn) होते हैं, जिनका अपना इंटरप्ट हैंडलर होता है। शेष GPIO को एक सामान्य व्यवधान (EINT3) का उपयोग करना होगा। आप इसके बाद व्यवधान स्थिति रजिस्टर को देख सकते हैं कि किस पिन ने रुकावट को ट्रिगर किया है।
  2. मैं LPC11xx से बहुत परिचित नहीं हूं लेकिन ऐसा लगता है कि इसमें प्रति GPIO पोर्ट एक है। आपको फिर से विशिष्ट पिनों का पता लगाने के लिए स्थिति रजिस्टर की जांच करनी होगी। 12 पिन तक भी हैं जो वेकअप स्रोत के रूप में कार्य कर सकते हैं। मुझे यकीन नहीं है कि यदि आप उन्हें सामान्य व्यवधान के रूप में अपहरण कर सकते हैं (अर्थात वे शायद केवल नींद की स्थिति में ट्रिगर हो जाएंगे)।
  3. डिफ़ॉल्ट हैंडलर तालिका को पता 0 (जो फ़्लैश में है) पर रखा गया है। पहली प्रविष्टि एसपी रजिस्टर के लिए रीसेट मान है, दूसरी रीसेट वेक्टर है, और बाकी अन्य अपवाद और बाधित वैक्टर हैं। पहले वाले कुछ जोड़े (जैसे एनएमआई और हार्डफॉल्ट) एआरएम द्वारा तय किए गए हैं, बाकी चिप-विशिष्ट हैं। यदि आपको रनवे पर वैक्टर को बदलने की आवश्यकता है, तो आप इसे रैम को रीमैप कर सकते हैं (आपको पहले तालिका की प्रतिलिपि बनाने की आवश्यकता है)। LPC11xx में एसआरएएम (0x10000000) की शुरुआत के लिए रीमैपिंग तय है, अन्य चिप्स अधिक लचीले हो सकते हैं।
  4. NVIC को कुशल व्यवधान से निपटने के लिए अनुकूलित किया गया है:
    • प्रत्येक रुकावट के लिए 0-3 के प्रोग्राम योग्य प्राथमिकता स्तर। एक उच्च प्राथमिकता वाले अवरोध कम-प्राथमिकता वाले (नेस्टिंग) को दिखाते हैं। उच्च प्राथमिकता वाले व्यवधान के समाप्त होने पर निम्न प्राथमिकता का निष्पादन शुरू हो जाता है।
    • व्यवधान प्रविष्टि पर प्रोसेसर राज्य का स्वचालित स्टैकिंग; यह सी में सीधे हैंडलर को लिखने की अनुमति देता है और असेंबली रैपर की आवश्यकता को हटा देता है।
    • टेल-चेनिंग: राज्य को फिर से पॉप करने और धक्का देने के बजाय, अगले लंबित व्यवधान को तुरंत नियंत्रित किया जाता है
    • देर से पहुंचने वाला: यदि प्रोसेसर स्थिति को स्टैक करते समय कोई उच्च प्राथमिकता वाला अवरोध आता है, तो पहले से लंबित एक के बजाय इसे तुरंत निष्पादित किया जाता है।

चूंकि आप PIC से परिचित हैं, इस ऐप पर एक नज़र डालें: PIC Microcontrollers से Cortex-M3 की ओर पलायन

यह M3 के बारे में है, लेकिन अधिकांश बिंदु M0 पर भी लागू होते हैं।


8

ऑस्टिन और इगोर जवाब काफी विस्तृत हैं। हालांकि, मैं इसका दूसरे तरीके से जवाब देना चाहता हूं, हो सकता है कि आपको यह मददगार लगे।

LPC11xx (Cortex-M0) में GPIO पिन के लिए 4 स्तर हैं, GPIO0.0 से GPIO0.n तक सभी पिन एक ही इंटरप्ट नंबर साझा करते हैं, और GPIO3.0 से GPIO3.0 तक सभी पिन एक ही इंटरप्ट नंबर साझा करेंगे।

LPC11xx में GPIO इंटरप्ट को इनिशियलाइज़ करने के लिए छह चरण हैं

  1. पिन कनेक्शन ब्लॉक रजिस्टरों को संशोधित करके पिन फ़ंक्शन सेट करें।
  2. GPIO डेटा दिशा रजिस्टर (डिफ़ॉल्ट मान इनपुट है) को संशोधित करके पिन दिशा सेट करें।
  3. प्रत्येक व्यक्तिगत पिन के लिए व्यवधान को सेट करें, आपको GPIO इंटरप्ट मास्क रजिस्टर GPIOnIE पर जाना होगा और बिट (जो पिन से मेल खाती है) तर्क 1 को सेट करना होगा।
  4. बढ़ती बढ़त या गिरने वाले किनारे के लिए या दोनों को GPIO बाधा समझ को संशोधित करके GPIOnIBE और GPIOnIS रजिस्टर करें।
  5. CMSIS फ़ंक्शंस का उपयोग करके नेस्टेड वेक्टरड इंटरप्ट कंट्रोल में PIO_0 / PIO_1 / PIO_2 / PIO_3 में से किसी एक के बीच के स्रोत को सक्षम करें।
  6. CMSIS फ़ंक्शन का उपयोग करके व्यवधान प्राथमिकता सेट करें।

कोड कार्यान्वयन। आपको दो कार्यों की आवश्यकता है: एक ऊपर के 6 चरणों को इनिशियलाइज़ करता है, और दूसरा इंटरप्ट हैंडलर है, जिसे स्टार्ट-अप कोड, startup_LPC11xx.sफ़ाइल में परिभाषित हैंडलर के समान नाम की आवश्यकता होती है । नाम से PIOINT0_IRQHandlerहैं PIOINT3_IRQHandler। यदि आप अलग-अलग नाम का उपयोग करते हैं, तो आपको स्टार्ट-अप फ़ाइल में नामों को बदलना होगा।

/*Init the GPIO pin for interrupt control */
void GPIO_Init(){
    LPC_IOCON-> =..              //Pin configuration register
    LPC_GPIO1->FIODIR = ...      //GPIO Data direction register
    LPC_GPIO1->FIOMASK = ..      //GPIO Data mask register - choose  the right pin
    LPC_GPIO1->GPIOnIE = ..      //Set up falling or rising edge 
    NVIC_EnableIRQ(PIO_1);       //Call API to enable interrupt in NVIC
    NVIC_SetPriority(PriorityN); //Set priority if needed
}


/*Must have the same name as listed in start-up file startup_LPC11xx.s */
void PIOINT1_IRQHandler(void){
   //Do something here
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.