سؤال

أثناء تشغيل برنامجي على جهاز ICD3 ذي الرقاقة الدقيقة، تبدو معالجة الاستثناء غريبة.سيتوقف البرنامج عن الاستجابة أثناء حدوث الاستثناء.أثناء التحقق من الكود، لاحظت أن الملف default-general-exception-handler.c سيقوم بإنشاء حلقة لا نهائية.إنه أمر محير حقًا لأنني لا أستطيع معرفة مكان حدوث الخطأ وما هو السبب.هل هذا يعني أن Microchip لا يدعم معالجة الاستثناءات؟أم أن هناك طريقة لقراءة رسالة الخطأ؟

حلقة لا نهائية:

---  \home\c11067\work\C32\builds\pic32-microchip-release-1.12-20101221-rc2-20101221\pic32-libs\libc\stubs\default-general-exception-handler.c
9D00DD28  1000FFFF   beq         zero,zero,0x9d00dd28
9D00DD2C  00000000   nop        

من خلال تحديد _general_exception_handler، فإنه يعمل!

// declared static in case exception condition would prevent
// auto variable being created
static enum {
    EXCEP_IRQ = 0,          // interrupt
    EXCEP_AdEL = 4,         // address error exception (load or ifetch)
    EXCEP_AdES,             // address error exception (store)
    EXCEP_IBE,              // bus error (ifetch)
    EXCEP_DBE,              // bus error (load/store)
    EXCEP_Sys,              // syscall
    EXCEP_Bp,               // breakpoint
    EXCEP_RI,               // reserved instruction
    EXCEP_CpU,              // coprocessor unusable
    EXCEP_Overflow,         // arithmetic overflow
    EXCEP_Trap,             // trap (possible divide by zero)
    EXCEP_IS1 = 16,         // implementation specfic 1
    EXCEP_CEU,              // CorExtend Unuseable
    EXCEP_C2E               // coprocessor 2
} _excep_code;



static unsigned int _epc_code;
static unsigned int _excep_addr;

// this function overrides the normal _weak_ generic handler
void _general_exception_handler(void)
{
    asm volatile("mfc0 %0,$13" : "=r" (_excep_code));
    asm volatile("mfc0 %0,$14" : "=r" (_excep_addr));

    _excep_code = (_excep_code & 0x0000007C) >> 2;

    while (1) {
        // Examine _excep_code to identify the type of exception
        // Examine _excep_addr to find the address that caused the exception
    }
}
هل كانت مفيدة؟

المحلول

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

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

نصائح أخرى

ومثلما رؤساء متابعة لمزيد من التصحيح استثناء PIC32، رموز استثناء وجميع البتات في سجل "السبب" (القيمة كنت تقرأ في متغير _excep_code قبل وجي جميع أجزاء أخرى بعيدا) هي المعرفة في:

دليل PIC32 المرجعي العائلة في القسم 2.12.9 السبب التسجيل http://ww1.microchip.com/downloads/en/DeviceDoc/61113C.pdf

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