2012-08-02 20 views
6

Atmel प्रोसेसर के लिए codevision संकलक में, वहाँ उदाहरणएक चर प्रारंभ करना और भंडारण पते को एक ही समय निर्दिष्ट करना: क्या यह संभव है?

int a @0x100; // will place the variable at the address 0x100 in RAM 
बेशक

के लिए, एक वैश्विक चर के भंडारण के पते निर्दिष्ट करने के लिए एक संभावना है, मानक सी के अनुसार, चर पर प्रारंभ किया जा सकता है घोषणा

int a=42; 

हालांकि, मुझे दोनों को करने की कोई संभावना नहीं मिली। int a @0x100 = 42 या int a = 42 @0x100; काम नहीं करते हैं, वे संकलक त्रुटियों का कारण बनते हैं।

आप कारण है कि यह यह करने के लिए बहुत महत्वपूर्ण है पूछ सकते हैं, क्योंकि एक बस

int a @0x100; 

int main() 
{ 
    a = 42; 
    //... 
} 

हो सकता था हालांकि, अगर मैं EEPROM में चर है, मैं उन्हें प्रारंभ करने की आवश्यकता है क्योंकि यह है इसमें मूल्यों के साथ स्वचालित रूप से eeprom फ़ाइल उत्पन्न करने का एकमात्र तरीका। मैं बाद में उन मानों को असाइन नहीं कर सकता, क्योंकि उस स्थिति में यह वास्तव में कार्यक्रम की प्रत्येक शुरुआत में मूल्यों को eeprom में लिख देगा।

+0

कौन सा विशेष एटम प्रोसेसर परिवार? क्या यह धागा http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=102678? –

+0

एटमेगा में मदद करता है, लेकिन eeprom हैंडलिंग एक ही है। धागा केवल विस्तार से वर्णन करता है कि मैं क्या करता हूं मेरे पिछले पैराग्राफ में लिखा है (यदि मैं घोषणा 'eeprom int a पर एक eeprom चर के लिए मान असाइन करता हूं = 42; 'इसका मतलब है कि यह मान जेनरेट की गई eeprom फ़ाइल में जोड़ा जाएगा जो केवल डिवाइस पर एक बार लिखा जाएगा। जब भी कार्यक्रम शुरू होता है, यह वास्तव में eeprom को लिखा नहीं जाएगा, एक बहुत अच्छी सुविधा)। अगर मैंने एक अलग कमांड में मान असाइन किया था, तो इसे eeprom को लिखने के निर्देश के लिए संकलित किया जाएगा। लिंक के लिए धन्यवाद, अगर मैं यहां कुछ भी उपयोगी नहीं हूं तो मैं वहां पूछने की कोशिश करूंगा। – vsz

+0

कृपया बताएं कि आप वास्तव में क्या करने की कोशिश कर रहे हैं, ऐसा लगता है कि आप कुछ ऐसा करने के लिए गलत पथ नीचे गए हैं।एटम के पास इनमें से किसी के साथ कुछ लेना देना नहीं है। क्या आप एक विशिष्ट पते पर eeprom स्पेस में मौजूद मान को नियंत्रित करना चाहते हैं? क्या आप ऐसे मूल्य को नियंत्रित करना चाहते हैं जो एक रजिस्टर/मेमोरी में है जो eeprom में नहीं है? यदि उत्तरार्द्ध आप पते को नियंत्रित करना चाहते हैं ताकि आपके कार्यक्रम को एक बार शुरू करने के लिए एक चर हो सकता है जो उस रजिस्टर/मेमोरी लोकेशन (जो eeprom में नहीं है) पर इंगित करता है? –

उत्तर

2

CodeVisionAVR मदद से बस एक नज़र,

"अगर एक वैश्विक चर, @ operator का उपयोग कर किसी विशिष्ट पते पर रखा गया है, घोषणा के दौरान प्रारंभ किया जाना चाहिए निम्न कार्यविधि इस्तेमाल किया जाना चाहिए:

/* the variable will be stored in EEPROM at address 0x10 */ 

eeprom int abc @0x10; 

/* and it will be initialized with the value 123 */ 

eeprom int abc=123; 
0

आप सूचक है कि एक पूर्ण पता दर्शाए उपयोग कर सकते हैं:

volatile int *pa = (int *) 0x100; 

तो फिर तुम तो जैसे उस पते पर मूल्य का उपयोग करने की dereferencing ऑपरेटर * उपयोग कर सकते हैं:

int value = *pa; 

या

*pa = 0x10; 

संपादित करें: किसी वैरिएबल को किसी विशिष्ट क्षेत्र को इंगित करने का कोई तरीका नहीं है और साथ ही उस क्षेत्र में एक मान असाइन करें। जब तक कि कंपाइलर में एक्सटेंशन नहीं होते हैं, जो इसे अनुमति देते हैं।

+0

यह 'int @ 0x100' करने का एक और तरीका है; (और यह खतरनाक है, क्योंकि संकलक उस पते पर कुछ और आवंटित कर सकता है)। यह ** ** उस पते पर मूल्य ** कैसे शुरू करेगा? इसके अलावा, जैसा कि सवाल में बताया गया है, यह eeprom चर के मामले में सबसे महत्वपूर्ण है। एम्बेडेड सिस्टम के लिए – vsz

+1

@vsz कंपाइलर्स स्मृति और स्मृति स्थानों की बात करते समय _very_ सख्त हैं। एम्बेडेड सिस्टम में ढेर, ढेर और अन्य डेटा सेगमेंट के लिए विशिष्ट क्षेत्र होते हैं। केवल अगर सिस्टम मिस-कॉन्फ़िगर किया गया है तो संकलक मेमोरी एड्रेस रेंज का उपयोग करेगा जो इसे नहीं माना जाता है। –

+0

और 'int @ @xx100; जहां तक ​​मुझे पता है एएनएसआई सी द्वारा समर्थित नहीं है। बेशक एवीआर कंपाइलर्स (कोडविजन और एवीआर-जीसीसी और संभवतः अन्य दोनों) के पास इस उद्देश्य के लिए एक्सटेंशन हैं। – vsz

2

जबकि मुझे किसी विशिष्ट पते पर सीधे ईईपीरोम वैरिएबल असाइन करने का कोई तरीका नहीं है और इसे प्रारंभ करने के लिए, मुझे यह लिंक बहुत उपयोगी पाया: EEPROM data at fixed address

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

उदाहरण:

typedef eeprom struct EEvars 
{ 
    eeprom char foo1; // will be located at EEPROM address 0x0000 
    eeprom char foo2; // will be located at EEPROM address 0x0001 
    eeprom short foo3; // will be located at EEPROM address 0x0002 
    eeprom long foo4; // will be located at EEPROM address 0x0004 
    eeprom char[3] fooArr; // fooArr[0] @ 0x0008; fooArr[1] @ 0x0009; 
          // fooArr[2] @ 0x000A 
} EEVARS; 

फिर आप संरचना की घोषणा में चर को प्रारंभ कर सकते हैं। जब आप संकलित करते हैं, तो यह ज्ञात ईईपीरोम पते पर प्रारंभिक मानों के साथ .eep फ़ाइल बना देगा।

eeprom EEVARS eepromInit = {0xAA, 0xBB, 0xCCDD, 0xEEEEFFFF, {0xF0, 0xF1, 0xF2}}; 

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

2

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

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

__attribute__((__section__("<section_name>"))) 

ATmega श्रृंखला आप के रूप में एक ही लाइन पर शामिल करके EEPROM में किसी भी स्मृति का पता लगाने के लिए: उदाहरण के लिए एक जीएनयू toolchain पर, इन वर्गों चर के साथ खंड विशेषता का उपयोग करके चर घोषणाओं के भाग के रूप में उपयोग किया जाता है अपने चर घोषणा (या तो पहले या बाद में, जब तक यह एक काम में पहले '=' आता है के रूप में) पाठ: आप गारंटी नहीं है कि EEPROM में विशिष्ट स्मृति पते पर सेट है चाहते हैं, तो

__attribute__((__section__(".eeprom"))) 

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

उदाहरण के लिए, मैंने स्मृति सेटिंग्स के ईईपीरोम भाग में ".tune_data" खंड घोषित करके डेटा के ब्लॉक के साथ सटीक रूप से वर्णन किया है (ऑफ़र को संबोधित करने के लिए प्रदान किए गए दस्तावेज के बाद), फिर एक चर घोषित करना

const __attribute__((__section__(".tune_data))) Tune_Data_s as_tune_data = { <all_my_data> }; 

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