2010-08-22 17 views
8

कितना है मैं Arduino programmable board का उपयोग करने की योजना बना रहा हूं। संकलित सी या सी ++ कोड स्टोर करने के लिए 16 और 128 केबी के बीच बहुत सीमित फ्लैश यादें हैं।32 केबी संकलित कोड

अनुमान लगाने के तरीके क्या हैं (मानक) कोड का प्रतिनिधित्व करेगा?

मुझे लगता है कि यह बहुत अस्पष्ट है, लेकिन मैं केवल परिमाण के क्रम की तलाश में हूं।

+19

64k किसी के लिए पर्याप्त होना चाहिए! –

+3

16kB "स्वचालित रूप से जुड़े हुए रनटाइम के लिए आवश्यक आकार के दसवें" से "लगभग एक हजार कथन" के लिए कहीं भी प्रतिनिधित्व करता है, बाद में संकलित बयान के लिए औसत 16 बाइट मानते हैं। –

+0

सुनिश्चित करें कि किसी भी बड़े बफर को स्थिर रूप से आवंटित न करें। – Anon

उत्तर

6

size कमांड का आउटपुट एक अच्छी शुरुआत स्थान है, लेकिन आपको आवश्यक सारी जानकारी नहीं देता है।

$ avr-size program.elf 
text   data bss  dec  hex filename 

आपकी छवि का आकार आम तौर पर टेक्स्ट और डेटा अनुभागों के योग से थोड़ा अधिक होता है। बीएसएस अनुभाग अनिवार्य रूप से संपीड़ित है क्योंकि यह सभी 0 है। ऐसे अन्य अनुभाग हो सकते हैं जो प्रासंगिक हैं जो आकार के अनुसार सूचीबद्ध नहीं हैं।

यदि आपकी बिल्ड सिस्टम एवीआर माइक्रोकंट्रोलर के लिए पहले उपयोग की गई है तो आप एक * .elf फ़ाइल के साथ-साथ * .bin फ़ाइल, और संभवत: एक * .hex फ़ाइल के साथ समाप्त हो जाएंगे। * .bin फ़ाइल वास्तविक छवि है जो प्रोसेसर के प्रोग्राम फ्लैश में संग्रहीत की जाएगी, ताकि आप यह निर्धारित करने के लिए अपने आकार की जांच कर सकें कि जब आप इसे संपादित करते हैं तो आपका प्रोग्राम कैसा बढ़ रहा है। * .bin फ़ाइल * .elf फ़ाइल से objdump कमांड और कुछ झंडे से निकाली जाती है जिसे मैं अभी याद नहीं कर सकता।

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

यह संभवतः सी ++ के उपयोग के साथ बढ़ाया जाएगा, जो सी की तुलना में कोड में बदलने वाली और चीजों को छिपाने के लिए होता है। चीजों के बीच चीफ सी ++ छुपाएं विनाशक कॉल हैं और पॉइंटर डीरफ्रेंसिंग के बहुत सारे हैं जिन्हें ऑब्जेक्ट्स में this पॉइंटर के साथ-साथ एक गुप्त सूचक के साथ भी करना है, कई ऑब्जेक्ट्स में उनके वर्चुअल फ़ंक्शन टेबल और क्लास स्थिर चर होते हैं।

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

AVR पर छोटे कार्यक्रमों के लिए कुछ युक्तियां:

  • उपयोग uint8_t और int8_t बजाय int जब भी आप कर सकते हैं। यदि आप अपना कोड पोर्टेबल होना चाहते हैं तो आप और int_fast8_t का भी उपयोग कर सकते हैं। इससे कई ऑपरेशन हो सकते हैं जो केवल आधा कोड लेते हैं, क्योंकि int दो बाइट्स हैं।

  • स्ट्रिंग और स्ट्रक्चर स्थिरांक और शाब्दिक और कैसे/जहां वे संग्रहीत हैं, जैसी चीजों से अवगत रहें।

  • यदि आप इससे डरते नहीं हैं, तो एवीआर असेंबली मैनुअल पढ़ें।आप निर्देशों के प्रकारों का एक विचार प्राप्त कर सकते हैं, और उस प्रकार से सी कोड जो आसानी से उन निर्देशों को मानचित्र करता है। उस तरह के सी कोड का प्रयोग करें।

+0

विशेष रूप से सभी व्यावहारिक सलाह के लिए, आपके उत्तर के लिए धन्यवाद। – Klaus

+0

@ क्लोस: यदि आपको लगता है कि उत्तर उपयोगी है, तो आपको इसे स्वीकृत उत्तर के रूप में चिह्नित करना चाहिए। :) –

+0

यह सब बहुत सैद्धांतिक है। मैंने जो खोजा और जो मैंने कल्पना की, माइक्रोस्कोस खोज के लिए बहुत से लोग नए उदाहरण हैं और पुस्तकालयों के आकार का न्याय करने का एक तरीका है, सी बनाम सी ++ में कुछ सरल एलईडी पीडब्लूएमिंग कितनी बड़ी है, क्या आम के आकार की एक सूची है Arduino पर इस्तेमाल पुस्तकालयों, इस तरह की चीजें। – Nobody

3

आप वास्तव में वहां नहीं कह सकते हैं। असम्पीडित कोड की लंबाई संकलित कोड की लंबाई के साथ बहुत कम है। उदाहरण के लिए:

#include <iostream> 
#include <vector> 
#include <string> 
#include <algorithm> 

int main() 
{ 
    std::vector<std::string> strings; 
    strings.push_back("Hello"); 
    strings.push_back("World"); 
    std::sort(strings.begin(), strings.end()); 
    std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, "")); 
} 

बनाम

#include <iostream> 
#include <vector> 
#include <string> 
#include <algorithm> 

int main() 
{ 
    std::vector<std::string> strings; 
    strings.push_back("Hello"); 
    strings.push_back("World"); 
    for (int idx = 0; idx < strings.size(); idx++) 
    std::cout << strings[idx]; 
} 

दोनों लाइनों की ठीक उसी संख्या में हैं, और एक ही उत्पादन का उत्पादन है, लेकिन पहले उदाहरण std :: एक तरह से एक इन्स्टेन्शियशन, जो शायद एक है शामिल यहां शेष कोड की तुलना में परिमाण के अधिक कोड का क्रम।

यदि आपको प्रोग्राम में उपयोग किए गए बाइट्स की संख्या गिनने की आवश्यकता है, तो असेंबलर का उपयोग करें।

+2

आखिरी वक्तव्य को छोड़कर सभी अच्छे! लोग सीमित अंतरिक्ष वातावरण में सी (और सी ++) में खुशी से कोड करते हैं। –

+1

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

+0

@ किथ: मैंने कभी नहीं कहा था कि आपको सीमित अंतरिक्ष वातावरण में असेंबलर का उपयोग करना था। मैंने कहा कि अगर आपको * बिल्कुल सुनिश्चित होना चाहिए * कोड आकार बाइनरी आकार को कैसे प्रभावित करेगा, यही वह है जो आपको करना होगा। उत्पन्न कोड की मात्रा इनपुट कोड आकार के लिए सीधे आनुपातिक नहीं है, यहां तक ​​कि सी और सी ++ में भी। @Pete: यह सच है - मैंने प्रत्येक फिक्स्ड फिक्स्ड-चौड़ाई निर्देश (पीआईसी और एमआईपीएस) के लिए कभी भी असेंबलर लिखा है। बेशक यदि आप एंबलर से भी x86 की तरह कुछ लिख रहे हैं, तो आपकी मदद नहीं कर सकता है, लेकिन कम से कम यह सी या सी ++ स्रोत कोड से प्रोग्राम आकार से अधिक सीधे संबंधित होगा। –

0

लिनक्स सिस्टम पर आप स्थैतिक संकलित उदाहरण प्रोग्राम के साथ कुछ प्रयोग कर सकते हैं। जैसे

$ size `which busybox ` 
text   data bss  dec  hex filename 
1830468 4448 25650 1860566 1c63d6 /bin/busybox 

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

ठीक है, busybox में बहुत सारी कार्यक्षमताएं हैं (जैसे सभी सामान्य शेल कमांड, एक खोल इत्यादि) ।

यदि आप gcc -static के साथ अपने उदाहरण लिंक करते हैं, तो ध्यान रखें कि आपका उपयोग किया गया libc नाटकीय रूप से प्रोग्राम आकार को बढ़ा सकता है और एम्बेडेड libc का उपयोग करके अधिक स्थान कुशल हो सकता है।

यह जांचने के लिए कि आप diet-libc या uclibc देख सकते हैं और उसके खिलाफ लिंक कर सकते हैं। असल में, व्यस्त बॉक्स आमतौर पर uclibc के खिलाफ जुड़ा हुआ है।

ध्यान दें कि आपको इस तरह के आकार आपको परिमाण का क्रम देता है। उदाहरण के लिए, आपके वर्कस्टेशन शायद आर्डिनो बोर्ड की तुलना में एक और सीपीयू आर्किटेक्चर का उपयोग करता है और विभिन्न आकारों का मशीन कोड इसके आकार में (कमांड आकार, उपलब्ध निर्देश, ओपोड एन्कोडिंग और इतने एक के कारण) भिन्न हो सकता है।

परिमाण तर्क की किसी न किसी आदेश के साथ पर जाने के लिए, बिजीबॉक्स मोटे तौर पर 309 tools (एफ़टीपी डेमॉन और इस तरह के सामान सहित) है, यानी एक बिजीबॉक्स उपकरण की औसत कोड आकार मोटे तौर पर 5k है।

+0

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

+0

यहां फ़ाइल का आकार 183 केबी है? मैं 'आकार' कमांड से परिचित नहीं हूं (मुझ पर शर्मिंदा)। – Klaus

+0

यह प्रतिनिधि नहीं होगा, आप विशाल पुस्तकालयों और एल्फ प्रारूप के ऊपरी भाग में खींचेंगे, जो Arduino पर एक बाइनरी की तुलना में बहुत बड़ा होगा। – nos

1

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

इसके अलावा, अक्सर एम्बेडेड सिस्टम के लिए सी ++ कंपाइलर्स सी कंपाइलरों की तुलना में बहुत खराब होते हैं। यही है, वे सामान्य डेस्कटॉप ओएस के लिए सी ++ कंपाइलर्स के रूप में कहीं भी अच्छे नहीं हैं (लक्षित प्लेटफॉर्म के लिए कुशल मशीन कोड बनाने के मामले में)।

+0

प्रतिक्रिया के लिए धन्यवाद :) हम देखेंगे कि हम सी ++/ओओपी के साथ अधिक जगह/रैम खो देते हैं या नहीं। – Klaus

2

Arduino IDE डाउनलोड करें और अपने कुछ मौजूदा कोड को 'सत्यापित करें' या नमूना स्केच देखें। यह आपको बताएगा कि कोड कितने बाइट्स है, जो आपको एक विचार देगा कि आप किसी दिए गए डिवाइस में कितना फिट बैठ सकते हैं। यादृच्छिक रूप से दो उदाहरणों को चुनकर, web server उदाहरण 5816 बाइट्स है, और LCD hello world 2616 है। दोनों बाहरी पुस्तकालयों का उपयोग करते हैं।

+0

मैंने ऐसा किया, लेकिन डिफ़ॉल्ट उदाहरण सभी काफी छोटे हैं। मुझे http://www.fisherinnovation.com/?p=fi-apartmentbot पर एक बड़ा कोड मिला जिसने मुझे एक बेहतर विचारधारा दिया। संकलित, यह लगभग 6 केबी है। – Klaus

2

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

किसी न किसी संकेत के रूप में, मेरा पहला ऐप (पुश बटून द्वारा नियंत्रित एलईडी फ्लैशर) को 10 9 2 बाइट की आवश्यकता होती है। यह 32k में से लगभग 1K है। सी ++ कोड के लिए बहुत छोटा पदचिह्न!

मुझे सबसे ज्यादा चिंता है राम की सीमित मात्रा (1 Kb)। यदि सीपीयू स्टैक इसमें से कुछ लेता है, तो कोई डेटा संरचना बनाने के लिए बहुत कुछ नहीं बचा है।

मेरे पास केवल 48 घंटे के लिए मेरा आर्डिनो था, इसलिए इसका उपयोग करने के लिए अभी भी बहुत कुछ है ;-) लेकिन इसका उपयोग करने में बहुत मज़ा आता है :)।

+0

प्रतिक्रिया और सलाह के लिए धन्यवाद :) अपने Arduino के साथ मजा करो। – Klaus

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