2013-02-17 15 views
5

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

  1. प्रारूपित उत्पादन (यानी printf की ओर से कुछ)
  2. लगातार प्रिंट (है कि हो से पहले पिछले प्रिंट समाप्त हो गया है)

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

+1

दिलचस्प आवश्यकता है, लेकिन मुझे नहीं लगता कि आप 'अस्थायी उचित प्रतिलिपि समारोह द्वारा परिपत्र बफर के लिए नकल के बाद बफर में प्रारूप' काफी की तुलना में बेहतर करने के लिए जा रहे हैं है। –

उत्तर

2

एक समाधान आपके sprintf को लागू करने के लिए हो सकता है जो रिंग बफर के साथ काम करने में सक्षम है। दुर्भाग्य से यह आपको अधिक बुनियादी समस्या के बारे में मदद नहीं करेगा: यदि आपका रिंगबफर भरा हुआ है और आप sprintf का आह्वान करते हैं तो आप क्या करेंगे?

अपनी स्मृति स्थिति इसे बर्दाश्त कर सकते हैं, मैं इस समस्या के लिए एक समाधान का सुझाव चाहते हैं:

विचार बफ़र्स की दोनों आपस में जुड़े सूचियों के आधार पर किया जाता है (मुक्त बफ़र्स के लिए एक सूची, संचारित कतार के रूप में एक सूची) । बफर समान आकार के होते हैं ताकि वे सबसे खराब केस लंबाई स्ट्रिंग स्टोर कर सकें। बफर एक साधारण ढेर बनाते हैं जहां आवंटन/डीलोकेशन केवल मुक्त या ट्रांसमिशन सूची से तत्व को निकालने/निकालने के लिए होता है।

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

मैं इस प्रकार यह चल रहा है कल्पना कर सकता:

  1. आप में डेटा प्रस्तुत करने के लिए नि: शुल्क सूची से एक बफर आवंटित।
  2. अपने कार्यों प्रस्तुत करना (suchas sprintf) का उपयोग बफर में डेटा प्रस्तुत करने के लिए
  3. आंकड़ा संचरण कतार में भेजे जाने के लिए संलग्न (और यदि आवश्यक हो एक संचरण गति प्रदान)

डीएमए के लिए आप के लिए स्थानांतरण ट्रांसफर एंड आईआरक्यू को संभालें। वहां आप बफर को "मुक्त सूची" में स्थानांतरित कर देते हैं और कतार में अगले बफर के लिए स्थानांतरण सेट करते हैं।

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

शायद यह विचार आपको अपनी आवश्यकताओं को हल करने के लिए एक प्रेरणा देता है।

1

एक तरीका जिस पर आप अनुमान लगा सकते हैं, अपने प्रिंटफ बफर को अपने रिंगबफर के आकार के 2x के रूप में आवंटित करना है, और फिर अपने अंगूठी बफर के रूप में पहली छमाही का उपयोग करना है। एक अतिप्रवाह का पता लगाएं, बाद के आधे हिस्से में ओवरफ्लो को सामने (अंगूठी भाग) में कॉपी करें।कुछ इस तरह:

void xprintf(const char *format, ...) 
{ 
    int written; 
    va_list args; 
    va_start(args, format); 
    written = vsnprintf(buffer, HALF_BUFFER_SIZE, format, args); 
    va_end(args); 
    if (buffer + written > bufferStart + HALF_BUFFER_SIZE) 
    { // time to wrap 
    int overflow = (buffer + written) - (bufferStart + HALF_BUFFER_SIZE); 
    memmove(bufferStart, bufferStart + HALF_BUFFER_SIZE, overflow; 
    buffer = bufferStart + overflow; 
    } 
} 
संबंधित मुद्दे