मैं इस समय Cortex M0 / M4 के लिए कोडिंग कर रहा हूं और जिस दृष्टिकोण का हम C ++ में उपयोग कर रहे हैं (कोई C ++ टैग नहीं है, इसलिए यह उत्तर ऑफ-टॉपिक हो सकता है) निम्नलिखित है:
हम एक ऐसे वर्ग का उपयोग करते हैं CInterruptVectorTable
, जिसमें सभी व्यवधान सेवा दिनचर्याएँ होती हैं जो नियंत्रक के वास्तविक व्यवधान वेक्टर में संग्रहीत होती हैं:
#pragma location = ".intvec"
extern "C" const intvec_elem __vector_table[] =
{
{ .__ptr = __sfe( "CSTACK" ) }, // 0x00
__iar_program_start, // 0x04
CInterruptVectorTable::IsrNMI, // 0x08
CInterruptVectorTable::IsrHardFault, // 0x0C
//[...]
}
कक्षा CInterruptVectorTable
में रुकावट वैक्टर का एक अमूर्त भाग होता है, इसलिए आप रनटाइम के दौरान विभिन्न कार्यों को बीच में रोक सकते हैं।
उस वर्ग का इंटरफ़ेस इस तरह दिखता है:
class CInterruptVectorTable {
public :
typedef void (*IsrCallbackfunction_t)(void);
enum InterruptId_t {
INTERRUPT_ID_NMI,
INTERRUPT_ID_HARDFAULT,
//[...]
};
typedef struct InterruptVectorTable_t {
IsrCallbackfunction_t IsrNMI;
IsrCallbackfunction_t IsrHardFault;
//[...]
} InterruptVectorTable_t;
typedef InterruptVectorTable_t* PinterruptVectorTable_t;
public :
CInterruptVectorTable(void);
void SetIsrCallbackfunction(const InterruptId_t& interruptID, const IsrCallbackfunction_t& isrCallbackFunction);
private :
static void IsrStandard(void);
public :
static void IsrNMI(void);
static void IsrHardFault(void);
//[...]
private :
volatile InterruptVectorTable_t virtualVectorTable;
static volatile CInterruptVectorTable* pThis;
};
आपको उन फ़ंक्शन को बनाने की आवश्यकता है जो वेक्टर टेबल में संग्रहीत हैं static
क्योंकि नियंत्रक एक- this
पॉइंटर प्रदान नहीं कर सकता है क्योंकि वेक्टर टेबल ऑब्जेक्ट नहीं है। तो उस समस्या को हल करने के लिए हमारे पास स्थिर- pThis
सूचक है CInterruptVectorTable
। स्थैतिक व्यवधान कार्यों में से एक में प्रवेश करने पर, यह pThis
एक वस्तु के सदस्यों तक पहुंच प्राप्त करने के लिए -pointer तक पहुंच सकता है CInterruptVectorTable
।
अब प्रोग्राम में, आप SetIsrCallbackfunction
किसी फ़ंक्शन को फ़ंक्शन पॉइंटर प्रदान करने के लिए उपयोग कर सकते हैं static
जिसे एक रुकावट होने पर बुलाया जाना है। पॉइंटर्स को स्टोर किया जाता है InterruptVectorTable_t virtualVectorTable
।
और एक रुकावट फ़ंक्शन का कार्यान्वयन इस तरह दिखता है:
void CInterruptVectorTable::IsrNMI(void) {
pThis->virtualVectorTable.IsrNMI();
}
तो यह एक static
अन्य वर्ग (जो हो सकता है private
) की एक विधि को कॉल करेगा , जो तब static
this
उस ऑब्जेक्ट के सदस्य-चर तक पहुंच प्राप्त करने के लिए एक और -पॉइंट कर सकता है (केवल एक)।
मुझे लगता है कि आप IInterruptHandler
वस्तुओं को पॉइंटर्स की तरह बना और इंटरफ़ेस कर सकते हैं, इसलिए आपको static
this
उन सभी वर्गों में -pointer की आवश्यकता नहीं है । (शायद हम कोशिश करते हैं कि हमारी वास्तुकला के अगले पुनरावृत्ति में)
अन्य दृष्टिकोण हमारे लिए ठीक काम करता है, क्योंकि एक बाधा हैंडलर को लागू करने के लिए अनुमति दी गई एकमात्र वस्तुएं हार्डवेयर अमूर्त परत के अंदर होती हैं, और हमारे पास आमतौर पर प्रत्येक हार्डवेयर ब्लॉक के लिए केवल एक ही वस्तु होती है, इसलिए यह static
this
-ऑइंटर्स के साथ ठीक काम करता है। और हार्डवेयर एब्स्ट्रेक्शन लेयर इंटरप्ट को एक और एब्सट्रैक्ट प्रदान करता है, जिसे ICallback
तब हार्डवेयर के ऊपर डिवाइस लेयर में लागू किया जाता है।
क्या आप वैश्विक डेटा का उपयोग करते हैं? सुनिश्चित करें कि आप करते हैं, लेकिन आप अधिकांश वैश्विक डेटा को- this
पॉइंटर्स और इंटरप्ट फ़ंक्शंस की तरह निजी बना सकते हैं ।
यह बुलेटप्रूफ नहीं है, और यह ओवरहेड जोड़ता है। आप इस दृष्टिकोण का उपयोग करके एक IO- लिंक स्टैक को लागू करने के लिए संघर्ष करेंगे। लेकिन अगर आप टाइमिंग के साथ बहुत तंग नहीं हैं, तो यह वैश्विक चर का उपयोग किए बिना मॉड्यूल में इंटरप्ट और संचार का एक लचीला अमूर्तता प्राप्त करने के लिए काफी अच्छी तरह से काम करता है जो हर जगह से सुलभ हैं।