I / O पिन एब्स्ट्रक्शन के लिए C ++ क्लासेस


13

मैं हार्डवेयर I / O अंक या पिन के लिए C ++ एब्स्ट्रैक्ट की तलाश कर रहा हूं। In_pin, out_pin, inout_pin, शायद open_collector_pin, आदि जैसी चीजें।

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

Google ने कुछ भी नहीं किया, शायद इसलिए कि मुझे नहीं पता कि दूसरे इसे कैसे कहेंगे।

मेरा उद्देश्य I / O पुस्तकालयों का निर्माण करना है जो ऐसे बिंदुओं पर आधारित हैं, लेकिन ऐसे बिंदु भी प्रदान करते हैं, इसलिए उदाहरण के लिए एक HD44780 LCd को चिप के IO पिन या I2C (या SPI) से जोड़ना आसान होगा। I / O एक्सटेंडर, या कोई अन्य बिंदु जो किसी भी तरह से नियंत्रित किया जा सकता है, बिना एलसीडी क्लास के किसी भी बदलाव के।

मुझे पता है कि यह इलेक्ट्रॉनिक्स / सॉफ्टवेयर बढ़त पर है, क्षमा करें यदि यह यहां नहीं है।

@ एलोन: वायरिंग सॉफ्टवेयर का एक बड़ा बैग है, मुझे करीब से देखने की आवश्यकता होगी। लेकिन लगता है कि वे एक पिन अमूर्तता का उपयोग नहीं करते हैं जैसे मैं चाहता हूं। उदाहरण के लिए कीपैड कार्यान्वयन में मैं देख रहा हूं

digitalWrite(columnPins[c], LOW);   // Activate the current column.

इसका तात्पर्य यह है कि एक फ़ंक्शन (digitalWrite) है जो जानता है कि I / O पिन कैसे लिखना है। इससे एक नए प्रकार के I / O पिन को जोड़ना असंभव हो जाता है (उदाहरण के लिए एक MCP23017 पर, इसलिए इसे I2C के माध्यम से लिखा जाना चाहिए) बिना digitalWrite फ़ंक्शन को फिर से लिखना।

@ ओली: मैंने एक Arduino IO का उदाहरण दिया, लेकिन वायरिंग लाइब्रेरी के समान दृष्टिकोण के बारे में उपयोग करना प्रतीत होता है:

int ledPin = 13;                 // LED connected to digital pin 13
void setup(){
    pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

हम यहां किस माइक्रोकंट्रोलर से बात कर रहे हैं?
मजेंको सेप

वह अप्रासंगिक है; एक विशेष माइक्रोकंट्रोलर के लिए उस uC wil के io पिन उपयुक्त इंटरफेस को लागू करेंगे। लेकिन यह C ++ के लिए है, इसलिए ARM, Cortex और MIPS जैसे 32-बिट चिप्स के बारे में सोचें।
वाउटर वैन ओइजेन

1
मैंने कभी एक का उपयोग नहीं किया है, लेकिन क्या Arduino इस तरह से सभी पिनों को अमूर्त नहीं करता है? आप कुछ उपयोगी जानकारी प्राप्त कर सकते हैं (जिस तरह से उन्होंने चीजों को किया है)।
ओली ग्लेसर

1
और digitalWrite फ़ंक्शन को फिर से लिखने के लिए - C ++ में "ओवरलोडिंग" देखें। मैं अभी कुछ समय पहले Arduino के लिए एक IO विस्तारक बोर्ड के लिए एक अधिभार digitalWrite फ़ंक्शन लिखा है। जब तक आप अलग-अलग मापदंडों का उपयोग करते हैं (मैंने पहले "int" को "संरचना" के साथ बदल दिया) यह डिफ़ॉल्ट रूप से आपके डिजिटलविराइट को वरीयता में ले जाएगा।
मजेंको

1
मैंने इस विषय पर अपने काम के बारे में बर्लिन में C ++ से मिलने की बात की। यह youtube पर पाया जा सकता है: youtube.com/watch?v=k8sRQMx2qUw तब से मैं थोड़ा अलग दृष्टिकोण पर आ गया, लेकिन बात अभी भी दिलचस्प हो सकती है।
राउटर वैन ओइजेन

जवाबों:


3

संक्षिप्त उत्तर: दुख की बात है कि आप जो चाहते हैं, वह करने के लिए कोई पुस्तकालय नहीं है। मैंने इसे स्वयं कई बार किया है लेकिन हमेशा गैर-ओपन-सोर्स प्रोजेक्ट्स में। मैं गितुब पर कुछ डालने पर विचार कर रहा हूं लेकिन मुझे यकीन नहीं है कि मैं कब कर सकता हूं।

C ++ क्यों?

  1. संकलक गतिशील शब्द-आकार अभिव्यक्ति मूल्यांकन का उपयोग करने के लिए स्वतंत्र है। C इंट का प्रचार करता है। आपका बाइट मास्क / शिफ्ट तेजी से / छोटा किया जा सकता है।
  2. इनलाइन।
  3. टेंपलेटाइजिंग ऑपरेशन आपको शब्द आकार और अन्य गुणों को अलग-अलग प्रकार की सुरक्षा के साथ बदलता है।

5

मुझे बेशर्मी से अपने ओपन सोर्स प्रोजेक्ट https://Kvasir.io को प्लग इन करने की अनुमति दें । क्वासिर :: Io भाग पिन जोड़तोड़ कार्य प्रदान करता है। आपको पहले अपना पिन परिभाषित करना होगा एक क्वासिर :: Io :: PinLocation की तरह

constexpr PinLocation<0,4> led1;    //port 0 pin 4
constexpr PinLOcation<0,8> led2;

ध्यान दें कि यह वास्तव में रैम का उपयोग नहीं करता है क्योंकि ये कॉन्स्ट्रेक्स चर हैं।

अपने पूरे कोड के दौरान आप 'एक्शन फैक्ट्री' में इन पिन स्थानों का उपयोग कर सकते हैं जैसे मेकओप्रेन, सेट, क्लियर, मेक ऑउटपुट और इतने पर। एक 'एक्शन फैक्ट्री' वास्तव में कार्रवाई को अंजाम नहीं देता है, बल्कि यह एक क्वासिर :: रजिस्टर :: एक्शन देता है जिसे क्वासिर का उपयोग करके निष्पादित किया जा सकता है :: रजिस्टर :: लागू करें ()। इसका कारण यह है कि लागू () उस पर पारित किए गए कार्यों को मर्ज कर देता है जब वे एक और एक ही रजिस्टर पर कार्य करते हैं ताकि दक्षता प्राप्त हो।

apply(makeOutput(led1),
    makeOutput(led2),
    makeOpenDrain(led1),
    makeOpenDrain(led2));

चूंकि क्रियाओं के निर्माण और विलय का संकलन समय पर किया जाता है, इसलिए इसे समान कोडांतरक कोड के रूप में प्राप्त करना चाहिए, जैसे कि विशिष्ट हाथ कोडित समान:

PORT0DIR |= (1<<4) | (1<<8);
PORT0OD |= (1<<4) | (1<<8);

3

तारों की परियोजना अमूर्त की तरह उपयोग करती है:

http://wiring.org.co/

और संकलक C ++ में लिखा गया है। आपको स्रोत कोड में बहुत सारे उदाहरण खोजने चाहिए। Arduino सॉफ्टवेयर वायरिंग पर आधारित है।


प्रश्न निकाय में उत्तर दिया गया है
राउटर वैन ओइजेन

2

C ++ में, एक वर्ग लिखना संभव है, ताकि आप I / O पोर्ट का उपयोग कर सकें, जैसे कि वे चर थे, उदाहरण के लिए

  PORTB = 0x12; / * 8-बिट पोर्ट पर लिखें * /
  अगर (RB3) LATB4 = 1; / * एक I / O पढ़ें और सशर्त रूप से एक और लिखें * /

अंतर्निहित कार्यान्वयन के लिए संबंध के बिना। उदाहरण के लिए, यदि कोई एक हार्डवेयर प्लेटफ़ॉर्म का उपयोग कर रहा है जो बिट-स्तरीय संचालन का समर्थन नहीं करता है, लेकिन बाइट-स्तर के रजिस्टर संचालन का समर्थन करता है, तो एक (शायद कुछ मैक्रोज़ की सहायता से) एक स्थैतिक वर्ग IO_PORTS को इनलाइन रीड-राइट के साथ परिभाषित कर सकता है गुण जिसे bbRB3 और bbLATB4 कहा जाता है, जैसे कि ऊपर दिया गया अंतिम विवरण बदल जाएगा

  if (IO_PORTS.bbRB3) IO_PORTS.bbLATB4 = 1;

जो बदले में कुछ इस तरह से संसाधित किया जाएगा:

  if (!! (PORTB & 8)) (1? (PORTB | = 16): (PORTB & = ~ 16%);

एक संकलक में स्थिर अभिव्यक्ति को नोटिस करने में सक्षम होना चाहिए ?: ऑपरेटर और बस "सच" भाग शामिल करें। यह संभव हो सकता है कि मैक्रोज़ द्वारा बनाई गई संपत्तियों की संख्या को कुछ कम करने के लिए विस्तारित किया जाए:

  अगर (IO_PORTS.ppPORTB [3]) IO_PORTS.ppPORTB [4] = 1;

या

  if (IO_PORTS.bb (addrPORTB, 3)) IO_PORTS.bbPORTB (addrPORTB, 4) = 1;

लेकिन मुझे यकीन नहीं है कि एक संकलक कोड को अच्छी तरह से इन-लाइन करने में सक्षम होगा।

मैं किसी भी तरह से मतलब नहीं है कि मैं / हे बंदरगाहों का उपयोग कर के रूप में यद्यपि वे चर रहे हैं जरूरी एक अच्छा विचार है, लेकिन जब से आप C ++ का उल्लेख करते हैं, यह जानने के लिए एक उपयोगी चाल है। C या C ++ में मेरी स्वयं की पसंद, यदि उपरोक्त कोड शैली का उपयोग करने वाले कोड के साथ संगतता की आवश्यकता नहीं थी, तो संभवतः प्रत्येक I / O बिट के लिए कुछ प्रकार के मैक्रो को परिभाषित करना होगा, और फिर "readBit", "राइटबाइट" के लिए मैक्रोज़ को परिभाषित करना होगा। "setBit", और "ClearBit" प्रोविज़ो के साथ कि उन मैक्रोज़ को पास किए गए बिट-आइडेंटिग तर्क को ऐसे मैक्रोज़ के साथ उपयोग के लिए I / O पोर्ट का नाम होना चाहिए। उदाहरण के लिए, उपरोक्त उदाहरण के रूप में लिखा जाएगा

  if (readBit (RB3)) setBit (LATB4);

और के रूप में अनुवाद किया

  अगर (!! (_ PORT_RB3 & _BITMASK_RB3)) _PORT_LATB4 | = _BITMASK_LATB4;

यह C ++ शैली की तुलना में प्रीप्रोसेसर के लिए थोड़ा अधिक काम होगा, लेकिन यह संकलक के लिए कम काम होगा। यह भी कई I / O कार्यान्वयन के लिए इष्टतम कोड पीढ़ी, और लगभग सभी के लिए सभ्य कोड कार्यान्वयन की अनुमति देगा।


3
प्रश्न से एक उद्धरण: "मैं 'के लिए नहीं देख रहा हूँ अरे, आप इसे इस तरह से कर सकते हैं" उत्तर के प्रकार "...
Wouter van Ooijen

मुझे लगता है कि मैं स्पष्ट नहीं हूं कि आप क्या देख रहे हैं। निश्चित रूप से मैं उम्मीद करूंगा कि बहुत से लोग जो I / O पिन पुनर्निर्माण के लिए कक्षाओं में रुचि रखते हैं, उन्हें यह जानने में भी दिलचस्पी होगी कि गुणों का उपयोग करके कोड बना सकते हैं जो कि I / O की एक शैली के लिए लिखा जाता है, बस कुछ और के बारे में उपयोग करें। मैंने "LATB3 = 1;" जैसे कथन बनाने के लिए गुणों का उपयोग किया है TCP स्ट्रीम के लिए I / O अनुरोध भेजें।
सुपरकाट

मैंने अपने प्रश्न में स्पष्ट होने की कोशिश की: मैं IO पिन का उपयोग करने वाले कोड को फिर से लिखने के बिना नए प्रकार के IO पिनों को व्यवस्थित करने में सक्षम होना चाहता हूं। आप उपयोगकर्ता-परिभाषित प्रकार के रूपांतरणों और असाइनमेंट ऑपरेटरों के बारे में लिखते हैं, जो निश्चित रूप से दिलचस्प हैं, मैं हर समय उनका उपयोग करता हूं, लेकिन मेरी समस्या का समाधान नहीं।
रूटर वैन ऊइजेन सेप

@ राउटर वैन ओइजेन: क्या "नए प्रकार के I / O पिंस" आप अनुमान लगा रहे होंगे? यदि स्रोत कोड को "if (BUTTON_PRESSED) MOTOR_OUT = 1;" जैसे सिंटैक्स के साथ लिखा गया है, तो मैं उम्मीद करूंगा कि किसी भी तंत्र के बारे में जिसके द्वारा प्रोसेसर एक बटन नियंत्रण पढ़ सकता है या एक मोटर एक पुस्तकालय लिख सकता है, इसलिए उपरोक्त स्रोत यदि बटन धकेल दिया जाए तो कोड मोटर पर बदल जाएगा। इस तरह की लाइब्रेरी मोटर को चालू करने के सबसे कुशल तरीके का प्रतिनिधित्व नहीं कर सकती है, लेकिन इसे काम करना चाहिए।
सुपरकाट

@Wouter van Ooijen: यदि कोई आवश्यक हो तो दक्षता में सुधार कर सकता है यदि कोई स्रोत किसी भी इनपुट को पढ़ने से कुछ समय पहले UPDATE_IO () या UPDATE_INPUTS () मैक्रो को इनवॉइस करता है, और किसी भी आउटपुट के साथ कुछ समय बाद UPDATE_IO () या UPDATE_OUTPUTS () प्रदर्शन करता है। वे शब्दांश जिन्हें इनपुट या तो पढ़े जाने वाले कोड पर या पिछले UPDATE_INPUTS () / UPDATE_IO () मंगलाचरण के नमूने लिए जा सकते हैं। इसी तरह आउटपुट या तो तुरंत घटित हो सकता है या स्थगित हो सकता है। यदि एक I / O को एक शिफ्ट रजिस्टर की तरह कुछ का उपयोग करके कार्यान्वित किया जाता है, तो कार्रवाई को स्थगित करना कई कार्यों को समेकित करने की अनुमति देगा।
16

1

यदि आप हार्डवेयर को अमूर्त करने के लिए वास्तव में बहुत बढ़िया हैं, और आप अपने C ++ कौशल में आश्वस्त हैं, तो आपको यह पैटर्न आज़माना चाहिए:

https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

मैंने इसका उपयोग एक कॉर्टेक्स- M0 चिप के लिए हार्डवेयर को अमूर्त करने के प्रयास में किया है। मैंने अभी तक इस अनुभव के बारे में कुछ भी नहीं लिखा है (मैं किसी दिन ऐसा करूंगा), लेकिन मेरा विश्वास है कि यह अपने स्थैतिक बहुरूपी प्रकृति के कारण बहुत उपयोगी रहा है: विभिन्न चिप्स के लिए एक ही विधि, बिना किसी लागत के (गतिशील बहुरूपता की तुलना में)।


इस पोस्ट के बाद के वर्षों में मैंने pin_in, pin_out, pin_oc और pin_out_out के लिए अलग-अलग "कक्षाओं" पर कदम रखा। इष्टतम प्रदर्शन (आकार और गति) के लिए, मैं स्थिर कक्षाओं का उपयोग करता हूं, जिसे टेम्पलेट मापदंडों के रूप में पारित किया गया है। मैंने बर्लिन में C ++
Wouter van Ooijen
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.