assembly कॉर्टेक्स एम 0+(सैम 21) लंबित अंतरायन निष्पादित नहीं कर रहा है



arduino embedded (1)

String debugstring = ""; यह सुराग है कि यह सामान वास्तव में सी ++ है इस प्रकार आपको शुद्ध सी फ़ंक्शन के रूप में आईआरक्यू हैंडलर घोषित करना होगा:

extern "C" {
void EIC_Handler(void);
}
void EIC_Handler(void){
  int_count++;
  EIC->INTFLAG.reg = 1 << 0;
}

अन्यथा यह समारोह सी ++ है जो आईआरक्यू हैंडलर के रूप में काम नहीं करता है क्योंकि इसे लिंकर द्वारा मान्यता प्राप्त नहीं किया जा सकता है।

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

जब मैं मैन्युअल रूप से एक डीबगर के साथ अपने कोड के माध्यम से कदम करते समय एक दखल को गति देता हूं, तो यह कई चरणों (कभी-कभी 2, कभी-कभी 50 कोड पर निर्भर करता है) को लेता है इससे पहले कि वह आईएसआर को कूदता है।

इस मुद्दे को डिबग करने की कोशिश करते समय मैंने यह बहुत आसान कोड लिखा था जो इस मुद्दे को प्रदर्शित करता है:

#include <Arduino.h>
// Setup and Loop declared in Arduino core
void configInterrupt(void);
volatile uint32_t debug = 0;
uint32_t int_count = 0;

void EIC_Handler(void){
  int_count++;
  EIC->INTFLAG.reg = 1 << 0;
}

void configInterrupt(void){
  NVIC_DisableIRQ(EIC_IRQn);
  NVIC_ClearPendingIRQ(EIC_IRQn);
  NVIC_SetPriority(EIC_IRQn, 0);
  NVIC_EnableIRQ(EIC_IRQn);
  GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_EIC));
  EIC->WAKEUP.reg |= (1 << 0);
  EIC->CONFIG[0].reg |= 0x2;                    // falling edge
  pinConfig(16,INPUT,UP);                   // pin 16 as input with pullup 
  PORT->Group[0].PINCFG[16].bit.PMUXEN = 1; // enable peripheral muxing
  PORT->Group[0].PMUX[8].bit.PMUXE = 0x0;       // function A (EIC) = 0x0
  EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << 0);
  EIC->CTRL.bit.ENABLE = 1;
}

void setup() {
  configInterrupt();                            
}

void loop() {
  for(int i = 0 ; i < 100 ; i++) debug++;   // volatile so that the compiler doesn't touch

  String debugstring = "";

  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __DSB();
  __WFI();
}

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

मैंने SAMD21 डेटापत्रक में इंटरप्ट और अपवादों के बारे में बहुत कुछ पढ़ा है, कोर्टेक्स एम 0 + जेनेरिक उपयोगकर्ता गाइड और एआरएम आर्किटेक्चर मैनुअल। माना जाता है कि कोर्टेक्स एम सीरीज़ में कम लेटेंसी इंटरप्ट होता है, जिसमें कोई निर्देश ओवरहेड नहीं होता है और ऐसा लगता है कि कोड इंटरप्ट को ट्रिगर करने के तुरंत बाद आईएसआर पर कूद जाना चाहिए।

मैंने एआरएम आर्किटेक्चर मैनुअल के कॉरटेक्स एम 0 + जेनेरिक गाइड के 2.3.6 को कई बार और साथ ही बी 1.3.2 पढ़ा है, जो विस्तार के काफी थोड़ा सा कवर अपवाद प्रविष्टि है। SAMD21 डेटा पत्रक में बहुत कम स्तर की जानकारी नहीं होती है

मैंने इस समस्या को अलग करने और डिवाइस के व्यवहार में किसी भी पैटर्न की पहचान करने की कोशिश की है और मैंने कुछ चीजें देखी हैं

यह केवल कोड की विशिष्ट लाइनों पर आईएसआर के लिए कूदता है। उदाहरण के लिए उपरोक्त कोड में, यदि बाहरी इंटरप्ट को 'लूप ()' की शुरुआत में ट्रिगर किया गया है, तो यह 'for' लूप में कितने पुनरावृत्तियों की परवाह किए बिना स्ट्रिंग घोषित होने पर आईएसआर पर कूद जाएगा। अगर मैं 'के लिए' लूप के ऊपर स्ट्रिंग घोषणा को ऊपर ले जाता हूं, तो यह आईएसआर के लिए लगभग तुरंत कूद जाएगा (2 या 3 डिबगिंग चरणों के बाद)

मैंने देरी, एनओपी और आईएसबी डालने की कोशिश की है, जो इसे कितना समय लगेगा या इसे तुरन्त छलांग नहीं बनाते जब मैं एनवीआईसी में आईएसपीआर रजिस्टर के माध्यम से सॉफ़्टवेयर में एक लंबित अंतरायन स्थापित करता हूं, तो समान समस्या होती है। मैंने Atmel स्टूडियो में आधार फ्लैश मेमोरी का ट्रैक रखा है और देखा है कि "स्टैक" जिस पर प्रोसेसर का वर्तमान 'स्टेट' धकेल रहा है, वह तुरंत बदल नहीं सकता है यह केवल तभी बदलता है जब मैं आईएसआर में कोड की पहली पंक्ति पर जाता हूं।

कोड के अन्य टुकड़े जिन पर मैंने स्ट्रिंग घोषणा के समान कार्य देखा है और कोड को आईएसआर पर जाने के लिए कारण होता है वायर लायब्रेरी का अंत संचारण समारोह, एसडी कार्ड लाइब्रेरी में कुछ फ़ंक्शन, Arduino विलंब समारोह

क्या यह इस तथ्य से संबंधित हो सकता है कि मैं पहली जगह में एक डिबगर का उपयोग कर रहा हूं जो हस्तक्षेप / बाधाओं के साथ अच्छा नहीं खेलता है? मैं काफी यकीन है कि इससे पहले कि मैं डीबगर को बाहर निकालने से पहले समस्या हुई। संपादित करें: कोर्टेक्स एम 0 + तकनीकी संदर्भ मैनुअल और एआरएमवी 6 मैनुअल के माध्यम से पढ़ना मैंने एक रजिस्टर नामक डीएचसीएसआर पाया है जो डिबगर को मुखौटा को मुखौटा बनाने की अनुमति देता है, लेकिन मैं इन रजिस्टरों तक कैसे पहुंच सकता हूं

मुख्य प्रश्न: PRIMASK और वैश्विक / व्यक्तिगत रजिस्टर बिट्स के अलावा, निष्पादित होने से लंबित बाधा को रोकने में और क्या रोक सकता है?

संपादित करें: जानकारी का एक महत्वपूर्ण हिस्सा छोड़ दिया, हालांकि मैं Atmel स्टूडियो में काम कर रहा हूँ परियोजना Arduino कोर का उपयोग करता है

संपादित करें: मैंने गौर किया है कि मैन्युअल रूप से एक अंतराल को ट्रिगर करने के बाद, यह मेरे अगले डिबगिंग चरण के दौरान एनवीआईसी-> आईएसपीआर रजिस्टर में लंबित हो जाता है। इससे मुझे विश्वास हो जाता है कि बीच में बीच में घुसपैठ किया जा रहा है (मैंने पीरमास्क की जांच की है, वैश्विक सक्षम और व्यक्ति को अब तक कोई भाग्य के साथ सक्षम नहीं है)।