اطلاعیه

Collapse
No announcement yet.

حذف آدرس بازگشت در فراخوانی وقفه؟

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

    حذف آدرس بازگشت در فراخوانی وقفه؟

    سلام دوستان
    یه تابع دارم که داخلش توی یه حلقه while منتظر دریافت ورودی میمونه. میخام با وقفه 0 و قبل از دریافت ورودی از این تابع بیام بیرون و یه تابع دیگر رو فراخوانی کنم.
    مشکل اینجاست که بعد از تموم شدن تابع دوم، دوباره بر میگرده با آدرس بازگشت (همون حلقه منتظر دریافت ورودی).
    یه سری سرچ کردم که میشه با دستور
    کد:
     __builtin_return_address 
    void *pc0 = __builtin_return_address(0);
      void *pc1 = __builtin_return_address(1);
      void *pc2 = __builtin_return_address(2);
      void *pc3 = __builtin_return_address(3);
    به آدرس دسترسی داشت ولی اصلا نتونستم باهاش کار کنم
    1- چه جوری میشه بعد از فراخوانی یه وقفه آدرس بازگشت و حذف کرد؟
    2- یا اینکه آدرس بازگشت تو کدوم رجیستر ذخیره میشه؟دسترسی بهش هست؟
    3- با غیرفعال کردن وقفه از داخل روتین وقفه میشه آدرس بازگشت رو حذف کرد؟



    ATMega32 A
    Atmel Studio
    زبان سی کامپایلر AVR GCC



    کد:
    void func1();
    int Get_Input();
    int func2();
    
    void Process(int p);
    
    
    ISR(INT0_vect)
    {
    // need to remove returned address here by reti() or changing register values
    	func1();
    }
    
    void func1()
    {
    	int p;
    	while(1)
    	{
    		if(condition1)
    		{
    			p = Get_input();
    		}
    		if(condition2)
    		{
    			p =func2();
    		}
    		
    		Process(p);
    	}
    }
    int Get_input()
    {
    	int input = -1;
    	while(input != -1)
    	{
    		input = Get_Input();
    	}
    	return input;
    }
    
    void Process(int p){}
    
    void func2()
    {
    	condition1 = true;
    	// here need Empty return Stack
    	func1();
    	.
    	.
    	.
    	func2();
    }
    int main(void)
    {
    	while(1)func1();
    }
    اللهم صل علي محمد و ال محمد و عجل فرجهم
    >>> www.DMF313.ir <<<
    اگر ژرف یابی و پژوهش نباشد; نتیجه اش یک جا ایستادن،
    در جا زدن و با دنیای پیرامون خود به تدریج بیگانه تر شدن
    است.

    #2
    پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟(لطفا حرفه ای ها بیان تو )

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

    دیدگاه


      #3
      پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟(لطفا حرفه ای ها بیان تو )

      لازم نیست انقدر قضیه رو پلیسی جناییش کنی
      :redface: :biggrin:
      ممنون دوست عزیز.
      یه روشی بود که متغیر داخل حلقه while طوری تعریف میکردیم که کامپایلر دستکاریش نکنه تا با وقفه قابل تغییر بود
      اون روشش چی بود چی بود؟
      اللهم صل علي محمد و ال محمد و عجل فرجهم
      >>> www.DMF313.ir <<<
      اگر ژرف یابی و پژوهش نباشد; نتیجه اش یک جا ایستادن،
      در جا زدن و با دنیای پیرامون خود به تدریج بیگانه تر شدن
      است.

      دیدگاه


        #4
        پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟(لطفا حرفه ای ها بیان تو )

        احتمالا منظورت volatile هست.
        مثلا volatile int ret_check;

        البته بگم که این مورد زمانی بدرد میخوره که متغیر تو اینتراپتها مقدارش تغییر کنه و توی main چک بشه.
        ولی شما استفاده کن.

        دیدگاه


          #5
          پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

          حالا گذشته از این موضوع، کلا راهی هست که به آدرس برگشت دسترسی داشته باشیم؟ رجیستری؟چیزی؟
          اللهم صل علي محمد و ال محمد و عجل فرجهم
          >>> www.DMF313.ir <<<
          اگر ژرف یابی و پژوهش نباشد; نتیجه اش یک جا ایستادن،
          در جا زدن و با دنیای پیرامون خود به تدریج بیگانه تر شدن
          است.

          دیدگاه


            #6
            پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

            اگر شما کل برنامه رو با اسمبلی مینوشتی مشکلی نبود ، خیلی راحت میتونستی با دستوران push , pop تو فضای Stack حرکت داشته باشی . اما وقتی داری تو یه کامپایلر C برنامه مینوسی و اون کد شما رو به اسمبلی تبدیل میکنه ، اونوقت شما نمیدونید که ادرس برگشت رو تو کدوم آدرس از Stack قرار داده تا شما تغییرش بدی.

            نمیدونم متوجه شدی که منظورم چیه؟

            دیدگاه


              #7
              پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

              بله متوجه شدم ممنون.
              البته دستور __builtin_return_address به ترتیب محل آدرس ها رو برمیگردونه ولی کامپایلر من این دستور رو نمیشناسه
              :angry: :angry:
              فقط شما نیاز به یه متغیر داری که تو تابع دومت اون رو ست کنی و وقتی از تابع دوم برگشت تو تابع اولت یا همون while که میگی ، تو او while بیا اون متغیر رو چک کن.
              اگر ست شده بود از while خارج شو.
              تست کردم. متاسفانه این کار فقط از دستور while خارج میشه و بعد از تمام شدن تابع به آدرسی که تابع فراخوانی شده برمیگرده و از اونجا شروع میکنه به ادامه دادن.
              من میخوام یک سیر فراخوانی از داخل روتین وقفه ایجاد کنم که بعد از تموم شدنشون دیگه برنگرده به قبل از روتین وقفه.. متوجه شدید میخام چیکر کنم؟ oo: oo: :cry: :cry:
              اللهم صل علي محمد و ال محمد و عجل فرجهم
              >>> www.DMF313.ir <<<
              اگر ژرف یابی و پژوهش نباشد; نتیجه اش یک جا ایستادن،
              در جا زدن و با دنیای پیرامون خود به تدریج بیگانه تر شدن
              است.

              دیدگاه


                #8
                پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

                متاسفانه این مورد رو اصلا کار نکردم و اطلاعی هم ندارم ، اما بنظرم میرسه شما راه رو داری اشتباه میری.شما میتونید با تغییر در مقدار یک یا چند متغیر عمومی و چک کردن اون تو main و جاهایی که لازمه ، راحت توابع مختلف رو فراخونی کنید و تصور نمیکنم نیازی به این کارا باشه. اگر شما بگین میخواین چیکار کنید شاید بهتر بشه راهنمایی کرد.
                موفق باشید.

                دیدگاه


                  #9
                  پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

                  با سلام

                  دوست عزیز وقفه اسمش روشه . یعنی پردازنده در حال انجام کار عادیش است یک دفعه وقفه رخ میده . پردازنده میره کار جدید انجام میده و دوباره ادامه کار قبلی رو پی میگیره .
                  من دقیقا هدف شما رو متوجه نشدم که چرا میخواهید کار خارق العاده انجام دهید.
                  مثال
                  شما در آشپزخانه درحال پختن آش هستید . یک هو وقفه تلفن رخ میده . شما به پذیرایی میروید و به تلفن جواب میدهید . حال شما میخواهد بعد از جواب دادن به تلفن مستقیما به لب روخونه برید برای ماهی گیری ؟ :eek: ؟ پس اون قضیه پختن آش چی شد ؟
                  تنها موردي كه همه آدما يقين دارن خدا در حقش زیاد لطف کرده
                  داشتن عقله زيادتر از دیگر آدم ها است

                  دیدگاه


                    #10
                    پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

                    دوست عزیز وقفه اسمش روشه . یعنی پردازنده در حال انجام کار عادیش است یک دفعه وقفه رخ میده . پردازنده میره کار جدید انجام میده و دوباره ادامه کار قبلی رو پی میگیره .
                    من دقیقا هدف شما رو متوجه نشدم که چرا میخواهید کار خارق العاده انجام دهید.
                    مثال
                    شما در آشپزخانه درحال پختن آش هستید . یک هو وقفه تلفن رخ میده . شما به پذیرایی میروید و به تلفن جواب میدهید . حال شما میخواهد بعد از جواب دادن به تلفن مستقیما به لب روخونه برید برای ماهی گیری ؟ :eek: ؟ پس اون قضیه پختن آش چی شد ؟
                    مثال خوبی زدید،سناریو رو اینطوری عوض کنید:
                    در حین آشپزی تلفن زنگ میزنه، تلفن رو جواب میدم، دوستم زنگ زده و منو دعوت کرده به رستوران،پس کلا بیخیال آشپزی شدم.... :agree:
                    گرفتید چی شد؟

                    شما میتونید با تغییر در مقدار یک یا چند متغیر عمومی و چک کردن اون تو main و جاهایی که لازمه ، راحت توابع مختلف رو فراخونی کنید و تصور نمیکنم نیازی به این کارا باشه.
                    یه متغیر global گذاشتم تو همه توابع که توی برگشت آدرس اگه اون متغیر ست شده باشه به تابع قبلی return میکنه و اینجوری مشکلم حل شد. ولی کدم کثیف شد! :angry: :angry: :angry: :angry:

                    به هرحال ممنون از دوستان. :nice: :nice:
                    اللهم صل علي محمد و ال محمد و عجل فرجهم
                    >>> www.DMF313.ir <<<
                    اگر ژرف یابی و پژوهش نباشد; نتیجه اش یک جا ایستادن،
                    در جا زدن و با دنیای پیرامون خود به تدریج بیگانه تر شدن
                    است.

                    دیدگاه


                      #11
                      پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

                      نوشته اصلی توسط حمید زارع
                      سلام دوستان
                      یه تابع دارم که داخلش توی یه حلقه while منتظر دریافت ورودی میمونه. میخام با وقفه 0 و قبل از دریافت ورودی از این تابع بیام بیرون و یه تابع دیگر رو فراخوانی کنم.
                      مشکل اینجاست که بعد از تموم شدن تابع دوم، دوباره بر میگرده با آدرس بازگشت (همون حلقه منتظر دریافت ورودی).

                      اگر وقفه فقط یک بار رخ بده حق با شماست ولی وقفه اگر چند بار رخ بده چی ؟ یعنی بار اول که وقفه رخ داد با دست کاری پشته شما برای همیشه میپری به تابع a حال اگر برای بار دوم وقفه رخ بده چی ؟ وسط کار تابع a شما دوباره میپری به اول تابع a ? خوب این یعنی چی؟

                      کلا دست کاری آدرس بزگشت تابع به راحتی آب خوردن است . ولی این دیگه برنامه نمی شه میشه بمب دستی . هر لحظه امکان ترکیدن داره.
                      تنها موردي كه همه آدما يقين دارن خدا در حقش زیاد لطف کرده
                      داشتن عقله زيادتر از دیگر آدم ها است

                      دیدگاه


                        #12
                        پاسخ : حذف آدرس بازگشت در فراخوانی وقفه؟

                        اگر وقفه فقط یک بار رخ بده حق با شماست ولی وقفه اگر چند بار رخ بده چی ؟ یعنی بار اول که وقفه رخ داد با دست کاری پشته شما برای همیشه میپری به تابع a حال اگر برای بار دوم وقفه رخ بده چی ؟ وسط کار تابع a شما دوباره میپری به اول تابع a ? خوب این یعنی چی؟
                        شما درست میگید، یه سری متغیرهایی گذاشتم واسه کنترل روندش
                        اللهم صل علي محمد و ال محمد و عجل فرجهم
                        >>> www.DMF313.ir <<<
                        اگر ژرف یابی و پژوهش نباشد; نتیجه اش یک جا ایستادن،
                        در جا زدن و با دنیای پیرامون خود به تدریج بیگانه تر شدن
                        است.

                        دیدگاه

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