PIC में मॉलोक का उपयोग


10

मैं PIC में कैसे उपयोग malloc()और free()कार्य कर सकता हूं ? मैंने stdlib.hहेडर चेक किया है और उनमें से कोई भी उल्लेख नहीं है। मैं MCC18 का उपयोग कर रहा हूं।

क्या किसी को उनका उपयोग करना था?

मुझे उनकी आवश्यकता है क्योंकि मैं विंडोज़ एक्सपी से पीआईसी तक एक पुस्तकालय पोर्ट कर रहा हूं। पोर्टिंग गाइड से कहता है

ऑपरेटिंग सिस्टम के विशिष्ट कार्यों को मेरे PIC लोगों के अनुकूल बनाएं

लेकिन मैं नहीं जानता कि कैसे "अनुवाद" malloc()और free()कार्य करता है।


4
यदि संभव हो तो स्थैतिक आवंटन का उपयोग करने का प्रयास करें।
निक टी

1
क्यों? वास्तव में समस्या यह है कि मैं एक बहुत बड़ी लाइब्रेरी की निचली परत (मंच विशिष्ट एक) लिख रहा हूं और बहुत सारे कार्यों का मुझे कोई पता नहीं है कि वे इसके लिए क्या उपयोग कर रहे हैं .. और मुझे नहीं पता कि कैसे बदलना है डायनेमिक टू स्टैटिक ..
stef

11
ऐसा लगता है कि <4KB RAM वाला PIC माइक्रोकंट्रोलर आपके आवेदन के लिए गलत हो सकता है। एक पीसी पर एक पोर्ट शुरू करने से पहले अपने पीसी लाइब्रेरी की मेमोरी उपयोग को मापें। आप एआरएम कॉर्टेक्स-एम 3 जैसे कुछ बीफियर के साथ बेहतर हो सकते हैं। अंगूठे का नियम: यदि आप जिस कोडबेस को पोर्ट कर रहे हैं, वह समझने के लिए बहुत बड़ा है तो यह PIC में फिट नहीं होगा।
टॉबी जाफ़े

विंडोज ड्राइवर (और सामान्य रूप से अनुप्रयोग) अनिवार्य रूप से एक 'असीमित रैम' प्रतिमान के साथ लिखे जाते हैं, क्योंकि अगर भौतिक रैम समाप्त हो जाती है, तो वर्चुअल मेमोरी को स्वैप किया जा सकता है। पुस्तकालय क्या कर रहा है, इसके आधार पर, यह 4k से अधिक अच्छी तरह से उपभोग कर सकता है। आपके PIC18F87J11 में उपलब्ध है। मुझे संदेह है कि आप यह नहीं समझ पाएंगे कि ड्राइवर कितनी मेमोरी का उपयोग करने वाला है।
एडम लॉरेंस

एक अन्य संभावित मुद्दा: एक Win32 int 32 बिट्स है, जबकि MCC18 संकलक के साथ, यह केवल 16 बिट्स है। यदि आप सावधान नहीं हैं तो आपको अजीब अतिप्रवाह समस्याएं मिल सकती हैं।
एडम लॉरेंस

जवाबों:


8

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

char * next_alloc;
शून्य * मालॉक (अंतर आकार)
{
    char * this_alloc;
    this_alloc = next_alloc;
    अगर (END_OF_ALLOC_SPACE - यह_लोक) <आकार)
      वापसी -1;
    next_alloc + = आकार;
    इस_लोक लौटें;
}
शून्य मुक्त (शून्य * ptr)
{
    अगर (पीटीआर)
        next_alloc = (char *) ptr;
}

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

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


जा complety posibilities के बारे में सूचित करने के लिए, इस सवाल का जवाब में पढ़ electronics.stackexchange.com/questions/7850/...
gavioto20

14

malloc()माइक्रोकंट्रोलर्स में आमतौर पर एक "बुरी चीज" मानी जाती है। लेकिन, अगर आपको इसकी पूरी जरूरत है तो आप थर्ड पार्टी वर्जन ढूंढना चाहेंगे।

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

मैंने पीसी पुस्तकालयों को माइक्रोकंट्रोलर में पोर्ट करने से पहले इस दृष्टिकोण का सफलतापूर्वक उपयोग किया है।

नीचे, आप आवंटनकर्ता के साथ सेटअप करेंगे my_malloc_init()और मेमोरी को आवंटित करेंगे my_malloc()my_free()वहाँ निर्भरता को संतुष्ट करने के लिए है, लेकिन वास्तव में कुछ भी नहीं होगा। अंततः आप निश्चित रूप से अंतरिक्ष से बाहर भाग जाएंगे।

इस काम को करने के लिए, आपको अपने कोड की सबसे खराब स्थिति की आवश्यकता को मापने की आवश्यकता होगी (यदि संभव हो तो पीसी पर ऐसा करें) तो HEAP_SIZEतदनुसार सेट करें । डायनामिक मेमोरी की आवश्यकता के लिए अपने पुस्तकालय के भाग में प्रवेश करने से पहले, कॉल करें my_malloc_init()। पुन: उपयोग करने से पहले, सुनिश्चित करें कि कुछ भी नहीं अभी भी अंक heap

uint8_t heap[HEAP_SIZE];
uint8_t *heap_ptr;

void my_malloc_init(void)
{
    heap_ptr = heap;
}

void *my_malloc(size_t len)
{
    uint8_t *p = heap_ptr;
    heap_ptr += len;
    if (heap_ptr >= heap + HEAP_SIZE)
        return NULL;
    else
        return p;
}

void my_free(void)
{
    // do nothing
}

(ध्यान दें: वास्तविक दुनिया में, आपको सूचक संरेखण पर विचार करने की आवश्यकता हो सकती है, अर्थात heap_ptr2 या 4 बाइट्स तक गोलाई )

एक और विकल्प malloc()एक फ्रीलास्ट की तरह, आमतौर पर प्रदान की तुलना में एक सरल आवंटन संरचना का उपयोग करना है , हालांकि यह आपको चर आकार के ब्लॉक आवंटित करने की अनुमति नहीं दे सकता है।


3
मुझे आश्चर्य होता है कि जब मालॉक आईएस एम्बेडेड में एक अच्छी बात माना जाता है।
केलेंज्ब

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

1
@Kellenjb अच्छी तरह से, यह एक नया सवाल है :-)
टोबी जाफ़ी

1
मैं यह सुझाव दूंगा कि my_free ने heap_ptr को पारित मूल्य पर सेट करना चाहिए, संकेतित वस्तु को प्रभावी ढंग से मुक्त करने और इसके साथ आवंटित सब कुछ। जाहिर है कि किसी को ऐसे अनुक्रम में चीजों को आवंटित करना चाहिए जो इस तरह के उपयोग की अनुमति देता है, लेकिन ऐसे पैटर्न असामान्य नहीं हैं। एक अन्य उपयोगी भिन्नता के लिए दो जोड़े हैं आवंटित / मुक्त कार्य, जिनमें से एक शीर्ष-नीचे आवंटित करता है और दूसरा नीचे-ऊपर आवंटित करता है।
सुपरकैट

13

यह शायद ही आपके प्रश्न का उत्तर है, लेकिन डायनेमिक मेमोरी आवंटन आमतौर पर छोटे रैम वातावरण पर और ऑपरेटिंग सिस्टम की अनुपस्थिति में (जैसे कि माइक्रोकंट्रोलर दुनिया में) अनुपस्थित होता है ... आपके द्वारा एम्बेडेड वातावरण में उपलब्ध ढेर का स्थान आमतौर पर होता है सैकड़ों बाइट्स में मापा ...

मॉलॉक और फ्री को लागू करना अनिवार्य रूप से "फ्री सेगमेंट" संरचनाओं की एक लिंक की गई सूची का रखरखाव है, और जैसा कि आप कल्पना कर सकते हैं, मुक्त खंडों से जुड़ी मेटाडेटा आमतौर पर उपलब्ध स्मृति की तुलना में विवादास्पद नहीं है ... जो कि "हेडहेड" है। "एक गतिशील मेमोरी पूल के प्रबंधन के लिए उपलब्ध संसाधनों की एक महत्वपूर्ण राशि की खपत होती है।


ऐसे कार्यान्वयन हैं जहां मेटाडेटा ओवरहेड बहुत छोटा है। एक आवंटित ब्लॉक के लिए, आपको केवल इसके आकार की आवश्यकता है। अप्रयुक्त ब्लॉक के लिए, लिंक्ड लिस्ट पॉइंटर (ओं) को आमतौर पर मुफ्त में फिट किया जा सकता है, यहां तक ​​कि काफी उचित न्यूनतम ब्लॉक आकारों के साथ भी।
मोनिका

माइक्रोकंट्रोलर्स का उपयोग करने वाले छोटे, लंबे समय तक चलने वाले सिस्टम की समस्या आमतौर पर मेटाडेटा के बारे में नहीं है, लेकिन स्मृति विखंडन के बारे में है। क्या बुरा है, आपके कोड में छोटे परिवर्तन स्मृति विखंडन का परिचय दे सकते हैं जहां पहले कोई नहीं था, ताकि आप एक निर्दोष दिखने वाला बदलाव कर सकें जो अचानक आपके प्रोग्राम को "बहुत जल्द" काम करना बंद कर देता है।
मोनिका

11

मुझे नहीं पता कि C18 मानक पुस्तकालय समर्थन करता है mallocऔर free, लेकिन माइक्रोचिप ऐप नोट AN914 दिखाता है कि आप अपने स्वयं के कार्यान्वयन कैसे कर सकते हैं।

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

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


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

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

@ सुपरकार आप सही कह रहे हैं। मैं वास्तव में नाटकीय रूप से नाटकीय था। उन गारंटी के औपचारिक प्रमाण हैं।
मोनिका

2

याददाश्त के मामले में आपका PIC कितना बड़ा है?

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

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

और अगर आप PIC18 पर "ऑपरेटिंग सिस्टम" विकसित कर रहे हैं या यदि यह माइक्रोकंट्रोलर का समर्थन करता है तो संभवतः स्थैतिक आवंटन के लिए समर्थन है। उदाहरण के लिए, SQLite3 स्थैतिक आवंटन का समर्थन करता है - आप इसे एक बड़े बफर सरणी को आवंटित करते हैं और यह जहां संभव हो, वहां इसका उपयोग करता है, भले ही यह माइक्रोकंट्रोलर के लिए न हो। यदि ऐसा नहीं होता है, तो क्या आपको यकीन है कि यह एक छोटे PIC18 के लिए डिज़ाइन किया गया है?


मैं देख रहा हूं कि आपका क्या मतलब है .. मैं PIC18F87J11 का उपयोग कर रहा हूं, जिसमें 128K है RAM, क्या यह पर्याप्त हो सकता है?
स्टेफ़

स्टेफानो, उस चिप में 3,904 बाइट्स रैम है। इसमें 128K प्रोग्राम फ्लैश मेमोरी है।
W5VO

@ सत्तेफाओ सलाती - 3.8KB छोटी है।
थॉमस ओ

सही खेद .. क्या आपको लगता है कि यह पर्याप्त हो सकता है?
stef

@ सत्तेफानो सलाति, माफी मांगने की जरूरत नहीं मुझे लगता है कि आप इसे वास्तव में आगे बढ़ाएंगे। यह काम कर सकता है, लेकिन यह प्रदर्शन और आपकी मुफ्त मेमोरी से एक हिस्सा लेगा।
थॉमस ओ

2

आप विचार कर रहे हैं malloc()और free()अपने एम्बेडेड सॉफ्टवेयर के लिए मैं तुम्हें UC / ओएस द्वितीय और पर एक नज़र डालें सुझाव है OSMemGet()और OSMemPut()malloc()आपको स्मृति का एक मनमाना ब्लॉक आवंटित करते समय , आपको OSMem*()पूर्व-आवंटित पूल से एक निश्चित आकार का ब्लॉक दें। मुझे यह दृष्टिकोण लचीलेपन malloc()और स्थैतिक आवंटन की मजबूती के बीच एक अच्छा संतुलन लगता है ।


0

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

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


1
तुम गलत हो। एक MMU आपको बाह्य मेमोरी (PIC पर 4kB से अधिक होने की संभावना) के साथ इंटरफेस करने की अनुमति देता है। MMU के साथ और इसके बिना गतिशील और स्थिर आवंटन में बहुत कम अंतर है। एक बार जब आप वर्चुअल मेमोरी में जाने लगते हैं, तो अंतर होता है, लेकिन यह केवल मॉलोक से संबंधित है।
केविन वर्मेयर

1
प्रारंभिक मैकिंटोश प्रोग्रामर्स ने मल्कोक () और मुफ्त () या (उनके पास्कल समकक्ष) का उपयोग अक्सर किया, इस तथ्य के बावजूद कि प्रारंभिक मैकिन्टोश कंप्यूटरों में कोई एमएमयू नहीं था। मॉलोक () का उपयोग करते हुए "एमएमयू" की आवश्यकता के बारे में विचार मुझे गलत लगता है।
दाविदक्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.