কীভাবে আরডুইনো সিরিয়াল বাফারকে ওভারফ্লো করে?


27

কীভাবে আরডুইনো সিরিয়াল বাফারকে ওভারফ্লো করে? এটি কি সর্বাধিক আগত ডেটা ফেলে দেয় বা পুরানো? বাফার কয়টি বাইট ধরে রাখতে পারে?

serial 

উত্তর:


13

হার্ডওয়্যার সিরিয়াল পোর্টগুলি জন্য আপনি দেখতে পাবেন HardwareSerial.cpp যে বাফারের আকার নির্দিষ্ট এভিআর উপলব্ধ RAM- র পরিমাণ উপর নির্ভর করে আলাদা হয়:

#if (RAMEND < 1000)
    #define SERIAL_BUFFER_SIZE 16
#else
    #define SERIAL_BUFFER_SIZE 64
#endif

একটি সফ্টওয়্যার সিরিয়াল পোর্টের জন্য SoftwareSerial.h রিসিভার বাফারের আকার _SS_MAX_RX_BUFF64 বাইট হিসাবে সংজ্ঞায়িত করা হয়। উভয় ক্ষেত্রেই এটি সম্পূর্ণ হওয়ার পরে কাতারে প্রাপ্ত ডেটা sertোকানোর চেষ্টা বন্ধ করে দেয়, সুতরাং আপনি কীভাবে সারি থেকে ডেটা পুনরুদ্ধার করছেন তার উপর নির্ভর করে আপনি পুরানো এবং নতুন ডেটাতে মিশ্রণ পেতে পারেন।

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


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

আমি কেবলমাত্র সমস্ত কোডটি দেখেছি (আন্ডার / usr / শেয়ার / আরডুইনো / হার্ডওয়্যার / আরডুইনো / কোর / আরডুইনো / হার্ডওয়্যারসার্ ial.cpp) এবং আপনি এখানে কী লিখেছেন তা নিশ্চিত করতে পারি। কেবলমাত্র আমি যুক্ত করব যেহেতু এসআরএএম 2K (র‌্যাম্যান্ড> 1000) হয় তবে যে বিবৃতিটি সর্বদা ন্যানো বা ইউনোতে 16 এর চেয়ে 64 ব্যবহার করবে। সুতরাং কেউ যদি রিং বাফার আকারটি প্রসারিত করতে চায় তবে এটি পরিবর্তনের জায়গা হবে
এসডসোলার

5

গ্রহণ

আপনি হার্ডওয়্যারশিয়ারের উত্স থেকে দেখতে পাচ্ছেন যে যদি আগত বাইটটি রিং বাফারটি পূর্ণ দেখতে পায় এটি বাতিল করা হয়:

inline void store_char(unsigned char c, ring_buffer *buffer)
{
  int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != buffer->tail) {
    buffer->buffer[buffer->head] = c;
    buffer->head = i;
  }
}

আমি এই ধারণাটি পেয়েছি যে আমি যদি আরডুইনোতে ডেটা প্রেরণ করি এবং আরডুইনো সাইডে ডেটার একটি সক্রিয় "চালক" না রাখি তবে যদি বাফারে ফিট করার মতো আরও ডেটা আসে তবে তা বাতিল হয়ে যাবে। আপনি কি তা নিশ্চিত করতে পারবেন?

হ্যাঁ তা ফেলে দেওয়া হবে। আপনার নিজের প্রয়োগ না করা হলে কোনও সফ্টওয়্যার বা হার্ডওয়্যার ফ্লো নিয়ন্ত্রণ নেই।

তবে একটি 64৪-বাইট বাফার এবং 9600 বাউডে ডেটা পাওয়ার সাথে সাথে আপনি প্রতি 1.04 এমএসে একটি বাইট পাবেন এবং এভাবে বাফারটি পূরণ করতে 66.6 এমএস লাগবে takes একটি 16 মেগাহার্টজ প্রসেসরে আপনার বাফারটি যথেষ্ট পরিমাণে পূরণ হয় না যা এটি পূরণ করে না। আপনাকে এখনই যা করতে হবে তা হ'ল হার্ডওয়্যারশিরাল বাফার থেকে ডেটাটি আপনার নিজের দিকে সরিয়ে নেওয়া, যদি আপনি এখনই এটি প্রক্রিয়া করতে না চান।

আপনি #if (RAMEND < 1000)চেক থেকে দেখতে পারবেন যে র‌্যামের 1000+ বাইট সহ প্রসেসরগুলি 64-বাইট বাফার পায়, এতে র‌্যাম কম 16-বাইট বাফার পাবে।


পাঠানো হচ্ছে

আপনি যে ডেটা লেখেন সেটি একই আকারের বাফারে (16 বা 64 বাইট) স্থাপন করা হয়। প্রেরণের ক্ষেত্রে যদি বাফার কোডগুলি "ব্লকগুলি" পূরণ করে যাতে সিরিয়াল বন্দরটি পরবর্তী বাইটটি প্রেরণ করার জন্য একটি বাধাগুলির জন্য অপেক্ষা করে।

যদি বাধা বন্ধ করা হয় তবে এটি কখনই ঘটবে না, সুতরাং আপনি কোনও বিঘ্নিত পরিষেবা রুটিনের ভিতরে সিরিয়াল প্রিন্টগুলি করবেন না


আমি বিশ্বাস করি আপনি একটি মাত্রার অর্ডার দ্বারা বন্ধ আছেন: 9600 বাউডে, আপনি প্রতি প্রতি 0.1 ডলারে একটি বাইট পাবেন, তাই এটি বাফারটি পূরণ করতে 6.6 এমএস লাগবে।
এরিক ডাণ্ড

1
9600 বাউডে আপনি প্রতি সেকেন্ডে 9600 বিট পান । যেহেতু প্রতিটি বাইট 10 বিট হয় (8 ডেটা + 1 স্টার্ট বিট + 1 স্টপ বিট) তবে আপনি প্রতি সেকেন্ডে 960 বাইট পাবেন। 1/960 = 0.001042 s- এটি প্রতি 1.04 এমএসে এক বাইট।
নিক গ্যামন

আহ, অবশ্যই বাইটস না! সংশোধনীর জন্য ধন্যবাদ.
এরিক দন্ড

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

হ্যাঁ, প্রেরণকারী বাফার আকারটি এই দৃশ্যে কিছু আসবে না। একটি ছোট বাফার প্রেরণটি কমিয়ে দেবে (সামান্য) তবে আপনি যদি দীর্ঘতর বিলম্ব করছেন তবে যাইহোক আপনি যত্ন করবেন না।
নিক গ্যামন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.