اطلاعیه

Collapse
No announcement yet.

هنگ کردن در روتین وقفه

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    هنگ کردن در روتین وقفه

    سلام
    به تازگی به مشکل عجیبی در روتین وقفه در lpc1768 برخوردم .در یک روتین وقفه RTC یک آرایه 64 بایتی تعریف کرده ام و در بخشی از روتین به اندازه 50 بایت پر می شود.حال وقتی برنامه اجرا می شود.در روتین وقفه گیر میکند و در دیباگ هم Jlink اخطار صفر بودن بیت T را در رجیستر XPSR را می دهد و برنامه متوقف می شود.قسمت جالب ماجرا اینجاست که اگر سایز آرایه را بیشتر کنم مثلا 128 مشکل حل می شود.
    این هم خطایی که در دیباگر می دهد:
    **JLink Warning: T-bit of XPSR is 0 but should be 1. Changed to 1.
    لازم به ذکره هیچگونه تغییری در بردارهای وقفه نیز ندادم .ممنون میشم اساتید کمک کنند

    #2
    پاسخ : هنگ کردن در روتین وقفه

    یکی از علت های هنگ کردن در وقفه اینه که پشته (Stack) پُر بشه، یا اشاره گرش به جای نادرستی اشاره کنه. این اتفاق هم وقتی رخ میده که متغیرها و مخصوصاً آرایه ها و اشاره گرهای محلی در تابع وقفه نوشته شده و در برنامه به آدرسِ نادرست اشاره شده و یه بخشی از پشته نابجا تغییر داده شده و در برگشت از وقفه بازیابی رجیسترهای وضعیت دچار اختلال می شه.
    اگه مشکلِ شما این باشه، راه حلش ساده س؛ اندازه (Size) پشته رو بیشتر کنید و داخل توابع یا روتین های وقفه مراقب آرایه ها و اشاره گرها باشید.
    بیایید با Google آشتی کنیم!

    دیدگاه


      #3
      پاسخ : هنگ کردن در روتین وقفه

      ممنون از پاسخ خوبتان.مشکل تا حدود زیادی حل شد.در واقع طبق گفته شما ایراد از آرایه تعریف شده بود.نکته در این بود که من طبق دستور sprintf و به شکل زیر آرایه را به اشتباه بیشتر از سایز پر میکردم :
      کد:
      sprintf((char*)buff,"**********ALARM**********\n\
      												Time = %02u:%02u:%02u\n\
      												Date = 20%02u/%02u/%02u\n",
      						rtctime.HOUR,rtctime.MIN,rtctime.SEC,rtctime.YEAR,rtctime.MONTH,rtctime.DOM);
      در واقع من به اشتباه تصور می کردم بعد از "\" (که برای خوانایی بهتر کد و چند خطه کردن دستور استفاده کرده بودم)بلافاصله ادامه حروف رشته قرار می گیرد و توجه نداشتم که فاصله ای که برای خوانا تر کردن کد از ابتدای خط بعد قرار داده بودم در آرایه منظور می شود و بنابراین آرایه سرریز میشد و باقی مشکلات.
      اما ...
      اما یک سوال اساسی هنوز برای من وجود دارد ،من این کد را به همین شکل قبلتر استفاده کرده بودم اما این مشکل به وجود نیامده بود.ممکن است اضافه تر شدن کد و اضافه کردن آرایه های جدید دلیل این امر باشه؟
      و سوال دوم این که اصولا در روتینهای وقفه استفاده از آرایه به چه صورت درست تر و مطمئنتر هست ؟

      دیدگاه


        #4
        پاسخ : هنگ کردن در روتین وقفه

        در موردِ اینکه چرا قبلاً کدتون درست کار می کرده و حالا نه، نظر خاصی ندارم. جز اینکه ممکنه وقفه های تو در تو استفاده کرده باشید و پشته سرریز شده باشه.

        روتین وقفه هیچ فرق چشمگیری با یک تابع نداره. در فراخوانیِ هر دوتاشون رجیسترهای وضعیت توی پشته ذخیره می شن و بعدش تمامِ متغیرهای محلی تابع توی پشته قرار می گیره. شما با هر پردازنده ای که کار می کنید باید بلد باشید اندازه پشته رو کجای کد یا تنظیمات کامپایلر باید زیاد و کم کنید.
        به صورت یک قانون کلی همیشه به خاطر داشته باشید که متغیرهای محلیِ زیاد و آرایه های حجیم به صورت محلی توی تابع تعریف نکنید. اگه مجبور به استفاده از یه آرایه بزرگ هستید ببریدش اول کد به صورت عمومی تعریفش کنید. سعی کنید توی وقفه تابع فراخوانی نکنید، خصوصاً توابعی که خودشون دوباره توابع دیگه رو فراخوانی می کنن. می تونید تصور کنید که اگه 6 تا تابع تو در تو فراخوانی بشن چه وضعیتی برای پشته به وجود میاد...

        آخرِ سر هم اینکه توابع کتابخانه ای ورودی/خروجی استاندارد C به طرز عجیبی پیچیده و خفن هستند! اونقدر خفن که باید ساعت ها و روزها وقت صرف کنیم تا بفهمیم داخلش داره چی می گذره. printf و sprintf و scanf و امثال اینها توابعی به شدت پیچیده هستند که زمان زیادی رو از پردازنده برای اجرا می گیرند. بهتره به هیچ عنوان این توابع داخل روتین وقفه فراخوانی نشن و همیشه توی main استفاده بشن.

        همینا دیگه
        موفق باشید
        بیایید با Google آشتی کنیم!

        دیدگاه

        لطفا صبر کنید...
        X