c ((पोर्ट*) 0x41004400UL) क्या मतलब है?




arm embedded (2)

मैं एक विकासशील बोर्ड पर काम कर रहा हूं जिस पर 32-बिट एआरएम आधारित माइक्रोप्रंट्रोलर (अर्थात् बोर्ड Atmel SAM D21J18A) है। मैं अभी भी सीखने के चरण में हूं और मेरे पास बहुत कुछ है, लेकिन मैं वास्तव में एम्बेडेड सिस्टम में हूँ

मुझे सी में कुछ पृष्ठभूमि है। हालांकि, यह स्पष्ट रूप से पर्याप्त नहीं है। मैं Atmel द्वारा एक उदाहरण परियोजना के कोडों को देख रहा था, और मुझे वास्तव में इसका कुछ हिस्सा नहीं मिला उनमें से एक यहां पर है:

    #define PORT              ((Port     *)0x41004400UL) /**< \brief (PORT) APB Base Address */

पोर्ट के रूप में परिभाषित किया गया है:

    typedef struct {
        PortGroup             Group[2];    /**< \brief Offset: 0x00 PortGroup groups [GROUPS] */
    } Port;

और पोर्ट ग्रुप को इस प्रकार परिभाषित किया गया है:

typedef struct {
    __IO PORT_DIR_Type             DIR;         /**< \brief Offset: 0x00 (R/W 32) Data Direction */
    __IO PORT_DIRCLR_Type          DIRCLR;      /**< \brief Offset: 0x04 (R/W 32) Data Direction Clear */
    __IO PORT_DIRSET_Type          DIRSET;      /**< \brief Offset: 0x08 (R/W 32) Data Direction Set */
    __IO PORT_DIRTGL_Type          DIRTGL;      /**< \brief Offset: 0x0C (R/W 32) Data Direction Toggle */
    __IO PORT_OUT_Type             OUT;         /**< \brief Offset: 0x10 (R/W 32) Data Output Value */
    __IO PORT_OUTCLR_Type          OUTCLR;      /**< \brief Offset: 0x14 (R/W 32) Data Output Value Clear */
    __IO PORT_OUTSET_Type          OUTSET;      /**< \brief Offset: 0x18 (R/W 32) Data Output Value Set */
    __IO PORT_OUTTGL_Type          OUTTGL;      /**< \brief Offset: 0x1C (R/W 32) Data Output Value Toggle */
    __I  PORT_IN_Type              IN;          /**< \brief Offset: 0x20 (R/  32) Data Input Value */
    __IO PORT_CTRL_Type            CTRL;        /**< \brief Offset: 0x24 (R/W 32) Control */
    __O  PORT_WRCONFIG_Type        WRCONFIG;    /**< \brief Offset: 0x28 ( /W 32) Write Configuration */
    RoReg8                         Reserved1[0x4];
    __IO PORT_PMUX_Type            PMUX[16];    /**< \brief Offset: 0x30 (R/W  8) Peripheral Multiplexing n */
    __IO PORT_PINCFG_Type          PINCFG[32];  /**< \brief Offset: 0x40 (R/W  8) Pin Configuration n */
    RoReg8                         Reserved2[0x20];
} PortGroup;

तो यहां, हम 0x41004400UL पते को देख रहे हैं, वहां डेटा प्राप्त करें, और फिर क्या होता है?

मैंने इसके लिए देखा लेकिन उपयोगी कुछ भी नहीं मिल सका। यदि आपके पास कोई सुझाव (ट्यूटोरियल, पुस्तकें आदि) हैं, तो कृपया मुझे सुनें।


कुछ भी नहीं होता है, क्योंकि आप केवल कुछ घोषणाओं को प्रस्तुत करते हैं। मुझे पूरी तरह से यकीन नहीं है कि प्रश्न वास्तव में क्या है, लेकिन संक्षेप में उस कोड को स्पष्ट करने के लिए:

  • 0x41004400UL जाहिर है I / O अंतरिक्ष में एक पता (नियमित मेमोरी नहीं) जहां एक पोर्ट शुरू होता है (I / O रजिस्टरों का एक समूह)

  • इस बंदरगाह में एकल समूहों की एक समान व्यवस्था वाले दो समूह होते हैं

  • स्ट्रक्चर PortGroup मॉडल हार्डवेयर पर मौजूद लेआउट में ठीक से इन रजिस्टर करता है

रजिस्टरों के अर्थ को जानने के लिए, हार्डवेयर दस्तावेज़ देखें


आम तौर पर आप सी में एक हार्डवेयर रजिस्टर इस तरीके से एक्सेस कर सकते हैं:

#define PORT  (*(volatile uint8_t*)0x1234)
  • 0x1234 रजिस्टर पता है
  • uint8_t रजिस्टर का प्रकार है, इस मामले में 1 बाइट बड़े
  • volatile आवश्यक है ताकि कंपाइलर जानता है कि वह इस तरह के एक चर का अनुकूलन नहीं कर सकता है, लेकिन यह कि प्रत्येक कोड में वर्णित वेरिएबल को पढ़ या लिखना वास्तव में किया जाना चाहिए।
  • (volatile uint8_t*) वांछित प्रकार के एक पते के लिए पूर्णांक शाब्दिक डाले।
  • बाएं-सबसे अधिक * तो उस पते की सामग्री ले लो, ताकि मैक्रो का इस्तेमाल किया जा सके, जैसे कि पीओआरटी एक नियमित चर था।

ध्यान दें कि यह कुछ भी आवंटित नहीं करता है! यह सिर्फ मानता है कि दिए गए पते पर एक हार्डवेयर रजिस्टर मौजूद है, जिसे निर्दिष्ट प्रकार ( uint8_t ) द्वारा एक्सेस किया जा सकता है

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

आपके उदाहरण में विशिष्ट कोड के लिए, यह किसी विशिष्ट हार्डवेयर परिधीय (एक सामान्य सामान्य प्रयोजन I / O पोर्ट की तरह दिखता है) के लिए विशिष्ट माइक्रोकंट्रोलर पर एक ठेठ भयानक रजिस्टर मैप है। एक ऐसा जानवर आमतौर पर एमसीयू का समर्थन करने वाले प्रत्येक संकलक के साथ प्रदान किया जाता है।

ऐसे रजिस्टर मैप्स दुर्भाग्य से हमेशा भयानक, पूरी तरह से गैर-पोर्टेबल तरीके से लिखा जाता है। उदाहरण के लिए, दो रेखांकित __ सी में एक निषिद्ध पहचानकर्ता है। न तो कंपाइलर और न ही प्रोग्रामर को ऐसी पहचानकर्ता (7.1.3) घोषित करने की अनुमति है।

क्या वास्तव में अजीब बात यह है कि उन्होंने volatile खोजशब्द को छोड़ा है। इसका अर्थ है कि यहां इन स्थितियों में से एक है:

  • वाष्पशील कीवर्ड Port परिभाषा के नीचे छिपा हुआ है। सबसे अधिक संभावना यह मामला है, या
  • रजिस्टर नक्शा घातक कीड़े से भरा है, या
  • कंपाइलर बकवास का एक भयानक टुकड़ा है कि यह सभी पर चर का अनुकूलन नहीं करता है। जो volatile साथ मुद्दों को दूर जाना होगा।

मैं इसे आगे की जांच करूँगा

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





atmelstudio