2010-11-04 4 views
6

बजट पीआईसी का सीमित ढेर आकार एक समस्या क्षेत्र है और मैंने इस वास्तविकता को समायोजित करने के लिए अपना कोड समायोजित किया है। मैं वर्तमान में मॉड्यूल में बारीकी से संबंधित कार्यों को समूहीकृत करने और मॉड्यूल में वैश्विक चर के सभी चर घोषित करने के लिए एक मोटा प्रतिमान अपनाता हूं (ऑटो पर्स में संग्रहीत चर की मात्रा को कम करने के लिए, और उत्परिवर्तन के मुद्दे केवल आईएसआर में प्रासंगिक हैं, जिनके लिए मैं खाता हूं ।) मैं ऐसा नहीं करता क्योंकि यह अच्छी प्रथा है, लेकिन वास्तविकता यह है कि आपके पास एक संपूर्ण परियोजना में मौजूद सभी स्थानीय फ़ंक्शन वर्रों को आवंटित करने के लिए एक सीमित मात्रा में स्थान है। 8/16 बिट चिप्स की एम्बेडेड दुनिया में, क्या यह एक उचित विधि है, बशर्ते मुझे आवश्यक सावधानी बरतें? मैं इथरनेट के लिए 256 बाइट्स रैम आवंटित करने जैसी चीजें भी करता हूं (मुझे पता है कि यह मानक एमटीयू के रूप में 1500 होना चाहिए, लेकिन हमारे पास कस्टम स्थिति और बहुत सीमित रैम है) बफर और पॉइंटर्स के माध्यम से उस मेमोरी को एक्सेस करना है ताकि मैं अर्थशास्त्र से बच सकूं मेमोरी बैंकिंग का। क्या मैं इसे गलत कर रहा हूँ? मेरा ऐप काम करता है, लेकिन मैं सुधार के लिए सुझावों के लिए 100% खुला हूं। [सी]पीआईसी 18 स्टैक/मेमोरी प्रबंधन के लिए सर्वोत्तम अभ्यास?

उत्तर

3

मुझे पता है कि यह 4 साल पहले पूछा गया था लेकिन अभी भी इसका सही उत्तर नहीं दिया गया है। मेरा मानना ​​है कि ओपी क्या पूछ रहा है वह है HiTech PICC18 सी कंपाइलर वैध और/या सर्वोत्तम अभ्यास की सीमा के आसपास काम करने का उनका दृष्टिकोण है। जैसा कि बाद की टिप्पणी में उल्लेख किया गया है (सीमा बल्कि एक बुरी और अच्छी तरह से हाइटेक द्वारा विज्ञापित नहीं) "हाई-टेक कंपाइलर केवल ऑटो चर के 256 बाइट्स को अनुमति देता है"। असल में सीमा उस से भी बदतर है क्योंकि यह स्थानीय चर और पैरामीटर के लिए कुल 256 बाइट है। जब यह पार हो जाता है तो लिंकर चेतावनी भी बहुत गूढ़ है। बशर्ते कि कॉल कॉल पेड़ की विभिन्न शाखाओं पर हों तो संकलक अंतरिक्ष का पुन: उपयोग करने के लिए चर को ओवरलैप कर सकता है। इसका मतलब है कि आप प्रभावी ढंग से 256 बाइट से अधिक कर सकते हैं। लेकिन ध्यान दें कि हस्तक्षेप हैंडलर (या यदि आप प्राथमिकता योजना का उपयोग करते हैं तो हैंडलर) का अपना कॉल पेड़ है जो 256 बाइट स्थानीय/पैरा ब्लॉक साझा करता है।

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

आरंभिकरण से सावधान रहें।

foo() 
{ 
int myvar = 5; 
} 

आप के चारों ओर मानकों आप जल्दी ही 256 बाइट सीमा में चलेंगे में कॉल पेड़ डेटा की बड़ी बहुत गुजर जाते हैं करने के लिए

foo() 
{ 
static int myvar; 
myvar = 5; 
} 

पैरामीटर को बदलना होगा। यहां आपका सबसे अच्छा विकल्प "विकल्प" के वैश्विक रूप से आवंटित संरचनाओं के लिए सूचक को पास करना हो सकता है। वैकल्पिक रूप से आपके पास शीर्ष कॉलर द्वारा सेट किए गए वैश्विक सेटिंग्स चर हो सकते हैं और पेड़ के नीचे कॉलिज़ द्वारा पढ़े जा सकते हैं। यह वास्तव में सॉफ्टवेयर के डिजाइन पर निर्भर करता है जो दृष्टिकोण बेहतर है।

मैंने ओपी के समान मुद्दों के साथ संघर्ष किया है और मुझे लगता है कि लंबे समय तक सबसे अच्छा विकल्प हाइटेक कंपाइलर का उपयोग करने से दूर जाना है।एक ब्लॉक में सभी स्थानीय/पैरा को आवंटित करने के लिए संकलक लेखकों ने ऑप्टिमाइज़ेशन निर्णय लिया है, जो कि बहुत ही छोटे आकार के पीआईसीएस के लिए वास्तव में उपयुक्त है। बड़े पीआईसीएस के लिए आप डिवाइस के राम आकार को हिट करने से पहले स्थानीय/param से बाहर चले जाएंगे। फिर आपको उलटा होने वाले कंपाइलर को फिट करने के लिए अपने कोड को हैक करना शुरू करना होगा।

संक्षेप में ... हाँ आपका दृष्टिकोण मान्य है। लेकिन सामान्य रूप से स्थानीय लोगों को स्थैतिक बनाने पर विचार करें, सामान्य रूप से, दायरे को कम करने से आपका कोड सुरक्षित हो जाता है।

+0

स्थानीय से फ़ंक्शन स्कोप स्थैतिक रूपांतरित करने के साथ देखने के लिए एक बिंदु प्रारंभिक जांच की जांच करने के लिए सावधान रहना चाहिए। – Felix

0

चूंकि आप लगभग स्मृति से बाहर हैं, आपको रैम के प्रत्येक बाइट को गिनना होगा। स्थानीय चर (ऑटो) का उपयोग स्मृति की पुन: उपयोग करने की अनुमति देता है जहां आपको इसकी आवश्यकता होती है (फ़ंक्शन में स्थानीय)। जब आप वैरिएबल को वैश्विक स्थिर पता स्थान पर ले जाते हैं, तो आप प्रत्येक चर को एक अद्वितीय स्थान देते हैं। यह पता स्थान की बर्बादी है।

माइक्रोचिप कंपाइलर अनुमति देता है कि विभिन्न चर समान पते साझा करते हैं। मेरे पास दस्तावेज़ नहीं हैं, लेकिन यह प्रज्ञा द्वारा किया जा सकता है।

लेकिन आपको जो चाहिए वह रैम आवश्यकताओं का विश्लेषण है। जब आप देखते हैं, कि स्टैक सभी चर नहीं रख सकता है लेकिन ऑटो चर वैश्विक मेमोरी उपयोग को कम कर देगा, तो आपको स्टार्टअप कोड और लिंकर स्क्रिप्ट का उपयोग करके स्टैक आकार को बढ़ाने पर विचार करना चाहिए।

+0

हम हाई-टेक PICC18 प्रो कंपाइलर का उपयोग कर रहे हैं। इसके बीच माइक्रोचिप सी 18 के बीच अंतर बहुत अधिक हैं, लेकिन महत्वपूर्ण बात यह है कि हाई-टेक कंपाइलर केवल ऑटो चर के 256 बाइट्स की अनुमति देता है और इस कंपाइलर में कोई लिंकर स्क्रिप्ट नहीं है जिसे मैं संपादित कर सकता हूं (मेरे ज्ञान के लिए।) – Nate

+0

ओपी सामान्य रूप से रैम नहीं है, स्टैक/स्थानीय स्थान के बारे में बात कर रहा है। – Felix

0

सर्वोत्तम अभ्यास एक हार्डवेयर चुनने के लिए है जो आवश्यकताओं को फिट करता है।

केवल कुछ डॉलर के आसपास माइक्रोक्रोनरोलर हैं, लेकिन हंडर्ड या हजारों डॉलर की विकास लागतों को बचाएं। यदि यह एक शौक विकास है तो आपका प्रयास गिन सकता है। लेकिन वास्तविक दुनिया में आप अक्सर हार्डवेयर ढूंढ सकते हैं जो केवल हार्डवेयर लागतों के दृश्य के साथ डिज़ाइन किया गया है।

विशेष रूप से पीआईसी 18 कॉम्पैक्ट कोड के लिए सबसे अच्छा उदाहरण नहीं है, फ्लैश मेमोरी के साथ समस्या भी हो सकती है।

+0

यह पहली बार नहीं है जब मैंने इस बिंदु को सुना है। यह अच्छी तरह से लिया जाता है, मैं भविष्य की परियोजनाओं और संभावित रूप से आईएआर देव उपकरणों के लिए एवीआर यूसी का उपयोग करने का मामला बनाउंगा। मैं वित्त पोषण को नियंत्रित नहीं करता हूं और इस परियोजना में वर्तमान चिप्स के लिए पहले से ही फर्मवेयर की एक बड़ी मात्रा है, यूसी बदलना इस बिंदु पर एक विकल्प नहीं है। – Nate

+0

गैर-तकनीकी प्रबंधकों द्वारा संचालित @harper वाणिज्यिक उद्यम बिल्कुल डेवलपर्स को सबसे छोटे चिप का उपयोग करने में धक्का दे रहे हैं! – Radu

+0

@Nate रैम सीमाओं के साथ एक एवीआर पीआईसी के समान समस्याओं से ग्रस्त है। जबकि व्यक्तिगत यूपी वरीयताएं ठीक हैं (और एवीआर ठीक चिप्स हैं) यह अंततः आपके प्रश्न का उत्तर नहीं है। – boz

1

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

सामान्य सलाह जब गति (गति या स्थान) अनुकूलन है: यह साबित करने के लिए माप करें कि आपके अनुकूलन का सकारात्मक प्रभाव है।

0

थोड़ा देर हो चुकी है, लेकिन आपको सी 18 कंपाइलर उपयोगकर्ता मार्गदर्शिका (यदि आप इस कंपाइलर का उपयोग कर रहे थे) पर नज़र डालें।

आप स्थानीय चर आवंटित (ऑटो कीवर्ड को ओवरराइड करने) द्वारा नाटकीय रूप से स्टैक को कम कर सकते हैं। इससे भी बेहतर, आप ओवरले स्टोरेज पहचानकर्ता का उपयोग कर सकते हैं, जो रैम को कम करने, एक ही पते पर अलग-अलग गैर ओवरलैपिंग लाइफटाइम चर को रखने की अनुमति देता है। (सी 18 कंपाइलर को गैर-विस्तारित मोड में संचालित होना चाहिए)।

0

यह माइग ध्वनि स्पष्ट है, लेकिन 8 बिट प्रीवार्स पर 16 बिट्स चर का उपयोग न करने का प्रयास करें।16 बिट्स वैरिएबल ठीक हैं और बड़े आर्किटेक्चर पर जरूरी है, लेकिन सीमित (8 बिट) आर्किटेक्चर में 16 बिट अंकगणित किसी भी समय राम और रॉम यादों को कम करने का एक त्वरित तरीका नहीं है।

यदि आप 16 बिट्स वैरिएबल बढ़ाने की कोशिश करते हैं, तो कंपाइलर में 16 बिट्स वृद्धि लाइब्रेरी शामिल होगी, जो ज्यादातर मामलों में बहुत अधिक जगह लेती है।

इसके अलावा, विभाजित या गुणा करने की कोशिश न करें, क्योंकि कुछ नियंत्रकों के लिए वे सॉफ्टवेयर लागू होते हैं।

व्यक्तिगत रूप से, मैं char के लिए अलवाइस जाता हूं और जब विभाजन विभाजन की आवश्यकता होती है, तो 2 एन बार विभाजित करने के लिए रगथ 'एन' बार घुमाएं।

उम्मीद है कि इससे मदद मिलती है!

+1

नीचे वोटिंग के रूप में यह सामान्य सलाह प्रदान करता है और ओपी के मुख्य प्रश्न को संबोधित नहीं करता है। – Felix

2

जबकि सी 18 कंपाइलर डेटा स्टैक को प्रबंधित करने के लिए कुछ एफएसआर (पॉइंटर्स) का उपयोग करता है, ऐसा लगता है कि माइक्रोचिप से नए एक्ससी 8 कंपाइलर एक संकलित स्टैक का उपयोग करता है, इसलिए आपको पता होना चाहिए कि संकलन में ढेर द्वारा कितनी जगह ली जाती है पहर। आपको यह भी पता चलेगा कि प्रत्येक स्टैक वैरिएबल कहाँ संग्रहीत किया जाता है। मैंने XC8 user's guide में इसके बारे में सब कुछ पढ़ा और यह बहुत अच्छा लगता है। यह सुविधा इस सवाल को हल करनी चाहिए, मान लीजिए कि आप एक्ससी 8 का उपयोग कर रहे हैं।