اطلاعیه

Collapse
No announcement yet.

کاربرد و عملکرد دقیق ماکرو assert_param

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

    کاربرد و عملکرد دقیق ماکرو assert_param

    با سلام.
    در زبان سی و همچنین کتابخانه های نوشته شده برای میکروکنترلر های STM32 تکنیکی به کار میره با عنوان های مختلف که بنده کاربردش رو دقیقا درک نکردم چی هست.
    توی زبان سی با عبارت ()assert نوشته میشه و در یکی از کتابخونه های STM32آ‌ به صورت زیر تعریف شده:
    کد:
    /* #define USE_FULL_ASSERT  1 */
    
    /* Exported macro ------------------------------------------------------------*/
    #ifdef USE_FULL_ASSERT
    
    /**
     * @brief The assert_param macro is used for function's parameters check.
     * @param expr: If expr is false, it calls assert_failed function
     *  which reports the name of the source file and the source
     *  line number of the call that failed.
     *  If expr is true, it returns no value.
     * @retval None
     */
     #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
    /* Exported functions ------------------------------------------------------- */
     void assert_failed(uint8_t* file, uint32_t line);
    #else
     #define assert_param(expr) ((void)0)
    #endif /* USE_FULL_ASSERT */

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

    البته ماکرو رو به دو صورت تعریف کرده یکی در حالت full و دیگری معمولی. در حالت معمولی هیچ کاری انجام نمیده فقط اگه شرط صحیح بود مقدار هیچی رو برمیگردونه و اگه نبود هم چیزی براش تعریف نشده.

    این ماکرو که در حقیقت دستور پیش پردازنده هست چه کمکی به برنامه نویس میکنه که اینقدر فراگیر ازش استفاده شده؟
    با سپاس
    شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
    هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
    چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

    #2
    پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

    پاسخ هایی که در اینترنت به اونها برخورد کردم:
    کد:
    Assert can be your best friend. For example, if instead of:
    int
    foo(int x, int y)
    { /* Return some function of x and y. Remember, x needs
    to be between 5 and 10, and y must be between 15 and 150
    or this will segfault!! */
    ....
    }
    
    you write:
    int
    foo(int x, int y)
    {
    assert(x > 5 && x <=10);
    assert (y >=15 && y<150);
    ....
    }
    
    You get 2 major benefits.
    1) Removes the ambiguity inherent in the English description
    regarding whether the endpoints are inclusive,
    2) When some code is changed so that a caller is using
    the wrong arguments, you will be instantly aware of it
    when you run, instead of getting a random segfault and
    having to track down what caused it.
    
    Also, placing assertions makes it clear to the maintainer
    what the coder expected. Any time you expect something
    to be true, place an assertion. If it fails, you either have
    a coding error somewhere, or your expectation is wrong.
    Either is good to know.
    
    Assert is better than if for this type of thing, because it goes
    away when you compile your non-debug version. You can
    accomplish that with precompiler wrappers around your
    if statements, but it is aesthetically unappealing in most
    cases.
    شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
    هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
    چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

    دیدگاه


      #3
      پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

      دیاگنوز! (Diagnostics)
      این هدر فایل (assert.h) واسه کارهای دیباگینگ به کار میره. وقتی شما در حال دیباگینگ هستید و می خوایید مقدار یه عبارت رو چک کنید و ببینید که درسته یا نه از این تابع استفاده میکنید:


      کد:
      void assert(int expression)
      اگه بررسی که میشه 0(صفر)(false) باشه این تابع یه پیغام خطا رو نشون میده که شامل فایل سورس و خطی که توش مورد وجود داره، هستش. بعدش تابع abort هم فراخونده میشه که برنامه رو نگه میداره. مثل این:

      کد:
      assert(1 == 2);
      
      /* Might result in */
      
      Assertion failed: 1 == 2, file silly.c, line 15

      همین.

      دیدگاه


        #4
        پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

        بحث جالبی در این خصوص در یه فروم آورده شده بود که قسمت هایی رو بنده مطالعه کردم که برخی رو در زیر آورده شده :

        یک دستور پیش پردازنده است. بدین معنی که عبارتی که همواره باید صحیح باشد را بررسی می کند و در صورتی که عبارت از نظر منقطی false باشد هنگام دیباگ به برنامه نویس اطلاع می دهد.
        توضیحات کامل و دقیقی در لینک زیر آورده شده است:
        http://bytes.com/topic/c/answers/479154-how-does-assert-benefit-your-code-really

        در بررسی های انجام شده این معنا برداشت شد که این دستور فقط در شرایطی باید استفاده شود که یقین داریم که عبارت منطقی مورد بررسی همواره true است تا در صورت نقض هنگام کامپایل به برنامه نویس نقض آنرا اطلاع دهد.

        در مورد مزایای استفاده از این روش به جای استفاده از دستور پیش پردازنده ای if این آورده شده است که برنامه را خوانا تر می کند.
        باید دقت داشت که در موارد استفاده از این تابع باید دقت نمود. این ماکرو باید زمانی فراخوانی شود که یقین داریم که مقدار true باید برگردانده شود. در شرایطی که مثلا مانند کد زیر:
        کد:
        char * p = malloc(10);
        
        assert(p != NULL);

        امکان این خطا بلقوه وجود دارد و نباید از تابع assert استفاده شود. بلکه باید به صورت زیر نوشته شود:
        کد:
        char * p = malloc(10);
        
        if(NULL == p)
        {
        // Now what? It's all too easy to call abort() etc?
        }
        یعنی اگر این شرایط اتفاق افتاد برنامه باید تمهیداتی در نظر بگیرد.

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

        تحلیل های مفصلی در این خصوص در ادامه مطالب این سایت آورده شده است که در فرصت مناسب باید مطالعه و شوند
        شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
        هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
        چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

        دیدگاه


          #5
          پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

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

          ابزاری هست کمکی جهت توسعه کتابخانه ها و ابزارهای زنجیره ای نرم افزاری، مثل همین توابع CMSISآ‌ و یا کتابخانه های نوشته شده برای XMEGAآ‌ و ... .
          دوستان دیگه اگر تجربه ای دارن در این خصوص استفاده میکنیم.
          موفق باشید
          شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
          هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
          چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

          دیدگاه


            #6
            پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

            یه مثال کاربردی میتونه این باشه:
            یه کتابخونه کامل برای تایمر نوشته شده، برخی از تایمر ها چند تا قابلیت بیشتر از بقیه دارن. حالا اگه حین برنامه نویسی کد نویس به اشتباه قابلیتی رو از تایمر فراخونی کنه که در این تایمر وجود نداره، این سبب میشه برنامه وارد یه حالت نا خواسته بشه.

            برای جلوگیری از این مسئله در کتابخونه مربوط به تایمر قبل استفاده از قابلیت هایی از این دست اول بررسی می کنن که این قابلیت در تایمر اساسا وجود داره یا نه، اگه وجود داشته باشه کد اجرا میشه اگه نه به برنامه نویس اطلاع میده که قابلیت رو و یا نام تایمر رو اشتباه نوشته شده.

            اینکار به برنامه نویس کمک میکنه که از ایجاد حالات ناخواسته که پیگیری اونها گاهی میتونه خیلی پیچیده بشه جلوگیری کنه.
            شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
            هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
            چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

            دیدگاه


              #7
              پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

              من یه موضوعی تازه یادم اومد. یکی از مواردی که کاربرد خوب داره استفاده از Unit testingها هستش.
              این صفحه نمونه های مفیدی رو براتون ارائه میده:


              Unit Testing C Code

              دیدگاه


                #8
                پاسخ : کاربرد و عملکرد دقیق ماکرو assert_param

                خوب حالا چرا کانپایلر به این گیرو میده:

                .\mainpanel.axf: Error: L6218E: Undefined symbol assert_param (referred from misc.o).

                البته وقتی Firmware رو اد میکمی .
                از جمله ی رفتگان این راه دراز
                باز آمده ای کو که به ما گوید راز
                هان بر سر این دو راهه از روی نیاز
                چیزی نگذاری که نمی آیی باز

                دیدگاه

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