এম্বেড থাকা সিস্টেমে বিঘ্ন ব্যবহার করার সময় বৈশ্বিক চলক এড়ানো


13

কোনও এমবেডেড সিস্টেমের জন্য কোনও আইএসআর এবং বাকি প্রোগ্রামের মধ্যে যোগাযোগ কার্যকর করার একটি ভাল উপায় আছে যা বৈশ্বিক চলকগুলি এড়িয়ে চলে?

দেখে মনে হয় যে সাধারণ প্যাটার্নটিতে একটি বৈশ্বিক পরিবর্তনশীল হওয়া উচিত যা আইএসআর এবং বাকি প্রোগ্রামের মধ্যে ভাগ করা হয় এবং একটি পতাকা হিসাবে ব্যবহৃত হয়, তবে বিশ্বব্যাপী ভেরিয়েবলগুলির এই ব্যবহারটি আমার কাছে শস্যের বিপরীতে চলে। আমি avr-libc স্টাইল ISR গুলি ব্যবহার করে একটি সাধারণ উদাহরণ অন্তর্ভুক্ত করেছি:

volatile uint8_t flag;

int main() {
    ...

    if (flag == 1) {
        ...
    }
    ...
}

ISR(...) {
    ...
    flag = 1;
    ...
}

মূলত একটি স্কোপিংয়ের সমস্যাটি আমি কাছাকাছি দেখতে পাচ্ছি না; আইএসআর এবং প্রোগ্রামের বাকি উভয় দ্বারা অ্যাক্সেসযোগ্য কোনও ভেরিয়েবল অবশ্যই সহজাতভাবে বিশ্বব্যাপী হওয়া উচিত? এ সত্ত্বেও, আমি প্রায়শই লোকদের "বৈশ্বিক পরিবর্তনশীল" আইএসআর এবং প্রোগ্রামের বাকী অংশগুলির মধ্যে যোগাযোগ বাস্তবায়নের একটি উপায় "(জোর দেওয়া খনি) এর ধারায় জিনিস বলতে দেখেছি , যা বোঝায় যে অন্যান্য পদ্ধতি রয়েছে; অন্য পদ্ধতি আছে, তারা কি?


1
সম্পর্কিত:
এম্বেডড

1
এটি অগত্যা সত্য নয় যে বাকি সমস্ত প্রোগ্রামের অ্যাক্সেস থাকবে; আপনি যদি ভেরিয়েবলটিকে স্থির হিসাবে ঘোষণা করেন তবে কেবল যে ফাইলটিতে ভেরিয়েবল ঘোষিত হয়েছিল তা কেবল এটিই দেখতে পাবে। সম্পূর্ণ এক ফাইলের মধ্যে দৃশ্যমান ভেরিয়েবলগুলি পাওয়া মোটেই শক্ত নয়, তবে প্রোগ্রামের বাকী অংশ নয় এবং এটি সাহায্য করতে পারে।
ডিবস্কো

1
পাশে, পতাকা অবশ্যই অস্থির হিসাবে ঘোষণা করতে হবে, কারণ আপনি এটি ব্যবহার করছেন / সাধারণ প্রোগ্রাম প্রবাহের বাইরে পরিবর্তন করছেন। এটি সংকলকটিকে পতাকাটিতে কোনও পঠন / লেখার অনুকূলিতকরণ এবং প্রকৃত পঠন / লেখার ক্রিয়া সম্পাদন করতে বাধ্য করে।
পরের-হ্যাক

@ পরের হ্যাক হ্যাঁ এটি একেবারে সঠিক, দুঃখিত আমি খুব দ্রুত একটি উদাহরণ নিয়ে আসার চেষ্টা করছিলাম।

উত্তর:


18

এটি করার জন্য একটি ডি ফ্যাক্টো স্ট্যান্ডার্ড উপায় রয়েছে (সি প্রোগ্রামিং ধরে নিলে):

  • বাধা / আইএসআরগুলি নিম্ন-স্তরের এবং তাই কেবলমাত্র সেই হার্ডওয়্যার সম্পর্কিত ড্রাইভারের মধ্যে প্রয়োগ করা উচিত যা বাধা সৃষ্টি করে। এগুলি অন্য কোথাও অবস্থিত হওয়া উচিত নয় তবে সেই ড্রাইভারের ভিতরে।
  • আইএসআরের সাথে সমস্ত যোগাযোগ কেবল চালক এবং চালক দ্বারা সম্পন্ন হয়। প্রোগ্রামের অন্যান্য অংশগুলিতে যদি সেই তথ্যে অ্যাক্সেসের প্রয়োজন হয় তবে সেটার / গেটর ফাংশন বা অনুরূপ মাধ্যমে ড্রাইভারের কাছে এটির অনুরোধ করতে হবে।
  • আপনার "গ্লোবাল" ভেরিয়েবলগুলি ঘোষণা করা উচিত নয়। গ্লোবাল অর্থ বাহ্যিক সংযোগ সহ ফাইল স্কোপ ভেরিয়েবল। এটি হল: ভেরিয়েবলগুলি যা মূলশব্দ দিয়ে externবা কেবল ভুল করে ডাকা যেতে পারে ।
  • পরিবর্তে, ড্রাইভারের ভিতরে প্রাইভেট এনক্যাপসুলেশন জোর করার জন্য, ড্রাইভার এবং আইএসআরের মধ্যে ভাগ করা এই জাতীয় সমস্ত পরিবর্তনগুলি ঘোষণা করা হবে static। যেমন একটি পরিবর্তনশীল না বিশ্বব্যাপী কিন্তু ফাইল যেখানে এটি ঘোষিত হয় অবধি সীমিত।
  • সংকলক অপ্টিমাইজেশনের সমস্যাগুলি রোধ করতে, এই জাতীয় ভেরিয়েবলগুলি হিসাবে ঘোষণা করা উচিত volatile। দ্রষ্টব্য: এটি পারমাণবিক অ্যাক্সেস দেয় না বা পুনরায় প্রবেশের সমাধান করে না!
  • আইএসআর ভেরিয়েবলের কাছে লেখার ক্ষেত্রে চালকের ক্ষেত্রে প্রায়শই পুনরায় প্রবেশের কোনও প্রক্রিয়া প্রয়োজন। উদাহরণস্বরূপ: বিঘ্নিত অক্ষম, গ্লোবাল ইন্টারপ্যান্ট মাস্ক, সেমফোর / মিটেক্স বা গ্যারান্টিযুক্ত পারমাণবিক পঠন।

দ্রষ্টব্য: অন্য কোনও ফাইলে অবস্থিত ভেক্টর টেবিলটিতে রাখার জন্য আপনাকে একটি শিরোনামের মাধ্যমে আইএসআর ফাংশন প্রোটোটাইপটি প্রকাশ করতে হতে পারে। তবে যতক্ষণ না আপনি ডকুমেন্ট করেছেন যে এটি একটি বাধাগ্রস্ত এবং প্রোগ্রামের মাধ্যমে কল করা উচিত নয় ততক্ষণ এটি কোনও সমস্যা নয়।
লন্ডিন

আপনি কী বলবেন, যদি পাল্টা যুক্তিটি সেটার / ফাংশনগুলি পাওয়ার জন্য ব্যবহারকারীর বর্ধিত ওভারহেড (এবং অতিরিক্ত কোড) হত? আমি আমাদের 8 বিট এম্বেডড ডিভাইসগুলির জন্য কোড স্ট্যান্ডার্ডের কথা ভেবে নিজেই এটিকে ছাড়িয়ে যাচ্ছি।
Leroy105

2
@ Leroy105 সি ভাষা এখন অবধি অনন্তকালীন জন্য ইনলাইন ফাংশনকে সমর্থন করেছে। যদিও এর ব্যবহারও inlineঅপ্রচলিত হয়ে চলেছে, যেহেতু সংকলকগণ কোডটি অনুকূলকরণের ক্ষেত্রে স্মার্ট এবং স্মার্ট হন। আমি বলব যে ওভারহেড সম্পর্কে উদ্বিগ্ন হওয়াই "প্রাক-পরিপক্ক অপ্টিমাইজেশন" - বেশিরভাগ ক্ষেত্রে ওভারহেড কোনও ব্যাপার না, এটি মেশিন কোডে এমনকি উপস্থিত থাকলে।
লন্ডিন

2
বলা হচ্ছে, আইএসআর ড্রাইভার লেখার ক্ষেত্রে, সমস্ত প্রোগ্রামারদের প্রায় 80-90% (এখানে অত্যুক্তি করা হয় না) সবসময় তাদের মধ্যে কিছু ভুল হয়। ফলাফলটি সূক্ষ্ম বাগগুলি: ভুলভাবে সাফ হওয়া পতাকাগুলি, অনুপস্থিত উদ্বায়ী, বর্ণের পরিস্থিতি, লুসি রিয়েল-টাইম পারফরম্যান্স, স্ট্যাকের ওভারফ্লোগুলি ইত্যাদি থেকে ভুল সংকলক অপ্টিমাইজেশন ইত্যাদি the ড্রাইভারের ভিতরে আইএসআর সঠিকভাবে আবদ্ধ না হলে, এই জাতীয় সূক্ষ্ম বাগের সম্ভাবনা রয়েছে is আরও বেড়েছে। পেরিফেরিয়াল আগ্রহের বিষয়গুলি নিয়ে উদ্বিগ্ন হওয়ার আগে বাগ-ফ্রি-ড্রাইভার লেখার দিকে মনোনিবেশ করুন, যেমন সেটার / গেটাররা যদি ওভারহেডের একটি সামান্য বিট প্রবর্তন করে।
লন্ডিন

10
গ্লোবাল ভেরিয়েবলের এই ব্যবহারটি আমার কাছে শস্যের বিপরীতে

এটিই আসল সমস্যা। এটি পেতে।

এখন হাঁটু ঝাঁকুনিরা তাত্ক্ষণিকভাবে এটি কীভাবে অশুচি তা সম্পর্কে গর্জন করার আগে, আমাকে এটি কিছুটা যোগ্য করে তুলুন। অতিরিক্তভাবে বৈশ্বিক ভেরিয়েবলগুলি ব্যবহার করার ক্ষেত্রে অবশ্যই বিপদ রয়েছে। তবে, তারা দক্ষতা বৃদ্ধি করতে পারে যা কখনও কখনও ছোট সংস্থান-সীমিত সিস্টেমে গুরুত্বপূর্ণ।

মূলটি হ'ল আপনি কখন যুক্তিসঙ্গতভাবে সেগুলি ব্যবহার করতে পারেন এবং নিজেকে সমস্যার মধ্যে ফেলতে পারেন না সে সম্পর্কে ভাবনাটি হ'ল, বাগটি কেবল ঘটতে অপেক্ষা করছে। সর্বদা ট্রেড অফস রয়েছে। যদিও সাধারণত বিঘ্ন এবং ফোরগ্রাউন্ড কোড মধ্যে যোগাযোগ গ্লোবাল ভেরিয়েবল এড়ানো, একটি undertandable গাইডলাইন, এটা নেয়ার ধর্মের চরম সবচেয়ে অন্য নির্দেশিকাও মত, পাল্টা-উৎপাদনশীল হয়।

বিঘ্নিত এবং অগ্রভাগের কোডের মধ্যে তথ্য পাস করতে আমি মাঝে মাঝে বৈশ্বিক চলকগুলি ব্যবহার করি এমন কয়েকটি উদাহরণ হ'ল:

  1. সিস্টেম ক্লক বিঘ্নিত দ্বারা পরিচালিত ক্লক টিক কাউন্টারগুলি। আমার সাধারণত পর্যায়ক্রমিক ঘড়ি বাধা থাকে যা প্রতি 1 এমএসে চলে। এটি সিস্টেমে বিভিন্ন টাইমিংয়ের জন্য প্রায়শই কার্যকর। বাধা রুটিন থেকে এই তথ্যটি বের করার এক উপায় যেখানে সিস্টেমের বাকী অংশগুলি এটি ব্যবহার করতে পারে তা হ'ল একটি বিশ্বব্যাপী ক্লক টিক কাউন্টার রাখা। বাধা রুটিন প্রতিটি ঘড়ির টিককে কাউন্টার বাড়ায় incre অগ্রভাগের কোডটি যে কোনও সময় কাউন্টারটি পড়তে পারে। প্রায়শই আমি এটি 10 ​​এমএস, 100 এমএস এবং এমনকি 1 সেকেন্ডের টিকের জন্য করি।

    আমি নিশ্চিত করি যে 1 এমএস, 10 এমএস এবং 100 এমএস টিকগুলি একটি শব্দের আকারের যা একক পরমাণু ক্রিয়াকলাপে পড়া যায়। যদি উচ্চ স্তরের ভাষা ব্যবহার করা হয় তবে সংকলককে নিশ্চিত করে নিশ্চিত করুন যে এই ভেরিয়েবলগুলি তাত্পর্যপূর্ণভাবে পরিবর্তিত হতে পারে। সিতে, আপনি তাদের বাহ্যিক উদ্বায়ী ঘোষণা করেন , উদাহরণস্বরূপ। অবশ্যই এটি এমন কিছু যা একটি ডাবের মধ্যে চলে যায় ফাইল অন্তর্ভুক্ত করে, তাই আপনাকে প্রতিটি প্রকল্পের জন্য এটি মনে রাখার দরকার নেই।

    আমি মাঝে মাঝে 1 টি টিককে মোট সময় কাটানো কাউন্টারের কাউন্টার তৈরি করি, তাই 32 বিট প্রশস্ত করুন। আমি যে ছোট ছোট মাইক্রো ব্যবহার করি তার অনেকগুলি একক পারমাণবিক অপারেশনে এটি পড়া যায় না, যাতে এটি বিশ্বব্যাপী তৈরি হয় না। পরিবর্তে, একটি রুটিন সরবরাহ করা হয় যা মাল্টি-ওয়ার্ড মানটি পড়ে, পঠনের মধ্যে সম্ভাব্য আপডেটগুলি নিয়ে ডিল করে এবং ফলাফলটি দেয়।

    অবশ্যই ছোট 1 এমএস, 10 এমএস, ইত্যাদি টিক কাউন্টারগুলি পেতে রুটিনগুলি থাকতে পারে । যাইহোক, এটি সত্যিই আপনার পক্ষে খুব সামান্য কাজ করে, একটি শব্দ পড়ার জায়গায় প্রচুর নির্দেশনা যুক্ত করে এবং অন্য কল স্ট্যাকের অবস্থান ব্যবহার করে।

    ক্ষতি কী? আমি মনে করি যে কোনও ব্যক্তি টাইপো তৈরি করতে পারে যা দুর্ঘটনাক্রমে কাউন্টারগুলির মধ্যে একটিতে লিখিত হয়, যা সিস্টেমের অন্যান্য সময়গুলিকে বিশৃঙ্খলা করতে পারে। কাউন্টারে ইচ্ছাকৃতভাবে লেখার কোনও অর্থ নেই, সুতরাং এই ধরণের বাগটি টাইপের মতো অজান্তেই কিছু হওয়া দরকার। খুব অসম্ভব বলে মনে হচ্ছে। আমি প্রত্যাহার না যে কি কখনো ভাল 100 ছোট মাইক্রোকন্ট্রোলার প্রকল্পে ঘটছে।

  2. চূড়ান্ত ফিল্টার এবং অ্যা / ডি মান সমন্বয়। একটি সাধারণ জিনিস হ'ল এ / ডি থেকে বাধা রুটিন হ্যান্ডেল পঠন read আমি সাধারণত প্রয়োজনের তুলনায় অ্যানালগ মানগুলি দ্রুত পড়ি, তারপরে একটু লো-পাস ফিল্টারিং প্রয়োগ করি। প্রায়শই স্কেলিং এবং অফসেট থাকে যা প্রয়োগ হয়।

    উদাহরণস্বরূপ, 24 / ভি সরবরাহ পরিমাপ করতে A / D ভোল্টেজ বিভাজকের 0 থেকে 3 ভি আউটপুট পড়তে পারে। অনেকগুলি রিডিং কিছু ফিল্টারিংয়ের মাধ্যমে পরিচালিত হয়, তারপরে পরিমাপ করা হয় যাতে চূড়ান্ত মান মিলিভোল্টে থাকে। যদি সরবরাহ 24.015 ভি হয় তবে চূড়ান্ত মান 24015।

    সিস্টেমের বাকি অংশগুলি কেবল সরবরাহের ভোল্টেজকে নির্দেশ করে এমন একটি লাইভ আপডেটেড মান দেখায়। এটি ঠিক কখন আপডেট হয় তা জানেন না বা যত্নের প্রয়োজন নেই, বিশেষত যেহেতু এটি লো পাস ফিল্টার স্থায়ী সময়ের চেয়ে অনেক বেশি সময় আপডেট হয়।

    আবার, একটি ইন্টারফেস রুটিন ব্যবহার করা যেতে পারে তবে আপনি এটি থেকে খুব সামান্য উপকার পাবেন। আপনি যখনই বিদ্যুৎ সরবরাহের ভোল্টেজ প্রয়োজন তখন কেবল গ্লোবাল ভেরিয়েবলটি ব্যবহার করা সহজ। মনে রাখবেন সরলতা কেবল মেশিনের জন্য নয়, তবে সেই সরলতাটি মানে মানুষের ত্রুটির সম্ভাবনাও কম।


আমি আস্তে আস্তে থেরাপিতে যাচ্ছি, আমার কোডটি নিটপিক করার চেষ্টা করছিলাম। আমি ভেরিয়েবল অ্যাক্সেসকে সীমাবদ্ধ করার বিষয়ে লন্ডিনের দৃষ্টিভঙ্গিটি দেখতে পাচ্ছি, তবে আমি আমার আসল সিস্টেমগুলির দিকে তাকিয়ে দেখি এবং মনে করি এটি এমন একটি দূরবর্তী সম্ভাবনা যা কোনও ব্যক্তি প্রকৃতপক্ষে একটি সিস্টেমকে গুরুতর বৈশ্বিক পরিবর্তনশীলকে ঝুঁকিয়ে ফেলবে। গেটর / সেটার ফাংশনগুলি আপনাকে কেবলমাত্র একটি গ্লোবাল ব্যবহার করে ওভারহেডের জন্য ব্যয় করে এবং এগুলি গ্রহণ করা খুব সহজ প্রোগ্রাম ...
Leroy105

3
@ Leroy105 সমস্যাটি "সন্ত্রাসী" ইচ্ছাকৃতভাবে বৈশ্বিক পরিবর্তনশীলকে আপত্তিজনক নয়। বড় জায়গাগুলিতে নেমস্পেস দূষণ একটি সমস্যা হতে পারে, তবে এটি ভাল নামকরণের মাধ্যমে সমাধান করা যেতে পারে। না, আসল সমস্যাটি হ'ল প্রোগ্রামার হ'ল গ্লোবাল ভেরিয়েবলকে ইচ্ছাকৃতভাবে ব্যবহার করার চেষ্টা করছে তবে সঠিকভাবে তা করতে ব্যর্থ। হয় তারা সমস্ত আইএসআর সহ বিদ্যমান রেস কন্ডিশনের বিষয়টি বুঝতে না পারার কারণে বা বাধ্যতামূলক সুরক্ষা ব্যবস্থার বাস্তবায়নে গোলমাল করার কারণে বা কেবলমাত্র তারা সমস্ত কোডে গ্লোবাল ভেরিয়েবলের ব্যবহার স্পষ্ট করে দেয়, আঁটসাঁট মিলন তৈরি করে এবং অপঠনযোগ্য কোড
লন্ডিন

আপনার পয়েন্টগুলি বৈধ ওলিন, তবে এই উদাহরণগুলিতে প্রতিস্থাপন extern int ticks10msকরা inline int getTicks10ms()সংকলিত সমাবেশে একেবারেই কোনও পার্থক্য আনবে না, অন্যদিকে প্রোগ্রামের অন্যান্য অংশে দুর্ঘটনাক্রমে এর মান পরিবর্তন করা শক্ত হবে, এবং আপনাকে অনুমতি দেবে এই কলটিতে "হুক" করার উপায় (যেমন ইউনিট পরীক্ষার সময় সময়কে উপহাস করা, এই ভেরিয়েবলের অ্যাক্সেস লগ করতে বা যা কিছু) এমনকি যদি আপনি তর্ক করেন যে কোনও সান প্রোগ্রামার এই পরিবর্তনশীলটিকে শূন্যে পরিবর্তন করার সুযোগ দেয় তবে কোনও ইনলাইন গেটারের কোনও মূল্য নেই।
গ্রো

@ গ্রু: এটি কেবলমাত্র সত্য যদি আপনি এমন কোনও ভাষা ব্যবহার করছেন যা ইনলাইনিং ফাংশন সমর্থন করে, এবং এর অর্থ গ্রাহক ফাংশনটির সংজ্ঞাটি সবার কাছে দৃশ্যমান হওয়া দরকার। আসলে উচ্চ স্তরের ভাষা ব্যবহার করার সময়, আমি গেটর ফাংশনগুলি বেশি এবং গ্লোবাল ভেরিয়েবলগুলি কম ব্যবহার করি। সমাবেশে, গিটার ফাংশন নিয়ে বিরক্ত করার চেয়ে বৈশ্বিক চলকের মান হ'ল আরও অনেক সহজ।
অলিন ল্যাথ্রপ

অবশ্যই, আপনি যদি ইনলাইন করতে না পারেন, তবে পছন্দটি এত সহজ নয়। আমি বলতে চেয়েছিলাম যে ইনলাইনড ফাংশনগুলি (এবং অনেকগুলি প্রাক C99 সংকলক ইতিমধ্যে ইনলাইনিং এক্সটেনশানগুলিকে সমর্থন করে), পারফরম্যান্স প্রাপ্তিদের বিরুদ্ধে কোনও যুক্তি হতে পারে না। যুক্তিসঙ্গতভাবে অনুকূলিতকরণ সংকলক সহ, আপনার একই উত্পাদিত সমাবেশটি শেষ হওয়া উচিত।
গ্রো

2

যে কোনও বিশেষ বাধা বিশ্বব্যাপী সংস্থান হবে। কখনও কখনও, তবে, একই কোডটি বেশ কয়েকটি বিঘ্ন ভাগ করে নেওয়া কার্যকর হতে পারে। উদাহরণস্বরূপ, একটি সিস্টেমে বেশ কয়েকটি ইউআরটি থাকতে পারে, যার সবগুলিই অনুরূপ প্রেরণ / গ্রহণ যুক্তি ব্যবহার করা উচিত।

এটি হ্যান্ডেল করার জন্য একটি দুর্দান্ত পদ্ধতির মধ্যে হ'ল বিঘ্নিত হ্যান্ডলার দ্বারা ব্যবহৃত জিনিসগুলি, বা তাদের নির্দেশকগুলিকে কোনও কাঠামোগত বস্তুতে স্থাপন করা এবং তারপরে প্রকৃত হার্ডওয়্যার বিঘ্নিত হ্যান্ডলারগুলি এমন কিছু হতে পারে:

void UART1_handler(void) { uart_handler(&uart1_info); }
void UART2_handler(void) { uart_handler(&uart2_info); }
void UART3_handler(void) { uart_handler(&uart3_info); }

বস্তু uart1_info, uart2_infoইত্যাদি গ্লোবাল ভেরিয়েবল হতে পারে, কিন্তু তারা হবে শুধুমাত্র বিশ্বব্যাপী বিঘ্ন হ্যান্ডেলার দ্বারা ব্যবহৃত ভেরিয়েবল। হ্যান্ডলাররা যে সমস্ত স্পর্শ করতে চলেছে সেগুলি হ'ল within

মনে রাখবেন যে বাধা হ্যান্ডলার এবং প্রধান-লাইন কোড উভয়ই অ্যাক্সেস করেছে যা অবশ্যই যোগ্য হতে হবে volatilevolatileবাধাপ্রাপ্ত হ্যান্ডলার দ্বারা ব্যবহৃত সমস্ত কিছু হিসাবে কেবল ঘোষণা করা সহজ হতে পারে , তবে যদি কার্য সম্পাদন গুরুত্বপূর্ণ হয় তবে এমন কোনও কোড লিখতে চাইতে পারে যা অস্থায়ী মানগুলিতে তথ্য অনুলিপি করে, সেগুলি চালিত করে এবং তারপরে সেগুলি আবার লিখে দেয় writes উদাহরণস্বরূপ, লেখার পরিবর্তে:

if (foo->timer)
  foo->timer--;

লিখুন:

uint32_t was_timer;
was_timer = foo->timer;
if (was_timer)
{
  was_timer--;
  foo->timer = was_timer;
}

পূর্বের পদ্ধতির পড়া এবং বুঝতে সহজ হতে পারে তবে পরবর্তীকালের চেয়ে কম দক্ষ হবে। এটি উদ্বেগ কিনা তা আবেদনের উপর নির্ভর করে।


0

এখানে তিনটি ধারণা দেওয়া হয়েছে:

একক ফাইলে স্কোপ সীমাবদ্ধ করতে পতাকা পরিবর্তনশীলটিকে স্থির হিসাবে ঘোষণা করুন।

পতাকাটি ভেরিয়েবলকে ব্যক্তিগত করুন এবং পতাকা মানটি অ্যাক্সেস করতে গেটর এবং সেটার ফাংশনগুলি ব্যবহার করুন।

ফ্ল্যাগ ভেরিয়েবলের পরিবর্তে সিগফলের মতো সিগন্যালিং অবজেক্ট ব্যবহার করুন। আইএসআর সেমফোর সেট / পোস্ট করবে।


0

একটি বাধা (যেমন, ভেক্টর যা আপনার হ্যান্ডলারের দিকে নির্দেশ করে) হ'ল একটি বৈশ্বিক সংস্থান। সুতরাং আপনি স্ট্যাক বা গাদাতে কিছু পরিবর্তনশীল ব্যবহার করলেও:

volatile bool *flag;  // must be initialized before the interrupt is enabled

ISR(...) {
    *flag = true;
}

বা 'ভার্চুয়াল' ফাংশন সহ অবজেক্ট ভিত্তিক কোড:

HandlerObject *obj;

ISR(...) {
    obj->handler_function(obj);
}

… অন্য পদক্ষেপে পৌঁছানোর জন্য প্রথম ধাপে অবশ্যই একটি বাস্তব গ্লোবাল (বা কমপক্ষে স্থিতিশীল) পরিবর্তনশীল জড়িত থাকতে হবে।

এই সমস্ত প্রক্রিয়া একটি ইন্ডিয়ারেশন যুক্ত করে, তাই আপনি যদি বিঘ্নিত হ্যান্ডলারের বাইরে চক্রটি শেষ করতে চান তবে সাধারণত এটি করা হয় না।


আপনার পতাকাটি অস্থায়ী ইন্ট * হিসাবে ঘোষণা করা উচিত।
পরের-হ্যাক

0

আমি এই মুহুর্তে কর্টেক্স এম0 / এম 4 এর জন্য কোডিং করছি এবং আমরা সি ++ তে যে পদ্ধতিটি ব্যবহার করছি (সেখানে কোনও সি ++ ট্যাগ নেই, সুতরাং এই উত্তরটি অফ-টপিক হতে পারে) নীচে রয়েছে:

আমরা CInterruptVectorTableএমন একটি ক্লাস ব্যবহার করি যার মধ্যে সমস্ত বিঘ্নিত পরিষেবা রুটিন থাকে যা নিয়ামকের আসল বিঘ্নিত ভেক্টরে সঞ্চিত থাকে:

#pragma location = ".intvec"
extern "C" const intvec_elem __vector_table[] =
{
  { .__ptr = __sfe( "CSTACK" ) },           // 0x00
  __iar_program_start,                      // 0x04

  CInterruptVectorTable::IsrNMI,            // 0x08
  CInterruptVectorTable::IsrHardFault,      // 0x0C
  //[...]
}

ক্লাসটি CInterruptVectorTableবিঘ্নিত ভেক্টরগুলির বিমূর্ততা প্রয়োগ করে, তাই আপনি রানটাইম চলাকালীন বিঘ্নিত ভেক্টরগুলিতে বিভিন্ন ফাংশন বাঁধতে পারেন।

এই শ্রেণীর ইন্টারফেসটি দেখতে এই রকম:

class CInterruptVectorTable  {
public :
    typedef void (*IsrCallbackfunction_t)(void);                      

    enum InterruptId_t {
        INTERRUPT_ID_NMI,
        INTERRUPT_ID_HARDFAULT,
        //[...]
    };

    typedef struct InterruptVectorTable_t {
        IsrCallbackfunction_t IsrNMI;
        IsrCallbackfunction_t IsrHardFault;
        //[...]
    } InterruptVectorTable_t;

    typedef InterruptVectorTable_t* PinterruptVectorTable_t;


public :
    CInterruptVectorTable(void);
    void SetIsrCallbackfunction(const InterruptId_t& interruptID, const IsrCallbackfunction_t& isrCallbackFunction);

private :

    static void IsrStandard(void);

public :
    static void IsrNMI(void);
    static void IsrHardFault(void);
    //[...]

private :

    volatile InterruptVectorTable_t virtualVectorTable;
    static volatile CInterruptVectorTable* pThis;
};

আপনাকে ভেক্টর টেবিলের মধ্যে সঞ্চিত ফাংশনগুলি তৈরি করতে হবে staticকারণ thisভেক্টর টেবিল কোনও বস্তু নয় বলে নিয়ামক একটি- পয়েন্টার সরবরাহ করতে পারে না । সুতরাং সমস্যাটি পেতে আমাদের কাছে স্ট্যাটিক- pThisপয়েন্টার রয়েছে CInterruptVectorTable। স্থিতিশীল বাধা ফাংশনগুলির একটিতে প্রবেশ করার পরে, এটির pThisএকটি অবজেক্টের সদস্যদের অ্যাক্সেস পাওয়ার জন্য পয়েন্টারটি অ্যাক্সেস করতে পারে CInterruptVectorTable


এখন প্রোগ্রামে, আপনি SetIsrCallbackfunctionকোনও ফাংশনটিতে একটি ফাংশন পয়েন্টার সরবরাহ করতে ব্যবহার করতে পারেন staticযা যখন কোনও বাধা ঘটে তখন ডাকা হয় called পয়েন্টারগুলিতে সংরক্ষণ করা হয় InterruptVectorTable_t virtualVectorTable

এবং একটি বাধা ফাংশন বাস্তবায়ন দেখে মনে হচ্ছে:

void CInterruptVectorTable::IsrNMI(void) {
    pThis->virtualVectorTable.IsrNMI(); 
}

সুতরাং এটি staticঅন্য শ্রেণীর একটি পদ্ধতি কল করবে (যা হতে পারে private), যা এরপরে static thisসেই অবজেক্টের সদস্য-ভেরিয়েবলগুলিতে অ্যাক্সেস পেতে অন্য পয়েন্টার থাকতে পারে (কেবলমাত্র একটি)।

আমি অনুমান করি যে আপনি IInterruptHandlerঅবজেক্টগুলিতে পয়েন্টার পছন্দ এবং সঞ্চয় করতে এবং ইন্টারফেস করতে পারবেন , সুতরাং আপনাকে এই static thisসমস্ত শ্রেণিতে পয়েন্টার লাগবে না । (সম্ভবত আমরা আমাদের স্থাপত্যের পরবর্তী পুনরাবৃত্তিতে এটি চেষ্টা করি)

অন্য পদ্ধতিটি আমাদের পক্ষে ঠিক কাজ করে, কারণ কেবল বাধা হ্যান্ডলারের বাস্তবায়নের জন্য অনুমোদিত অবজেক্টগুলি static thisহ'ল হার্ডওয়্যার বিমূর্ততা স্তরটির অভ্যন্তর এবং আমাদের সাধারণত প্রতিটি হার্ডওয়্যার ব্লকের জন্য কেবল একটি অবজেক্ট থাকে তাই এটি পয়েন্টারগুলির সাথে কাজ করে সূক্ষ্মভাবে কাজ করে । এবং হার্ডওয়্যার বিমূর্ততা স্তর বিঘ্নগুলির জন্য আরও একটি বিমূর্ততা সরবরাহ করে, যার নাম ICallbackএটি ডিভাইস স্তরটিতে হার্ডওয়ারের উপরে প্রয়োগ করা হয়।


আপনি কি বিশ্বব্যাপী ডেটা অ্যাক্সেস করেন? নিশ্চিত যে আপনি এটি করেছেন তবে আপনি বেশিরভাগ প্রয়োজনীয় বিশ্বব্যাপী ডেটা- thisপয়েন্টার এবং বাধা ফাংশনগুলির মতো ব্যক্তিগত করতে পারেন ।

এটি বুলেটপ্রুফ নয়, এবং এটি ওভারহেড যুক্ত করে। আপনি এই পদ্ধতির ব্যবহার করে একটি আইও-লিংক স্ট্যাক প্রয়োগ করতে সংগ্রাম করবেন। তবে আপনি যদি সময়গুলির সাথে অত্যন্ত কঠোর না হন তবে এটি সর্বত্র থেকে অ্যাক্সেসযোগ্য গ্লোবাল ভেরিয়েবলগুলি ব্যবহার না করে মডিউলগুলিতে বিঘ্ন এবং যোগাযোগের একটি নমনীয় বিমূর্ততা পেতে বেশ ভাল কাজ করে।


1
"যাতে আপনি রানটাইম চলাকালীন বিঘ্নিত ভেক্টরগুলিতে বিভিন্ন ফাংশন বাঁধতে পারেন" এটি একটি খারাপ ধারণা বলে মনে হচ্ছে। প্রোগ্রামটির "সাইক্লোমেটিক জটিলতা" কেবল ছাদ দিয়ে যেতে হবে। সমস্ত ব্যবহারের ক্ষেত্রে সংমিশ্রণগুলি পরীক্ষা করতে হবে যাতে সময় বা স্ট্যাকের ব্যবহার দ্বন্দ্ব না হয়। খুব সীমিত উপযোগিতা আইএমও সহ কোনও বৈশিষ্ট্যের জন্য প্রচুর মাথা ব্যথা। (আপনার যদি কোনও বুটলোডার কেস না থাকে তবে এটি অন্য গল্প) সামগ্রিকভাবে এটি গন্ধযুক্ত মেটা প্রোগ্রামিং।
লন্ডিন

@ লন্ডিন আমি সত্যিই আপনার বক্তব্যটি দেখতে পাচ্ছি না। আমরা এটি বাঁধার জন্য ব্যবহার করি উদাহরণস্বরূপ, ডিএমএ এসপিআই-র বিপরীত হ্যান্ডলারের ডিএমএ বিঘ্নিত হয় এবং ডিএএমএ যদি এটি ইউআরটির জন্য ব্যবহৃত হয় তবে ইউআআআআরআরটি বাধা হ্যান্ডলারের কাছে ব্যবহৃত হয়। উভয় হ্যান্ডলারেরই পরীক্ষা করতে হবে, নিশ্চিত, তবে কোনও সমস্যা নয়। এবং এটি অবশ্যই মেটা প্রোগ্রামিংয়ের সাথে কিছু করার নেই।
আর্সেনাল

ডিএমএ একটি জিনিস, বাধা ভেক্টরদের রান-টাইম অ্যাসাইনমেন্ট পুরোপুরি অন্য কিছু। রান-টাইমে কোনও ডিএমএ ড্রাইভার সেটআপটি পরিবর্তনশীল হতে দেওয়া অর্থপূর্ণ। একটি ভেক্টর টেবিল, এত বেশি নয়।
লন্ডিন

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