একটি মাইক্রোকন্ট্রোলারের EEPROM এ সমতলকরণ পরিধান করুন


15

উদাহরণস্বরূপ: এটিটিনি 2313 (যেমন বেশিরভাগ অ্যাটমেল এভিআর ডেটাশিটগুলি করেন) এর জন্য ডেটাশিটটি বলে:

128 বাইটস ইন-সিস্টেম প্রোগ্রামেবল EEPROM সহনশীলতা: 100,000 লিখুন / মুছুন চক্র

কল্পনা করুন যে কোনও প্রোগ্রামের কিছু কনফিগারেশন সঞ্চয় করতে কেবল দুটি বাইট প্রয়োজন, অন্যান্য 126 বাইট কার্যকরভাবে অপচয় হয়। আমার উদ্বেগটি হ'ল দুটি কনফিগারেশন বাইটের নিয়মিত আপডেটগুলি ডিভাইসের ইপ্রোম পরিধান করতে পারে এবং এটি অকেজো করে দেয়। পুরো ডিভাইসটি অবিশ্বাস্য হয়ে উঠবে, কারণ একটি নির্দিষ্ট মুহুর্তে আপনি কেবল EEPROM এর কোন বাইটগুলি বিশ্বাসযোগ্য নয় তা ট্র্যাক রাখতে পারবেন না।

যখন আপনি কার্যকরভাবে উপলব্ধ 128 টির মধ্যে কেবল এক বা দুটি বাইট ব্যবহার করেন তখন কোনও মাইক্রোকন্ট্রোলারের EEPROM এ সমতলকরণ করার কি স্মার্ট উপায় আছে?


1
যদি 100k রাইটিং চক্রটি বাধা হয়ে থাকে তবে এর পরিবর্তে অন্য কোনও প্রযুক্তি ব্যবহার করা কি বোধগম্য হবে? হয় এমন একটি প্রক্রিয়া যা অভ্যন্তরীণভাবে সমতলকরণকে অন্তর্ভুক্ত করে, বা প্রস্থের ক্রম বা আরও বেশি ধৈর্য সহকারে কিছু?
অনিন্দো ঘোষ

1
@ আনন্দোঘোষ আমার ধারণার প্রমাণের পরীক্ষার কারণে কেবলমাত্র ইপ্রোম পরিধান করার কারণে আমি আমার ক্ষুদ্রতর নিয়ন্ত্রণের ছোট স্টকটি নষ্ট করতে চাই না। নিয়ামকটি পুনরায় ব্যবহার করার সময় আমি কোন প্রকারের বাইটটি পূর্ববর্তী প্রকল্পে ব্যবহার করেছি তা নিয়ে আমি চিন্তা করতে চাই না। এবং আমি উপলব্ধ হার্ডওয়্যারটির সর্বোত্তম ব্যবহার করি তা জেনে ভাল লাগছে।
জিপ্পি


1
স্ট্যাকওভারফ্লোতে আমার উত্তরটি একবার দেখুন ।
জিমিবি

টিআই এর এমএসপি 430 ফ্রেম সিরিজটি একবার দেখুন ... 10 ^ 13 লিখেছেন !!!
জ্যামিতিকাল

উত্তর:


19

আমি সাধারণত যে কৌশলটি ব্যবহার করি তা হ'ল 4-বাইট রোলিং সিকোয়েন্স নম্বর সহ ডেটা উপসর্গ করা যেখানে বৃহত্তম সংখ্যাটি সর্বশেষতম / বর্তমান মান উপস্থাপন করে। 2 বাইট আসল ডেটা সংরক্ষণ করার ক্ষেত্রে যা মোট 6 বাইট দেয় এবং তারপরে আমি একটি বৃত্তাকার সারিতে বিন্যাস করি যাতে EEPROM এর 128 বাইটের জন্য এটি 21 এন্ট্রি ধারণ করে এবং 21 বার ধৈর্য বাড়ায়।

তারপরে বৃহত্তম সিকোয়েন্স নম্বরটি বুট করার সময় পরবর্তী সিকোয়েন্স নম্বর এবং সারির বর্তমান লেজ উভয় নির্ধারণ করতে ব্যবহার করা যেতে পারে। নিম্নলিখিত সি সিডো-কোডটি দেখায়, এটি ধরে নিয়েছে যে প্রাথমিক প্রোগ্রামিংয়ের পরে EEPROM অঞ্চলটি 0xFF এর মানগুলিতে মুছে ফেলা হয়েছে তাই আমি 0xFFFF এর ক্রম সংখ্যাকে উপেক্ষা করি:

struct
{
  uint32_t sequence_no;
  uint16_t my_data;
} QUEUE_ENTRY;

#define EEPROM_SIZE 128
#define QUEUE_ENTRIES (EEPROM_SIZE / sizeof(QUEUE_ENTRY))

uint32_t last_sequence_no;
uint8_t queue_tail;
uint16_t current_value;

// Called at startup
void load_queue()
{
  int i;

  last_sequence_no = 0;
  queue_tail = 0;
  current_value = 0;
  for (i=0; i < QUEUE_ENTRIES; i++)
  {
    // Following assumes you've written a function where the parameters
    // are address, pointer to data, bytes to read
    read_EEPROM(i * sizeof(QUEUE_ENTRY), &QUEUE_ENTRY, sizeof(QUEUE_ENTRY));
    if ((QUEUE_ENTRY.sequence_no > last_sequence_no) && (QUEUE_ENTRY.sequence_no != 0xFFFF))
    {
      queue_tail = i;
      last_sequence_no = QUEUE_ENTRY.sequence_no;
      current_value = QUEUE_ENTRY.my_data;
    }
  }
}

void write_value(uint16_t v)
{
  queue_tail++;
  if (queue_tail >= QUEUE_ENTRIES)
    queue_tail = 0;
  last_sequence_no++;
  QUEUE_ENTRY.sequence_no = last_sequence_no;
  QUEUE_ENTRY.my_data = v;
  // Following assumes you've written a function where the parameters
  // are address, pointer to data, bytes to write
  write_EEPROM(queue_tail * sizeof(QUEUE_ENTRY), &QUEUE_ENTRY, sizeof(QUEUE_ENTRY));
  current_value = v;
}

একটি ছোট EEPROM এর জন্য একটি 3-বাইট ক্রম আরও কার্যকর হবে, যদিও স্ট্যান্ডার্ড ডেটা ধরণের ব্যবহারের পরিবর্তে কিছুটা বিট স্লাইসিংয়ের প্রয়োজন হবে।


+1, দুর্দান্ত পন্থা। কম "ট্যাগ" বাইট ব্যবহার করে এবং অতিরিক্ত বিতরণ সরবরাহের জন্য সম্ভবত হ্যাশ বালতি ব্যবস্থার কোনও ফর্মের উপর নির্ভর করে স্টোরেজটি কি কিছুটা অনুকূল করা যায়? সমতলকরণ এবং আপনার পদ্ধতির মধ্যে একটি সংকর?
অনিন্দো ঘোষ

@ আনন্দো ঘোষ, হ্যাঁ আমি বিশ্বাস করি এটি পারে। আমি কোডটি সরলতার জন্য সাধারণত ব্যক্তিগতভাবে এই পদ্ধতিকে ছোট মাইক্রোতে ব্যবহার করেছি এবং ব্যক্তিগতভাবে এটি মূলত ডেটাফ্ল্যাশ এর মতো বড় ডিভাইসে ব্যবহার করেছি। অন্য একটি সহজ ধারণা যা মাথায় আসে তা হ'ল ক্রম সংখ্যাগুলি পর্যায়ক্রমে তাদের ছোট মানগুলিতে রাখার জন্য হ্রাস করা যেতে পারে।
পিটারজে

@ এম.আলিন দ্বারা উল্লিখিত এটমেল অ্যাপ্লিকেশন নোটটিতে একটি স্মার্ট সরলকরণ রয়েছে: একটি রিসেটের পরে [...] বাফারের মাধ্যমে অনুসন্ধান করা সম্ভব হবে, যেখানে শেষের [...] বাফার উপাদানটি স্থানটি আবিষ্কার করে পরিবর্তিত হয়েছিল যেখানে একটি বাফার উপাদান এবং পরবর্তী বাফার উপাদানের মধ্যে পার্থক্য 1 এর চেয়ে বড়
জিপ্পি

লেখার_মূল্য () কিউ_ টেইল * আকারের (QUEUE_ENTRY) এ এন্ট্রি রাখা উচিত নয়? আমি প্রথমবার সংশোধন করব, তবে একাধিক লেখক থাকলে এটি কি অগ্রসর হওয়া উচিত নয়? আমি লোড_কিউ () এর বাইরে বাড়ানো হয়নি।
মার্শাল ইউব্যাঙ্কস 25'15

2
@ ডিডব্লর্ড 32: হ্যাঁ, এটি প্রযুক্তিগতভাবে সঠিক, তবে বাস্তবে অপ্রাসঙ্গিক। এটি হওয়ার পরে, EEPROM এ পরিধানের সীমা 2000 এর গুণককে ছাড়িয়ে যাবে!
ডেভ টুইট করেছেন

5

নীচে বালতি এবং বালতি প্রতি প্রায় এক ওভারহেড বাইট ব্যবহার করে এমন একটি পদ্ধতি রয়েছে। বালতি বাইট এবং ওভারহেড বাইট একই পরিধানের প্রায় পায়। উদাহরণস্বরূপ, 128 ইপ্রোম বাইট দেওয়া এই পদ্ধতিতে 42 2-বাইট বালতি এবং 44 স্ট্যাটাস বাইট বরাদ্দ করা হয়, প্রায় 42-ভাড়ার পরিধানের ক্ষমতা বাড়ানো।

পদ্ধতি:

EEPROM ঠিকানার স্থান কে কে বালকেটে বিভক্ত করুন যেখানে k = ⌊ E / ( n +1) ⌋, এন = সেটআপ-ডেটা-অ্যারে আকার = বালতির আকার এবং E = EEPROM আকারের (বা আরও সাধারণভাবে EEPROM এর সংখ্যা সহ) কোষগুলি এই ডেটা কাঠামোর প্রতি উত্সর্গ করা হবে)।

একটি ডিরেক্টরি শুরু করুন, এম = বাইটের একটি অ্যারে এম কে সব সেট করে কে , এম = এন · কে দিয়ে । আপনার ডিভাইসটি শুরু হয়ে গেলে, এটি বর্তমান এন্ট্রি না পাওয়া পর্যন্ত এটি ডিরেক্টরিটি পড়ে, যা k এর সমান নয় বাইট । [যদি সমস্ত ডিরেক্টরি এন্ট্রি সমান কে থাকে তবে প্রথম ডিরেক্টরি এন্ট্রিটি 0 তে আরম্ভ করুন এবং সেখান থেকে যান]]

বর্তমান ডিরেক্টরী এন্ট্রি রয়েছে যখন , বালতি বর্তমান তথ্য রয়েছে। যখন আপনাকে একটি নতুন সেটআপ-ডেটা এন্ট্রি লিখতে হবে, আপনি বর্তমান ডিরেক্টরি এন্ট্রিতে j +1 সংরক্ষণ করবেন ; যদি এটি কে-এর সমান করে তোলে , পরবর্তী ডিরেক্টরি এন্ট্রিটি 0 তে আরম্ভ করুন এবং সেখান থেকে যান।

নোট করুন যে ডিরেক্টরি বাইটস বালতি বাইট হিসাবে সমান পরিমাণ পরিধান সম্পর্কে পায় কারণ 2 · k > মিকে

(আমি আমার উত্তর থেকে আর্দুইনো এসই প্রশ্নের 34189 প্রশ্নের উত্তর থেকে উপরের রূপান্তরিত করেছিলাম , কীভাবে ইপ্রোমের জীবন বাড়ানো যায়? )


2

আমি এর জন্য একটি রোলিং সিকোয়েন্স নম্বর ব্যবহার করেছি (পিটারের উত্তরের মতো)। ক্রম সংখ্যাটি আসলে 1 বিটের মতো সামান্য হতে পারে, যা সংখ্যার উপাদানগুলির সংখ্যা বিজোড় প্রদান করে। এরপরে মাথা এবং লেজটি টানা 2 টি 1 বা 0 এর দ্বারা চিহ্নিত করা হয়

উদাহরণস্বরূপ যদি 5 টি উপাদানের মাধ্যমে রোল করতে চান তবে ক্রম সংখ্যাগুলি হ'ল:

{01010} (0- এ লিখুন) {11010} (1 তে লিখুন) {10010} (2 তে লিখুন) {10110} (3 তে লিখুন) {10100} (4 তে লিখুন) {10101} (5 এ লিখুন)


1

আপনার কাছে থাকা EEPROM এবং আপনার ডেটার আকারের উপর নির্ভর করে বেশ কয়েকটি বিকল্প রয়েছে।

  1. যদি আপনার EEPROM এর স্বতন্ত্রভাবে মুছে ফেলা পৃষ্ঠাগুলি রয়েছে এবং আপনি 1 টি পৃষ্ঠা (বা আরও) ব্যবহার করেন তবে কেবলমাত্র ব্যবহৃত পৃষ্ঠাগুলি বাদে সমস্ত পৃষ্ঠা মুছে রাখুন এবং পৃষ্ঠাগুলিকে একটি বৃত্তাকার পদ্ধতিতে পুনরায় ব্যবহার করুন।

  2. আপনি যদি কেবল এমন কোনও পৃষ্ঠার ভগ্নাংশ ব্যবহার করেন যা একবারে মুছতে হয়, সেই পৃষ্ঠাটিকে ডেটা এন্ট্রিগুলিতে ভাগ করুন। প্রতিবার আপনি যখন লিখছেন তখন একটি পরিষ্কার এন্ট্রি ব্যবহার করুন এবং একবার পরিষ্কার এন্ট্রিগুলি শেষ হয়ে গেলে মুছুন।

যদি প্রয়োজন হয় তবে পরিষ্কার এবং ময়লা প্রবেশের মধ্যে বলতে একটি "নোংরা" বিট ব্যবহার করুন (সাধারণত, আপনার কমপক্ষে একটি বাইট থাকে যা 0xFF থেকে আলাদা হওয়ার গ্যারান্টিযুক্ত, যা নোংরা এন্ট্রিগুলি ট্র্যাক করতে ব্যবহার করা যেতে পারে)।

যদি আপনার EEPROM গ্রন্থাগারটি মুছা ফাংশনটি (আরডুইনোর মতো) প্রকাশ না করে, তবে এখানে # 2 অ্যালগোরিদমের ঝরঝরে কৌশল রয়েছে : যেহেতু আপনার প্রথম EEPROM এন্ট্রি সর্বদা ব্যবহৃত হয়, আপনি এটি পড়ে "নোংরা" বিটের মান নির্ধারণ করতে পারেন। তারপরে একবার আপনি পরিষ্কার এন্ট্রিগুলি শেষ হয়ে গেলে, আপনি "নোংরা" বিট উল্টিয়ে প্রথম এন্ট্রি থেকে আবার শুরু করবেন এবং আপনার বাকী এন্ট্রিগুলি স্বয়ংক্রিয়ভাবে "ক্লিন" হিসাবে চিহ্নিত হয়ে যাবে।

সিকোয়েন্স নম্বর এবং ক্যাটালগগুলি স্থানের অপব্যয়, যদি না আপনি খারাপ পৃষ্ঠাগুলি ট্র্যাক করতে সক্ষম হন বা আপনার EEPROM ডেটার বিভিন্ন অংশ স্বাধীনভাবে আপডেট করতে না চান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.