আরডুইনোতে ফাংশন পয়েন্টার নিয়োগগুলি পারমাণবিক?


11

নিম্নলিখিত স্নিপেটগুলি টাইমারঅন লাইব্রেরি উত্স কোড থেকে এসেছে :

// TimerOne.h:
void (*isrCallback)();

// TimerOne.cpp:
ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
  Timer1.isrCallback();
}

// TimerOne.cpp:
void TimerOne::attachInterrupt(void (*isr)(), long microseconds)
{
  if(microseconds > 0) setPeriod(microseconds);
  isrCallback = isr; // register the user's callback with the real ISR
  TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
  resume();                                                                                            
}

প্রশ্ন: যদি টাইমারটি ইতিমধ্যে চলমান থাকে এবং মূল প্রোগ্রামটি কল করে attachInterrupt(), ফাংশন পয়েন্টার অ্যাসাইনমেন্টের সময় সেখানে টাইমার বিঘ্নিত হতে পারে isrCallback = isr;? তারপরে, ভাগ্যবান টাইমিংয়ের সাথে, Timer1.isrCallback();ফাংশন পয়েন্টারটি আংশিকভাবে পুরানো এবং আংশিকভাবে নতুন ঠিকানার সমন্বয় করে, আইএসআরটি বগাসের জায়গায় ঝাঁপিয়ে পড়ে?

আমি মনে করি এটির ক্ষেত্রে এটি হতে পারে, যেহেতু ফাংশন পয়েন্টারগুলি অবশ্যই 1 বাইটের চেয়ে বেশি প্রশস্ত হয় এবং>> 1 বাইট ডেটা অ্যাটমিক হয় না। সম্ভাব্য কাজের ক্ষেত্রগুলি হতে পারে:

  • কল detachInterrupt()করার আগে টাইমারটি চলছে না তা নিশ্চিত হওয়ার জন্য সর্বদা কল করুন attachInterrupt(), অর্থাৎ টাইমার 1 ডক্স পরিষ্কার করুন।
  • অথবা, টাইমার 1 সংশোধন করুন, টাইমার ওভারফ্লো ব্যাহত করার আগে সাময়িকভাবে অস্থায়ীভাবে বিরতি ঘটে isrCallback = isr;

এটি কি অর্থবোধ করে, বা Timer1উত্স বা ফাংশন পয়েন্টার অ্যাসাইনমেন্টগুলিতে এমন কিছু আছে যা আমি মিস করেছি?

উত্তর:


7

সংযুক্তি আন্তঃবিড়ম্ব () এবং ডিটাচ ইন্টের্প্রপ্ট () এর কোড দেখুন /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WInterrupts.c(ভাল, এগুলি যেভাবেই ম্যাকের উপরে রয়েছে other

এটি আবির্ভূত হয় যে সংযুক্তি আন্তঃবিঘ্নিত () ধরে নিয়েছে যে প্রশ্নে বিঘ্নিত হওয়া এখনও সক্ষম হয়নি কারণ এটি কোনও সতর্কতা না নিয়ে ফাংশন পয়েন্টারটি লিখে দেয়। নোট করুন যে ডিটাচ ইন্টেরাপ্র্টস () তার ভেক্টরটিতে একটি NULL- পয়েন্টার লেখার আগে লক্ষ্য বাধাকে অক্ষম করে। সুতরাং আমি কমপক্ষে একটি detachInterrupt()/ attachInterrupt()জোড়া ব্যবহার করব

আমি এই জাতীয় কোডটি নিজেই একটি সমালোচনামূলক বিভাগে চালাতে চাই। এটি আপনার প্রথম উপায়ে প্রদর্শিত হবে (বিচ্ছিন্ন, তারপরে সংযুক্তি) কাজ করবে, যদিও আমি নিশ্চিত হতে পারি না যে এটি দুর্ভাগ্যক্রমে সময়সাপেক্ষ বাধাকে মিস করতে পারে না। আপনার এমসিইউর জন্য ডেটাশিটে আরও কিছু বলতে পারে। তবে উভয়ই আমি এই মুহুর্তে নিশ্চিত নই যে কোনও গ্লোবাল cli()/ sei()এটিও মিস করবে না। এটিএমগা 2560 ডাটাশিট, বিভাগের 6.8-এ বলা হয়েছে, "বাধা সক্ষম করতে এসইআই নির্দেশিকাটি ব্যবহার করার সময়, এসইআই অনুসারে নিম্নলিখিত নির্দেশটি কোনও বিচারাধীন বাধার আগে কার্যকর করা হবে, যেমন এই উদাহরণে দেখানো হয়েছে", বোঝা যাচ্ছে যে এটি বিঘ্নের সময় বাধা দিতে পারে বন্ধ আছে


এটি উত্সগুলিতে ডুব দেওয়ার পক্ষে সত্যই কার্যকর: টাইমরওনের সংযুক্তি / বিচ্ছিন্ন বিঘ্ন প্রক্রিয়াটি স্ট্যান্ডার্ড (উইন্টারটার্ট) এর মতোই সম্পন্ন হয়েছে বলে মনে হয় এবং একই "বৈশিষ্ট্যগুলি" রয়েছে।
জুনাস পুলক্কা

0

দেখে মনে হচ্ছে আপনার একটা বিষয় আছে। যুক্তিযুক্ত জিনিসটি হ'ল বিঘ্নগুলি এমনভাবে অক্ষম করা যাতে আপনি সেগুলিকে প্রথম স্থানে অক্ষম করা হয় যদি আপনি তাদের পুনরায় সক্ষম না করেন। উদাহরণ স্বরূপ:

  uint8_t oldSREG = SREG;  // remember if interrupts are on
  cli();                   // make the next line interruptible
  isrCallback = isr;       // register the user's callback with the real ISR
  SREG = oldSREG;          // turn interrupts back on, if they were on before

"বাধা সক্ষম করতে এসইআই নির্দেশিকাটি ব্যবহার করার সময়, এসইআই অনুসরণকারী নির্দেশগুলি কোনও মুলতুবি বাধা দেওয়ার আগেই কার্যকর করা হবে, যেমন এই উদাহরণে দেখানো হয়েছে"

এর উদ্দেশ্যটি আপনাকে এই জাতীয় কোড লিখতে দেয়:

  sei ();         // enable interrupts
  sleep_cpu ();   // sleep

এই বিধান ব্যতীত আপনি এই দুটি লাইনের মধ্যে একটি বাধা পেতে পারেন এবং এভাবে অনির্দিষ্টকালের জন্য ঘুমান (কারণ যে বিঘ্নটি আপনাকে জাগিয়ে তুলছিল তা ঘুমানোর আগেই ঘটেছিল )। প্রসেসরের বিধান যে পরবর্তী নির্দেশাবলী, বাধা দেওয়ার পরে সক্ষম করা সক্ষম করে যদি তারা আগে সক্ষম না করা হয়, সর্বদা কার্যকর করা হয়, এর বিরুদ্ধে রক্ষা করে।


এটা কি আরও দক্ষ হবে না TIMSK1=0; TIFR1=_BV(TOV1); isrCallback=isr; TIMSK1=_BV(TOIE1);? এটি একটি সিপিইউ রেজিস্ট্রারকে ছাড়ায় এবং বিঘ্নিত বিলম্বকে অবদান দেয় না।
এডগার বোনেট

অন্যান্য বিটগুলি যেমন আইসিআইই 1, ওসিআইই 1 বি, ওসিআইই 1 এ সম্পর্কে কী? আমি বিলম্বিতা সম্পর্কে বুঝতে পারি, তবে বাধাগুলি উপলব্ধ না হওয়ার কয়েক ঘন্টার চক্রের সাথে লড়াই করতে সক্ষম হওয়া উচিত। রেসের শর্ত থাকতে পারে। বাধা ইতিমধ্যে ট্রিগার হতে পারে (যেমন সিপিইউতে পতাকা সেট করা আছে) এবং টিআইএমএসকে 1 সক্রিয় করা এটি পরিচালনা করা বন্ধ করতে পারে না। এটি না ঘটে তা নিশ্চিত করার জন্য আপনাকে টিওভি 1 টি পুনরায় সেট করতে হবে (এটি টিআইএফআর 1 তে 1 লিখে) happen সেখানকার অনিশ্চয়তা আমাকে ভাবতে পরিচালিত করে যে বিশ্বব্যাপী বিঘ্ন ঘুরিয়ে দেওয়া নিরাপদ পথ।
নিক গ্যামন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.