कार्यक्रम AVR EEPROM सी स्रोत से सीधे


11

जब आप एक AVR C स्रोत में निम्नलिखित कोड शामिल करते हैं, तो आप अतिरिक्त कमांड या .hex फ़ाइल की आवश्यकता के बिना, प्रत्यक्ष रूप से फ़्यूज़ को सीधे प्रोग्राम कर सकते हैं।

#include <avr/io.h>

FUSES = {
        .low =          LFUSE_DEFAULT ,
        .high =         HFUSE_DEFAULT ,
        .extended =     EFUSE_DEFAULT ,
};

EEPROM में प्रोग्राम मानों के लिए एक समान चाल है?

मैंने जाँच की है /usr/lib/avr/include/avr/fuse.hकि मुझे मैक्रो के बारे में कुछ टिप्पणियां कहाँ मिल सकती हैं, लेकिन मैं एक समान टिप्पणी नहीं ढूँढ सकता /usr/lib/avr/include/avr/eeprom.hऔर प्रीप्रोसेसर सामान की व्याख्या करना मेरे लीग से थोड़ा बाहर है।

यह वास्तव में आसान होगा यदि मैं C स्रोत कोड में डिफ़ॉल्ट EEPROM मान शामिल कर सकता हूं। किसी को पता है कि कैसे पूरा करने के लिए?

edit1:

यह FUSES ट्रिक केवल ISP-time पर निष्पादित की जाती है, RUN-time पर नहीं। इसलिए नियंत्रक में परिणामस्वरूप असेंबली कोड में कोई फ़्यूज़ प्रोग्राम नहीं किया जा रहा है। इसके बजाय प्रोग्रामर स्वचालित रूप से एक अतिरिक्त FUSES प्रोग्रामिंग चक्र के माध्यम से चक्र करता है।

EDIT2:

मैं लिनक्स पर avr-gcc और avrdude toolchain का उपयोग करता हूं।


क्या यह केवल प्रोग्रामिंग आईएसपी है? अधिकांश बूटलोडर्स आपको फ़्यूज़ प्रोग्राम करने की अनुमति नहीं देते हैं, है ना?
स्वर्गदूत

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

@angelatlarge केवल ISP प्रोग्रामिंग। इस सेटअप में कोई बूटलोडर नहीं है।
जिप्पी

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

जवाबों:


7

Avr-gcc के साथ EEMEMमैक्रो का उपयोग चर की परिभाषा पर किया जा सकता है, libcडॉक्स और यहां एक उदाहरण देखें :

#include <avr/eeprom.h>
char myEepromString[] EEMEM = "Hello World!";

वर्णों के सरणी को ".Prom" नामक खंड में रहने की घोषणा करता है, जो संकलन के बाद प्रोग्रामर को बताता है कि यह डेटा EEPROM को प्रोग्राम किया जाना है। आपके प्रोग्रामर सॉफ्टवेयर के आधार पर, आपको प्रोग्रामर को बिल्ड प्रक्रिया के दौरान बनाए गए ".P" -इल का नाम स्पष्ट रूप से देने की आवश्यकता हो सकती है, या यह इसे अपने आप मिल सकता है।


मैंने 'माना' से थोड़ा अलग फ़ाइल नाम का उपयोग किया है, लेकिन ये वो कमांड हैं जिन्हें मैंने EEPROM को कमांड लाइन (और मेकफाइल) से प्रोग्राम करने के लिए शामिल किया है:
jippie

1
प्रोग्रामर द्वारा उपयोग किया जाने वाला इंटेल हेक्स डेटा युक्त एक फ़ाइल बनाएं:avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ihex $(src).elf $(src).eeprom.hex
जिप्पी

1
वास्तविक प्रोग्रामिंग द्वारा किया जाता है:avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
जिप्पी

7

हाँ, आप मैन्युअल रूप से स्रोत कोड में EEPROM को डिफ़ॉल्ट डेटा लिख ​​सकते हैं। पहले, EEPROM पर AVR: डीन के AVR EEPROM ट्यूटोरियल के साथ इस भयानक गाइड की जाँच करें इसके अलावा, मुझे यह जोड़ना चाहिए कि यह एक बेहतर विचार है। एक मेकाइल का उपयोग करके EEPROM डेटा युक्त एक .P फ़ाइल बनाना है जिसे स्रोत कोड के साथ डिवाइस पर प्रोग्राम किया जाएगा। हालांकि, यदि आप विभिन्न मेकफाइल और लिंकर संचालन से अपरिचित हैं, तो यह अभी भी आपके स्रोत कोड फ़ाइल के भीतर से किया जा सकता है - यह सिर्फ सर्किट के संचालित होने के साथ ही होगा, प्रारंभिक प्रोग्राम ऑपरेशन को रोकते हुए।

कार्यक्रम की शुरुआत में (मुख्य लूप के किसी भी प्रकार से पहले) आप कुछ ऐसा कर सकते हैं:

#include <avr/eeprom.h>

#define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_2 52  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_3 68  // This could be anything from 0 to the highest EEPROM address

uint8_t dataByte1 = 0x7F;  // Data for address 1
uint8_t dataByte2 = 0x33;  // Data for address 2
uint8_t dataByte3 = 0xCE;  // Data for address 3

eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);

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

if(eeprom_read_byte((uint8_t*)SOME_LOCATION) != DESIRED_VALUE){
  eeprom_write_byte((uint8_t*)SOME_LOCATION, DESIRED_VALUE);
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
  eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
  eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);
}

यदि आप बड़ी मात्रा में डेटा अपडेट करना चाह रहे हैं, तो अन्य कार्यों जैसे कि उपयोग करने का प्रयास करें eeprom_update_block(...)। और उस ट्यूटोरियल को जरूर पढ़ें; यह अच्छी तरह से लिखा गया है।

आप सभी EEPROM अपडेट स्टेटमेंट को एक एकल प्रीप्रोसेसर कंडीशनल स्टेटमेंट में रख सकते हैं। यह करना बहुत आसान है:

#if defined _UPDATE_EEPROM_
  #define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
  uint8_t dataByte = 0x7F;  // Data for address 1
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
#endif // _UPDATE_EEPROM_

जब तक आप निम्न कार्य नहीं करेंगे तब तक यह बिट कोड भी संकलित नहीं किया जाएगा:

#define _UPDATE_EEPROM_

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


ऐसा लगता है कि सही उत्तर लिंक किए गए पीडीएफ के अंतिम पैराग्राफ में है। Ch. 7 Setting Initial Values
जिप्पी

हाँ आप सही हैं। मैंने उल्लेख किया कि मेरे पहले पैराग्राफ में, लेकिन मामले में आप .Pf फाइल और मेकफाइल में लिंकर से परिचित नहीं थे!
कर्ट ई। क्लोथियर

1
स्थिर EEPROM पतों का उपयोग करना बुरा व्यवहार है। इसके बजाय EEMEM विशेषता का उपयोग करना बेहतर है और संकलक को पता वितरण का प्रबंधन करने दें। इसके अलावा, मैं प्रत्येक अनुभाग में सीआरसी जांच को लागू / निष्पादित करने की सिफारिश करूंगा। यदि CRC विफल हो जाता है, तो संबंधित अनुभाग में असमान या दूषित डेटा होता है। इस तरह, आप डेटा भ्रष्टाचार के मामले में पिछले कॉन्फ़िगरेशन के लिए एक बैकबैक तंत्र भी लागू कर सकते हैं।
Rev1.0

"स्थिर EEPROM पतों का उपयोग करना बुरा व्यवहार है।" क्यों?

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