2009-11-26 24 views
11

मैं एक एम्बेडेड सिस्टम (डीएसपीआईसी 33 मंच) के लिए सी कोड लिख रहा हूं, और मैं कई परियोजनाओं के बीच उपयोग करने के लिए एक पुन: प्रयोज्य कोड लाइब्रेरी का निर्माण करने पर विचार कर रहा हूं।पुन: प्रयोज्य एम्बेडेड सी के लिए सर्वोत्तम अभ्यास?

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

स्पष्ट रूप से पुस्तकालय में कुछ हार्डवेयर-विशिष्ट (और इस प्रकार परियोजना-विशिष्ट) निर्भरताएं होंगी, इसलिए यह मानना ​​उचित है कि इसे प्रत्येक प्रोजेक्ट (बाइनरी रूप में लिंक करने के बजाय) के साथ संकलित किया जाएगा।

जो कुछ भी मैंने अभी तक किया है, वह पुस्तकालय को केंद्रीय रूप से स्थित रखना है, लेकिन एक परियोजना-विशिष्ट लाइब्रेरी कॉन्फ़िग.h की आवश्यकता है जिसमें फ़ंक्शन परिभाषाएं, मैक्रोज़ इत्यादि शामिल हैं। इसके लिए लाइब्रेरी में हेडर शामिल है कोड, जिसका अर्थ है कि प्रोजेक्ट स्रोत निर्देशिका को शामिल पथ (केवल लाइब्रेरी स्रोत निर्देशिका नहीं) में होना आवश्यक है। उस तरह के #include "" और #include <> के बीच भेद को गड़बड़ कर देता है, है ना?

क्या यह सामान्य रूप से किया जाता है?

उत्तर

7

एक बहुत अच्छा सवाल-जवाब सरल नहीं है। विचार करने के लिए कई चीजें। यहां तक ​​कि मेरे अनुभव से कुछ राय यहां दी गई हैं।

आम बनाम परियोजना स्थानीय कोड को कॉपी

एक महत्वपूर्ण निर्णय है कि क्या "आम" पुस्तकालय कोड है कि (अपनी कंपनी के "पुन: उपयोग के पुस्तकालय") एक केंद्रीय स्थान से स्वचालित रूप से अद्यतन किया जाता है का उपयोग करना है, या क्या रखने के लिए एक परियोजना-स्थानीय प्रति।

यह this SO question में विस्तार से चर्चा की है।

एक केन्द्रीय पुस्तकालय का लाभ यह है कि काम एक बार किया कई परियोजनाओं को लाभ हो सकता है। एक परियोजना-स्थानीय प्रतिलिपि के साथ कठिनाई यह है कि किसी भी बग फिक्स और सुधार केंद्रीय पुस्तकालय में वापस योगदान नहीं दिया जाता है, और केंद्रीय पुस्तकालय में किसी भी बग फिक्स को आपके प्रोजेक्ट में नहीं लाया जा सकता है।

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

आम कोड से बाहर उर्फ ​​केंद्रीय पुन: उपयोग पुस्तकालय अच्छा मूल्य प्राप्त करने के लिए:

पुस्तकालय:

  • अच्छी तरह से परिभाषित आवश्यकताओं, एपीआई, और इकाई परीक्षण
  • परियोजना विशेष से बचना चाहिए होना आवश्यक है कोड; यह सामान्य प्रयोजन होना चाहिए
  • सफाई से परियोजना-विशिष्ट सेटिंग की स्थापना (इस, एपीआई के हिस्से के रूप में देखा जा सकता प्रभावी ढंग से)
  • संस्करण संख्याओं और सुधारों के साथ, एक औपचारिक रिहाई प्रक्रिया होनी चाहिए के लिए एक तंत्र होना चाहिए, मुद्दों ट्रैक किया जाना चाहिए।

व्यक्तिगत परियोजनाओं:

  • स्वचालित रूप से और आँख बंद करके "नवीनतम" नहीं मिलना चाहिए, लेकिन एक निर्दिष्ट संस्करण संख्या के साथ एक विशेष "रिलीज" प्राप्त करने के लिए सक्षम होना चाहिए। फिर परियोजनाओं पर नियंत्रण होना चाहिए यदि वे एक नए संस्करण में अपडेट करते हैं। परियोजना स्पष्ट रूप से ट्रैक करने में सक्षम होना चाहिए, "हम लाइब्रेरी xyz के संस्करण 1.2.3 का उपयोग कर रहे हैं"।
  • यदि संभव हो तो लाइब्रेरी कोड को "फोर्किंग" से बचना चाहिए। जैसे लाइब्रेरी कोड में प्रोजेक्ट-विशिष्ट "फीचर्स" जोड़ने से बचें।
  • लाइब्रेरी कोड
  • पर किसी स्थानीय संशोधन को ट्रैक करना चाहिए, यदि संभव हो तो केंद्रीय पुस्तकालय में तय होने के लिए बग को लाइब्रेरी बग के रूप में माना जाना चाहिए। कंपनी को केंद्रीय पुस्तकालय में उन्हें ठीक करने के लिए प्रक्रियाएं होनी चाहिए, लाइब्रेरी का परीक्षण अपने स्वयं के यूनिट टेस्ट सूट (शायद भविष्य में बग को पकड़ने के लिए यूनिट परीक्षण में सुधार करना)। फिर आवश्यकतानुसार केंद्रीय पुस्तकालय का एक नया संस्करण जारी करें, और यदि अन्य परियोजनाएं फिट हों तो अन्य परियोजनाओं पर तैनात करें।

एक कंपनी जगह में ऐसी प्रक्रिया नहीं है, तो एक परियोजना सिर्फ कोड का एक टुकड़ा की एक स्थानीय प्रति (जैसे कि, पिछले एक परियोजना से नकल) और फिर बनाना चाहिए पूर्ण परियोजना स्थानीय जिम्मेदारी लेने उसके बाद से। आपको अभी भी उस स्थिति में पुन: उपयोग से कुछ लाभ मिल रहा है, क्योंकि आप इसे स्क्रैच से पुनः लिख नहीं रहे हैं।

परियोजना विशिष्ट विन्यास

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

यह कैसे किया जा सकता है इसका एक अच्छा उदाहरण के लिए, Micrium से जीन लैब्रोसे द्वारा µC/OS-II RTOS (book) देखें।

1

यह भेद को गड़बड़ नहीं करता है, जो लगभग पूरी तरह प्लेटफॉर्म-परिभाषित है। एकमात्र परिभाषित व्यवहार यह है कि यदि "" फ़ाइल का उपयोग करने में विफलता शामिल है, तो यह फिर से खोजता है जैसे कि आपने <> कहा था।

मुझे लगता है कि आप सही काम कर रहे हैं। मेरे अनुभव में प्लेटफ़ॉर्म-विशिष्ट शीर्षलेख को संभालने का सामान्य तरीका यह है कि आप इसे एक ऐसा नाम देते हैं जिसे आप जितना संभव हो उतना आत्मविश्वास रखते हैं, कभी भी किसी और चीज़ के साथ टकराव नहीं करेंगे, और #के साथ इसे शामिल करें। फिर आप यह सुनिश्चित करने के लिए प्लेटफॉर्म पोर्टर को जो भी कंपाइलर-विशिष्ट चीज़ आवश्यक है, यह सुनिश्चित करने के लिए बताएं। आम तौर पर इसका मतलब है कि कुछ कंपाइलर तर्क निर्दिष्ट करना- I, जहां भी वह फ़ाइल रखना चाहता है। तो हाँ, उसकी परियोजना की निर्देशिका में से एक। लेकिन अगर सब कुछ विफल रहता है तो वह हमेशा अपनी फाइल को किसी ऐसे स्थान पर कॉपी कर सकता है जहां उसका कंपाइलर दिखाई देगा। वह इसे अपने पुस्तकालय स्रोत की अपनी स्थानीय प्रतिलिपि में भी कॉपी कर सकता है, अगर उसका संकलक पूरी चीज के बारे में अनुचित रूप से मुश्किल हो रहा है।

एक और तरीका है, पुस्तकालय, selectplatform.h में एक फ़ाइल है इस तरह लग रही:

// obviously WIN32 isn't an embedded platform, and GCC is too broad 
// to be supported by a single header file. Replace with whatever platforms 
// it is you do support out of the box. 
#if _WIN32 
    #include "platforms/msvc32.h" 
#elif __GNUC__ 
    #include "platforms/gcc.h" 
#else 
    #error "You must add a new clause to selectplatform.h for your platform" 
#endif 

इस संकलक विन्यास के लिए की जरूरत से बचा जाता है, लेकिन नकारात्मक पक्ष यह है कि हर नए प्लेटफार्म पोर्ट संशोधित करने के लिए है कि है फ़ाइल। यदि आप केवल एक ही पोर्टिंग कर रहे हैं जो निश्चित रूप से कोई समस्या नहीं है। अन्यथा कि एक फ़ाइल तीसरे पक्ष द्वारा फोर्क किया गया है। फिर हो सकता है कि वे आपकी लाइब्रेरी में platforms/ पर एक नई फ़ाइल जोड़ें, या हो सकता है कि वे अपनी फाइल कहीं और डाल दें। तो तीसरे पक्ष के साथ, यह केवल है कोई समस्या नहीं है। यदि वे और आप दोनों चाहते हैं तो वे अपने परिवर्तन (संभवतः उनके प्लेटफ़ॉर्म के शीर्षलेख सहित) को अपस्ट्रीम में योगदान दे सकते हैं।

1

सं।
आम तौर पर आप अपने कंपाइलर (आमतौर पर, यह -आई ध्वज) में कमांड ध्वज का उपयोग करके आपकी lib की निर्देशिका में पथ को परिभाषित करते हैं।

-I/usr/local/include/mylibheader/mycurrentplatform 

जहां mycurrentplatform निर्देशिका:

कहो, अगर आप जीसीसी संकलक का उपयोग कर रहे हैं, और अपनी लाइब्रेरी के हेडर फाइल

/usr/local/include/mylibheaders 

में हैं तो आप संकलक निम्नलिखित विकल्प के साथ कॉल करना होगा प्रत्येक परियोजना के लिए अलग है और शामिल परियोजना विशेष libraryConfig.h

इस प्रकार, आप हर परियोजना में #include<libraryConfig.h> उपयोग कर सकते हैं।

1

यह सी प्रश्न से अधिक विन्यास प्रबंधन प्रश्न है। मेरे अनुभव में, एक अच्छा संस्करण नियंत्रण कार्यक्रम का उपयोग करना सबसे उपयोगी है। एक ऐसा खोजें जो आपको कई अलग-अलग स्थानों से स्रोत कोड खींचकर "प्रोजेक्ट" को परिभाषित करने की अनुमति देता है। यह समझें कि आपके प्रोजेक्ट कंट्रोल प्रोग्राम की "प्रोजेक्ट" की परिभाषा परियोजना के निर्माण में एक आवश्यक तत्व बन जाएगी।

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

आपकी लाइब्रेरी मॉड्यूल भी एक फ़ाइल के साथ समाप्त हो सकता है जो प्रत्येक विशिष्ट प्रोजेक्ट के लिए लाइब्रेरी विकल्पों को परिभाषित करता है। एक अभ्यास जिसे मैंने अपनाया है, इन इंटरफ़ेस फ़ाइलों को नामित कर रहा है _PAL.h जहां _PAL एक प्रोजेक्ट एब्स्ट्रक्शन लेयर फ़ाइल इंगित करता है।

संबंधित मुद्दे