هل هناك خوارزمية عامة لتسوية تآكل EEPROM للمتحكم الدقيق؟

StackOverflow https://stackoverflow.com//questions/10667491

  •  11-12-2019
  •  | 
  •  

سؤال

أنا أعمل على مكتبة Arduino التي ستعمل على زيادة عمر EEPROM الخاص بـ AVR.فهو يأخذ عدد المتغيرات التي تريد تخزينها ويقوم بالباقي.هذه محاولتي التي لا تنجح في كل الحالات.

معلومات اساسية

يقول أتميل إن كل خلية ذاكرة مُصنفة بـ 100000 دورة كتابة/مسح.كما أنها توفر ملاحظة التطبيق, ، الذي يصف كيفية إجراء تسوية التآكل.فيما يلي ملخص لمذكرة التطبيق.

من خلال تبديل عمليات الكتابة عبر عنوانين للذاكرة، يمكننا زيادة عملية المسح/الكتابة إلى 200000 دورة.تمنحك ثلاثة عناوين ذاكرة 300000 دورة مسح/كتابة وما إلى ذلك.لأتمتة هذه العملية، يتم استخدام المخزن المؤقت للحالة لتتبع مكان الكتابة التالية.يجب أيضًا أن يكون المخزن المؤقت للحالة بنفس طول المخزن المؤقت للمعلمة لأنه يجب إجراء تسوية التآكل عليه أيضًا.نظرًا لأننا لا نستطيع تخزين فهرس الكتابة التالية، فإننا نقوم بزيادة الفهرس المقابل في المخزن المؤقت للحالة.

هنا مثال.

   <------------------- EEPROM -------------------->  
   0                                               N
   -------------------------------------------------
       Parameter Buffer    |     Status Buffer     |
   -------------------------------------------------

   Initial state.
   [ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ]

   First write is a 7. The corresponding position
   in the status buffer is changed to previous value + 1.
   Both buffers are circular.
   [ 7 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 ]

   A second value, 4, is written to the parameter buffer 
   and the second element in the status buffer becomes
   the previous element, 1 in this case, plus 1.
   [ 7 | 4 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | 0 | 0 | 0 ]

   And so on
   [ 7 | 4 | 9 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 ]

لتحديد مكان حدوث الكتابة التالية، ننظر إلى الفرق بين العناصر.إذا كان العنصر السابق + 1 لا يساوي العنصر التالي، فهذا هو المكان الذي يجب أن تحدث فيه الكتابة التالية.على سبيل المثال:

   Compute the differences by starting at the first
   element in the status buffer and wrapping around. 
   General algo: previous element + 1 = current element
   1st element:  0 + 1 = 1 = 1st element (move on)
   2nd element:  1 + 1 = 2 = 2nd element (move on)
   3rd element:  2 + 1 = 3 = 3rd element (move on)
   4th element:  3 + 1 = 4 != 4th element (next write occurs here)

   [ 7 | 4 | 9 | 0 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 ]
                 ^                       ^
                 |                       |

   Another edge case to consider is when the incrementing values
   wrap around at 256 because we are writing bytes. With the
   following buffer we know the next write is at the 3rd element 
   because 255 + 1 = 0 != 250 assuming we are using byte arithmetic.

   [ x | x | x | x | x | x | 254 | 255 | 250 | 251 | 252 | 253 ]
                                          ^
                                          | 

   After we write at element 3 the status buffer is incremented 
   to the next value using byte arithmetic and looks like this.
   255 + 1 = 0 (wrap around)
   0 + 1 != 251 (next write is here)

   [ x | x | x | x | x | x | 254 | 255 |  0  | 251 | 252 | 253 ]
                                                ^
                                                | 

توضح هذه الأمثلة أعلاه كيفية إطالة عمر EEPROM لمتغير واحد.بالنسبة للمتغيرات المتعددة، تخيل تجزئة EEPROM إلى أجزاء متعددة بنفس بنية البيانات، ولكن بمخازن مؤقتة أصغر.

مشكلة

لدي كود العمل لما وصفته أعلاه.مشكلتي هي أن الخوارزمية لا تعمل عندما يكون طول المخزن المؤقت >= 256.وهنا ما يحدث

   Buffer length of 256. The last zero is from
   the initial state of the buffer. At every index
   previous element + 1 == next element. No way to
   know where the next write should be.

   <-------------- Status Buffer ------------>
   [  1  |  2  | ... | 253 | 254 | 255 |  0  ]


   A similar problem occurs when the buffer length
   is greater than 256. A lookup for a read will think
   the next element is at the first 0 when it should be at 
   255.
   <-------------------- Status Buffer ------------------>
   [  1  |  2  | ... | 253 | 254 | 255 |  0  |  0  |  0  ]

سؤال

كيف يمكنني حل المشكلة المذكورة أعلاه؟هل هناك طريقة أفضل لتتبع مكان كتابة العنصر التالي؟

هل كانت مفيدة؟

المحلول

بعض الأفكار حول تمديد عمر EEPROM العام:

  1. عادةً ما تتم كتابة خلايا EEPROM (بواسطة الجهاز) في عملية من خطوتين:أولاً، يتم مسح الخلية، أي تعيينها على كل الآحاد (0b11111111 = 0xff)، ثم تتم كتابة البتات المراد كتابتها (فعليًا فقط تلك التي تكون 0) بالفعل.لا يمكن ضبط البتات إلا على 0 من خلال عملية كتابة فعلية.يتطلب التغيير قليلاً من 0 إلى 1 مسح الخلية بأكملها ثم إعادة كتابة القيمة الجديدة.

  2. إذا كانت خلية EEPROM تحتوي بالفعل على نفس القيمة التي سيتم كتابتها إليها - وهو ما قد يكون هو الحال بالنسبة إلى (إعادة) كتابة أكثر أو أقل من البيانات - ليست هناك حاجة للكتابة إلى الخلية على الإطلاق، مما يقلل ارتداء لعملية الكتابة هذه إلى 0.قد يرغب المرء في التحقق من محتوى الخلايا لتحديد ما إذا كان يجب كتابتها على الإطلاق بدلاً من كتابة قيمة جديدة لها دائمًا.

  3. يؤدي الجمع بين ما سبق إلى نهج حيث يتم مسح الخلية فقط قبل الكتابة، إذا كان هناك أي بت واحد في القيمة الجديدة حيث تحتوي القيمة المخزنة على 0 بت (أي، إذا StoredValue & NewValue != NewValue).ليست هناك حاجة لمسح الخلية إذا لم تكن هناك انتقالات 0 -> 1 بت مطلوبة للقيمة الجديدة (StoredValue & NewValue == NewValue).

  4. يوفر AVR تعليمات منفصلة للمسح والكتابة إلى خلية EEPROM على التوالي لدعم الآليات المذكورة أعلاه.

  5. إن أسوأ سرعة لنقل البيانات إلى EEPROM ستنخفض بالطبع عند إجراء عملية قراءة ومقارنة ومسح وكتابة بدلاً من مجرد عملية المسح والكتابة.ومع ذلك، فإن هذا لديه القدرة على تخطي عمليات المسح والكتابة بشكل كامل لبعض/معظم الخلايا مما قد يقلل من عقوبة السرعة النسبية.

بالنسبة لمشكلتك الحالية، فكر في النقاط المذكورة أعلاه:لماذا لا تستخدم البتات المفردة لتخزين موضع الكتابة التالي؟

مثال:

تتم تهيئة المخزن المؤقت للحالة للجميع:

Bit number: 0123 4567 89AB CDEF
Value:      1111 1111 1111 1111

قبل الوصول إلى قيمة في EEPROM، ابحث عن أول 1 بت في المخزن المؤقت للحالة لديك.يمثل رقم هذا البت عنوان "الرأس" الحالي للمخزن المؤقت للمعلمة (الدائرية).

في كل مرة تقوم فيها بتقديم المخزن المؤقت للمعلمة، قم بتعيين البت التالي في المخزن المؤقت للحالة الخاص بك إلى 0:

Bit number: 0123 4567 89AB CDEF
Value:      0111 1111 1111 1111

ثم

Value:      0011 1111 1111 1111

ثم

Value:      0001 1111 1111 1111

وما إلى ذلك وهلم جرا.

يمكن القيام بذلك بدون محو الخلية بأكملها وبالتالي سوف "يتآكل" فقط جزء واحد من المخزن المؤقت للحالة لكل تحديث - إذا كانت البيانات المكتوبة تحتوي على 0 بت واحد فقط أيضًا.
لتحويل، على سبيل المثال، قيمة مخزنة لـ 0111 إلى القيمة الجديدة 0011 يجب أن تكون البيانات المراد كتابتها 1011 (data = ( newValue XOR oldValue ) XOR 0xff)، مع ترك جميع الأجزاء دون تغيير باستثناء الجزء الوحيد الذي نريد تغييره بالفعل.

بمجرد استنفاد المخزن المؤقت للحالة (كل 0)، يتم مسحه بالكامل، ويبدأ كل شيء من جديد.

الميزة الإضافية هنا هي أنه يجب الحفاظ على وحدة بت واحدة فقط من الحالة لكل وحدة من المخزن المؤقت للمعلمة، والتي تستهلك فقط 1/8 من الذاكرة مقارنة بملاحظة تطبيق Atmel. علاوة على ذلك، فإن العثور على موقع الكتابة التالي سيكون أيضًا أسرع بكثير حيث ستكون هناك حاجة إلى 1/8 فقط من عمليات القراءة في المخزن المؤقت للحالة. (يحرر:ليس صحيحًا لأن قراءات EEPROM تأتي بتكلفة صفر تقريبًا من حيث الأداء، في حين أن تحويل البت المطلوب قد يستغرق بضع عشرات من الدورات.)

لكن ملاحظة أخرى:هل تعتقد أنه من المفيد بالفعل استخدام أكثر من 256 وحدة عازلة للمعلمات؟ستصبح الوحدات صغيرة جدًا عند التعامل، على سبيل المثال، مع 1024 بايت من إجمالي EEPROM المتوفر على الجهاز.- و100000 دورة مضروبة في 256 يمثل عددًا كبيرًا جدًا من عمليات الكتابة، وإذا بدا أن هذا العدد الكبير مطلوب، فمن المحتمل أن يكون هناك خطأ ما في الخوارزمية أو لا ينبغي استخدام EEPROM لهذا الغرض على الإطلاق.كبديل خارجي NVRAM سيكون اختيارًا جيدًا في بعض السيناريوهات.

قد يكون وقت الوصول جانبًا هنا أيضًا:عند محاولة البحث عن عنصر بحجم 3 بايت على سبيل المثال وقراءته في المخزن المؤقت للمعلمة مع مخزن مؤقت للحالة يبلغ 256 بايت، 256 (+3) ستكون هناك حاجة إلى عمليات القراءة في أسوأ الحالات - وهو عبء هائل!

هناك وثيقة توضيحية للغاية حول عمل خلايا EEPROM، بما في ذلك كيفية وسبب التدهور:

إس تي مايكروإلكترونيكس:"كيف يمكن للمصمم تحقيق أقصى استفادة من eEproms التسلسلية للإلكترونية stmicroelectronic

نصائح أخرى

أقترح عليك استخدام بت "متسخا" بسيطا على عناصر البيانات بدلا من العدادات.ما لم يكن المسح الضوئي للخطر العنصر المكتوب بطيئا للغاية، أو كنت ترغب في القيام بشيء ما مثل تتبع خلايا EEPROM سيئة، فلا توجد نقطة في وجود عدادات وكتالوجات.

الخوارزمية بسيطة للغاية: قم بتعيين "القذرة" في كل عنصر تكتب، والمسح الضوئي لهذا البت عندما تحتاج إلى قراءة العنصر الأخير أو كتابة واحدة جديدة.عند نفاد النقاط النظيفة، إما محو جميع العناصر أو (في حالة اردوينو) فقط اقلب قيمة "القذات" والبدء من البداية.لقد كتبت شرحا مفصلا هنا ، إذا كنت بحاجة إلى واحدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top