اطلاعیه

Collapse
No announcement yet.

سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

Collapse
این موضوع برجسته شده است.
X
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    #76
    پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

    با تشکر از همه دوستان مطالبی که گفته شد همه جالب و مفید بود اما تکراری چون تو کتابهایی که توبازار هست در مورد آرم اشاره ای شده بهشون یه سوال داشتم میشه یکی بگه ما میخوایم یه سیستم عامل رو روی بوردمون که خودمون هم طراحی کردیم و ساختیم پورت کنیم دقیقا چه جوریه تو میکرو چی بنویسیم سیستم عامل رو تو حافظه sd/mmcبریزیم کلا عملیش چه شکلیه تو نت سرچ کردم چیز کمی گیرم اومد اگه میشه یکم راهنمایی کنین

    دیدگاه


      #77
      پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

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

      دیدگاه


        #78
        پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

        بیخیال آقا رضا! خون خودتو کثیف نکن!
        من که دیگه عادت کردم به اینجور طعنه ها! :mrgreen: تو یه فروم دیگه با پیغام خصوصی، اینجام که که علنا ...

        یه سری هستن که چشم دیدن یادگیری و پیشرفت بقیه رو ندارن. این بنده خدام فکرکرده اینطوری می تونه انرژی منفی بده

        اتفاقا تصمیم گرفتم این تاپیک کامل کنم. چندتا مطلب مهم مونده که اونام با کمک آقا رضا مطرح می کنیم.

        ایشون هم اگه دوست داشت کتابشو معرفی کنه همه استفاده کنیم...
        https://www.linkedin.com/in/mohammadhosseini69

        http://zakhar.blog.ir

        دیدگاه


          #79
          پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

          مدیریت منابع و کنترل همزمانی تسک ها با سمافور (semaphore)

          سلام!

          همونطور که می دونید، امکانات و منابع تو هر سیستمی از نظر تعداد و ظرفیت محدودیت دارن اما تعداد تسک هایی که تقاضای استفاده از این منابع رو دارن زیاد. در قالب یک سیستم عامل، تعدادی تسک داریم که همزمان اجرا میشن. ما از روند اجرای این تسک ها بطور دقیق خبر نداریم. هر لحظه ممکنه یکی از تسک ها بخواد با یکی از منابع سیستم کار کنه. مشکل وقتی پیش میاد که در یک لحظه تعداد تسک های درخواست دهنده برای یک منبع، بیشتر از ظرفیت اون باشه. مثلا فرض کنید از یه منبع (مثل پورت خروجی) 2 تا داریم و 3 تا تسک هم هست که تو قسمتی از اجراشون به این منبع (یه پورت خروجی) احتیاج دارن. سوال اینه که چیکار کنیم که وقتی هر دو نمونه این منبع، توسط دو تسک اشغال هستن، تسک سوم مثل ... (بلا نسبت دو تسک دیگه!) نپره وسط. چیکار کنیم که تسک سوم منتظر بمونه تا منبع آزاد بشه و بعد به کارش ادامه بده. دقت کنید همونطور که تا حالا تو سیستم عامل از روش سرکشی استفاده نکردیم، اینجام نمی خوایم این کارو بکنیم. خود سیستم عامل باید مدیریت این کارها رو بعهده بگیره تا وقت پردازنده هدر نره.

          شخصیت اول این پست، سمافور، حلال مشکلات همزمانی!

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

          سمافور با تایپ OS_SEM تعریف و توسط تابع os_sem_init مقداردهی اولیه میشه.

          #include <AT91SAM7X256.h>
          #include <rtl.h>

          OS_SEM semaphore1;
          __task void task1(void);
          __task void task2(void);
          __task void task3(void);

          int main()
          {
          *AT91C_PIOB_PER = (1 << 19) | (1 << 20) | (1 << 21);
          *AT91C_PIOB_OER = (1 << 19) | (1 << 20) | (1 << 21);

          os_sys_init(task1);

          while(1){}
          return 0;
          }

          __task void task1(void)
          {
          int i = 0;
          os_sem_init (semaphore1, 1);

          os_tsk_create(task2, 1);
          os_tsk_create(task3, 1);

          while(1){
          os_sem_wait (semaphore1, 0xffff);
          *AT91C_PIOB_SODR = (1 << 19); //Set
          for (i = 0; i < 0x8ffff; i++); //Process
          *AT91C_PIOB_CODR = (1 << 19); //Clear
          os_sem_send (semaphore1);
          }
          }

          __task void task2(void)
          {
          int i = 0;
          while(1){
          os_sem_wait (semaphore1, 0xffff);
          *AT91C_PIOB_SODR = (1 << 20); //Set
          for (i = 0; i < 0x8ffff; i++); //Process
          *AT91C_PIOB_CODR = (1 << 20); //Clear
          os_sem_send (semaphore1);
          }
          }

          __task void task3(void)
          {
          int i = 0;
          while(1){
          os_sem_wait (semaphore1, 0xffff);
          *AT91C_PIOB_SODR = (1 << 21); //Set
          for (i = 0; i < 0x8ffff; i++); //Process
          *AT91C_PIOB_CODR = (1 << 21); //Clear
          os_sem_send (semaphore1);
          }
          }

          semaphore1 با مقدار اولیه 1 برای شمارنده تعریف شده. یعنی از منبعی فقط یک نمونه داریم.
          os_sem_wait تقاضای دسترسی به منبع رو میده. در صورتی که شمارنده سمافور صفر نباشه (token برای گرفتن موجود باشه) از شمارنده سمافور یکی کم میشه (تسک یه token میگیره) و کار خودش رو با منبع شروع میکنه. پارامتر دوم این تابع زمان انتظار برای حالتی که منبع موجود نباشه. (همونطور که می دونین در صورتی که 0xFFFF باشه یعنی زمان انتظار بی نهایت). os_sem_send شمارنده سمافورو یکی زیاد می کنه (token رو پس میده). چون مقدار اولیه این سمافور 1 هست، پس بطور همزمان فقط یک تسک می تونه بین wait و send در حال اجرا باشه (منبع رو در اختیار بگیره). برای اینکه ببینیم کدوم تسک، تنها token این سمافور رو در اختیار داره، هر کدوم یکی از پین های خروجی رو یک میکنن. برنامه رو اجرا کنین و ببینین.
          مقدار اولیه سمافورو 2 کنین و دوباره اجرا کنین...

          سمافور فقط برای مدیریت منابع استفاده نمیشه. کلا برای کنترل همزمانی و محدود کردن تسک ها کاربرد داره.
          منظور از منبع هم هرچیزی می تونه باشه... یکم فکر کنید نزدیک افطار چیزی به ذهنم نمیرسه! :mrgreen:
          https://www.linkedin.com/in/mohammadhosseini69

          http://zakhar.blog.ir

          دیدگاه


            #80
            پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

            با اجازه آقای حسینی؛

            اصولا موارد همزمانی و کنترل منابع در چند تا سیستم عاملی که دیدم مبتنی بر سه منطق کلی کار میکنه:

            1- حق تعلق
            2- در دسترس بودن
            3- اطلاع از وجود یک شرط

            در ویندوز به مواردی که مشخصا برای کار روی موارد همزمانی بین تسک های متفاوت کار میکنن و مورد استفاده دیگه ای ندارن synchronization object گفته میشه. گرچه در بعضی سیستم عامل ها موارد متعدد دیگه ای وجود داره که میتونن برای ایجاد همزمانی بین تسک ها استفاده بشن.

            اما مسئله!
            اصلا این همزمانی چیه؟

            یک سیستم بطور کلی اعم از سخت افزاری یا نرم افزاری بودنش دارای یک سری منابع منحصر بفرد هست. این منابع میتونه شامل خود هسته پردازشی سیستم؛ پورت سریال؛ حافظه رم سیستم و یا حتی یک تابع باشه. معمولا این منابع دارای محدودیتی هستن که نمیتونن در یک زمان به دو تسک متفاوت سرویس بدن. یعنی بهتر بگیم هر کدوم از این منابع بایستی در وضعیتی مثل A باشن که یک تسک بتونه شروع به استفاده از اونها بکنه. اما مادامی که این تسک مشغول دسترسی به اون منبع هست؛ وضعیت کاری اون منبع دیگه A نیست. یا معلوم نیست که باشه. در این حالت اگر تسک دیگه ای بخواد به همین منبع دسترسی پیدا کنه باید منتظر بمونه که تسک اول منبع رو به حالت A برگردونه و اطمینان بده که دیگه منبع رو به حالتی غیر از A نمیبره تا اون بتونه کارشو شروع کنه. این یک موردی هست که بایستی تسک ها برای دسترسی به یک منبع هماهنگ بشن. و چون این موارد موقعی پیش میاد که دو یا چند تسک میخوان در حین کار همدیگه روی یک منبع دسترسی پیدا کنن اصطلاحا میگیم اینا در استفاده از یک منبع واحد بطور همزمان اقدام کردن.

            برای رفع این مشکل کلیه منطق های دسترسی به یک منبع به یکی یا ترکیبی از سه موردی که قبلا عرض کردم شکسته میشن.

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

            1- مورد تعلق:
            هر تسک باید انتظار داشته باشه مادامی که به یک منبع دسترسی داره تسک دیگه ای مزاحم کارش نمیشه.
            مثلا فرض کنین میخواییم یک تابع رو صدا کنیم. این تابع ممکنه هر کاری کنه. تابع رو هم فرض گرفتم تا خیال نکنین الزاما بایستی یک منبع سخت افزاری باشه. مثلا قراره یک محاسبه ای انجام بده. که بر اساس یک سری متغیر ایستا کار میکنه. (متغیر های منحصر بفرد).

            مثلا کد زیر رو در نظر بگیرین:

            int my_func(int a, int b)
            {
            static int result;

            result = a + b;

            return result;
            }


            درسته این کد مزخرفیه اما قصد و غرض هایی در کاره!

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


            my_func:
            @1 load from [a]
            @2 load from [b]
            @3 add
            @4 store to [result]
            @5 ret [result]



            ....

            دیدگاه


              #81
              پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

              ....
              میدونیم که:
              1- دستورالعمل های ماشین وقفه پذیر نیستن. یعنی یک وقفه بعد از اجرای یک دستور میتونه پردازش بشه. نه وسط اجراش.
              2- زمانبندی تسک ها بر اساس وقفه تایمر هست که چون وقفه هست بین اجرای دو دستور ماشین اجرا میشه.
              3- در حین اجرای کد چه وقت وقفه تایمر اتفاق میفته؟ نمیدونیم! کجای کد هستیم؟ اونم نمیدونیم!

              فرض کنیم تسک اول این کد رو برای اعداد 3 و 4 استفاده میکنه و منتظره عدد 7 رو به عنوان نتیجه داشته باشه.
              تسک دوم در زمان اجرای بین دستور 4 و 5 اجرا میشه و همین تابع رو با مقادیر 1 و 2 صدا میکنه. کد اجرا میشه و نتیجه 3 رو بر میگردونه. این تابع به کار خودش ادامه میده تا دوباره نوبت اجرای تسک 1 بشه. تسک 1 چه مقداری رو میگیره؟ مسلما 7 نیست. چون ادامه کار یعنی دستور 5 باید اجرا بشه و مقدار متغیر result رو برگردونه. این متغیر توسط تسک 2 برابر با 3 شده. یعنی نتیجه میگیریم که تسک 1 دیده که:
              3 + 4 = 3

              چکار باید کرد؟

              این کد رو اینجوری مینویسیم:

              static volatile int access_permission = 0;

              int my_func(int a, int b)
              {
              static int result;
              int tmp;

              while(access_permission==0) //critical part
              continue; //critical part
              access_permission = 1; //critical part

              result = a + b;

              tmp = result;

              access_permission = 0;

              return tmp;
              }


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


              OS_MUT access_permission;

              void start_use_my_func(void)
              {
              os_mut_init( access_pemission );
              }


              int my_func(int a, int b)
              {
              static int result;
              int tmp;

              os_mut_wait( access_permission, 0xffff );

              result = a + b;

              tmp = result;

              os_mut_release(access_permission);

              return tmp;
              }


              اینجا دیگه وقتی تلف نمیشه.
              .....
              بقیه اش طلبتون.

              دیدگاه


                #82
                پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                با تشکر از آقا رضا. عجب تاپیک آکادمیکی شد!

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

                task1 اجرا میشه و منبعی به نام R رو توسط مکانیسم سمافور در اختیار میگیره. در همین حال که task1 منبع R رو در اختیار داره، شرایطی پیش میاد که task3 با اولویت بالاتر آماده اجرا میشه. خب سیستم task1 رو کنار میذاره و task3 اجرا میشه. این تسک در حین اجرای خودش، به منبع R احتیاج داره و توسط سمافور اعلام درخواست میکنه. اما چون R در اختیار task1 هست، task3 به حالت معلق میره و task1 اجرا میشه. خب تا اینجا چاره ای نیست. task1 که اولویت پایین تری داره باید کارش رو با منبع R تموم کنه تا بشه این منبع رو در اختیار task3 گذاشت. حالا فرض کنید قبل از اینکه کار task1 با منبع R تموم بشه، یه تسک دیگه هم بنام task2 با اولیت برابر task1 از راه برسه. خب چه اتفاقی می افته؟ task3 که نمی تونه اجرا بشه. میمونه task1 و task2 با اولویت برابر. بنابراین زمان پردازش بین این دوتا تقسیم میشه! و این برای یه سیستم بی درنگ یا Realtime یعنی فاجعه!! چون task3 با اولویت بالاتر منتظر تا منبع رو در اختیار بگیره. سیستم نباید به task2 زمان پردازش بده. باید سریعتر کار task1 با منبع تموم بشه. از اون بدتر اینه که اولویت task2 بین task1 و task3 باشه. دیگه سیستم task1 رو هم ول میکنه میره سراغ اجرای تمام و کمال task2 تا تموم بشه (اینجاست که کاربر کفری میشه!) بعد برگرده سراغ task1 و بعد (اگه سیستمی باقی مونده بود!) بره برای اجرای task3!
                کد زیر رو ببینین. اول خودتون بررسی کنید که چه اتفاقی می افته. بعد اجراش کنید تا ببینین با چه بی شرمی سیستم، جناب task3 روکنار میزنه و سر تعظیم به task2 فرو میاره!!

                __task void task1(void) //priority = 1
                {
                int i = 0, j = 0;
                os_sem_init (semaphore1, 1);

                os_sem_wait (semaphore1, 0xffff);
                os_tsk_create(task2, 2);
                os_tsk_create(task3, 3); //high priority

                for (j = 0; j < 3; j++){
                *AT91C_PIOB_SODR = (1 << 19); //Set
                for (i = 0; i < 0x8ffff; i++); //Process
                *AT91C_PIOB_CODR = (1 << 19); //Clear
                for (i = 0; i < 0x8ffff; i++); //Process
                }
                os_sem_send (semaphore1);
                os_tsk_delete_self();
                }

                __task void task2(void)
                {
                int i = 0, j = 0;
                for (j = 0; j < 3; j++){
                *AT91C_PIOB_SODR = (1 << 20); //Set
                for (i = 0; i < 0x8ffff; i++); //Process
                *AT91C_PIOB_CODR = (1 << 20); //Clear
                for (i = 0; i < 0x8ffff; i++); //Process
                }
                os_tsk_delete_self();
                }

                __task void task3(void)
                {

                os_sem_wait (semaphore1, 0xffff);
                *AT91C_PIOB_SODR = (1 << 21); //Set
                os_sem_send (semaphore1);
                os_tsk_delete_self();
                }

                نیازی به اشک ریختن نیست! سوپرمن این پست، جناب MutEx این مشکل رو که وارونگی اولویت نام داره حل میکنه.
                mutex مثل سمافور با این دوتا فرق.
                اولا که فقط یک توکن داره. به عبارت دیگه اصلا اون شمارنده سمافور رو دیگه نداره. فقط می تونه به یک تسک اجازه اجرا بده.
                اما فرق اصلی تو مکانیسمی هست که توسط mutex احرا میشه به نام وراثت اولویت! وقتی تسکی با mutex درخواست منبعی رو میکنه که در اختیار تسک دیگه ای با اولویت پایین تر هست، موقتا اولویت تسک دارنده منبع، بالاتر از این تسک جدید میاد تا اجرای خودش رو بدون مزاحمت تسک های دیگه ادامه بده. همین! کد زیر حرفی برای گفتن نمیذاره!

                OS_MUT mutex1;

                __task void task1(void) //priority = 1
                {
                int i = 0, j = 0;
                os_mut_init (mutex1);
                os_mut_wait (mutex1, 0xffff); //get mutex
                os_tsk_create(task2, 2);
                os_tsk_create(task3, 3); //high priority

                for (j = 0; j < 3; j++){
                *AT91C_PIOB_SODR = (1 << 19); //Set
                for (i = 0; i < 0x8ffff; i++); //Process
                *AT91C_PIOB_CODR = (1 << 19); //Clear
                for (i = 0; i < 0x8ffff; i++); //Process
                }
                os_mut_release (mutex1); //release
                os_tsk_delete_self();
                }

                __task void task2(void)
                {
                int i = 0, j = 0;
                for (j = 0; j < 3; j++){
                *AT91C_PIOB_SODR = (1 << 20); //Set
                for (i = 0; i < 0x8ffff; i++); //Process
                *AT91C_PIOB_CODR = (1 << 20); //Clear
                for (i = 0; i < 0x8ffff; i++); //Process
                }
                os_tsk_delete_self();
                }

                __task void task3(void)
                {
                os_mut_wait (mutex1, 0xffff); //get mutex
                *AT91C_PIOB_SODR = (1 << 21); //Set
                os_mut_release (mutex1); //release
                os_tsk_delete_self();
                }

                https://www.linkedin.com/in/mohammadhosseini69

                http://zakhar.blog.ir

                دیدگاه


                  #83
                  پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                  اولا ببخشید من عادت دارم از آخر به اول بیام! بخاطر همین از mutex شروع کردم.
                  ادامه:

                  مورد بعدی مسئله در دسترس بودن یک منبع برای انجام کاری هست. راسیتش کلی زور زدم لغت دیگه ای به نظرم نیومد. بذارین این رو با ذکر یک مثال شروع کنم. فرض کنیم یک تسک داریم که قراره روی داده های دریافتی از پورت سریال عملی انجام بده. مهمترین مسئله در اینجا اطلاع تسک از وجود بایت یا بایتهایی برای پردازش هست. اما از اونجایی که ما نمیدونم کی و چند بایت آماده پردازش شده استفاده از مکانیسم های معمول عملا وقت تلف کردنه. مثلا فرض کنید در حالت عادی عادت داریم اینجوری کار کنیم:


                  void UartTask(void)
                  {
                  for( ; ; )
                  {
                  if( !data_ready_to_be_processed )
                  continue;
                  get data
                  process data
                  }
                  }


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

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

                  دیگه خوابم گرفته... اینم برای اینکه زیاد آکادمیک نشه!!

                  دیدگاه


                    #84
                    پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

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

                    یه سری هستن که چشم دیدن یادگیری و پیشرفت بقیه رو ندارن. این بنده خدام فکرکرده اینطوری می تونه انرژی منفی بده

                    اتفاقا تصمیم گرفتم این تاپیک کامل کنم. چندتا مطلب مهم مونده که اونام با کمک آقا رضا مطرح می کنیم.

                    ایشون هم اگه دوست داشت کتابشو معرفی کنه همه استفاده کنیم...
                    راستی کتاب هم یکی arm کاوه فراغی چاپ جدیدش مال نشر علوم یکی هم یه کتاب که خیلی قطرش زیاده و مربوط cortex هست و اسم نویسنده یادم رفته ودر مورد خود سیستم عامل هم کرنل های بی درنگ برای آقای شکاری زاده
                    با تشکر

                    دیدگاه


                      #85
                      پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

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

                      دیدگاه


                        #86
                        پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                        آیا سیستم عامل rtx توانایی این رو داره که یه برنامه رو از روی یه mmc بخونه و اجرا کنه؟
                        اگر منظورتون ایجاد امکانی برای دسترسی به mmc باشه که آره.
                        اما اگر واقعا اون چیزی رو که ماها معمولا روی ویندوز و داس باهاش سروکار داشتیم یعنی program loader داشته باشه که خیر.
                        چون مسئله فقط بار کردن برنامه در حافظه به تنهایی مهم نیست. ایجاد ارتباط بین اجزای برنامه با اجزاء سیستم عامل و برنامه های دیگه هم یکی از ارکان یک loader هست که اینجا من ردی ازش ندیدم.
                        مثلا مسئله relocation ها رو یک loader باید بتونه مدیریت کنه و رفعش کنه که این خودش کلی کاره.

                        اما اگه دوست داشته باشین میتونین بجای این مثلا سیستم عامل از چیزایی مثل Windows CE روی پلتفرم های بزرگ استفاده کنین. مثلا یک mini2440 یا mini6410.

                        اما باز اگه بخوایین از همین سیستم بهره ببرین و روی یک سیستمی مثل آرم 7 کار کنین تنها راهی که بنظرم میرسه استفاده از یک سری زبونهایی مثل جاوا روی این تیپ سیستمها هست.

                        دیدگاه


                          #87
                          پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                          با سلام و احترام

                          از آقای حسینی و آقای آقازاده بابت آموزشآ‌های خوب و خالصانشون واقعا تشکر و قدردانی می کنم.

                          من تموم برنامه و مطالب تاپیکآ‌های صفحات 1تا 4 رو کامل مطالعه و اجرا کردم و مشکلی نداشتم. اما تاپیکی که در مورد semaphore بودو چندین بار خوندم برنامه هاشم اجرا کردم. حتی یه چند تا منبع دیگه هم خوندم تا کامل متوجه بشم ولی هنوز توی به کار گیری اون مشکل دارم. یعنی متوجه نمیشم چطوری باید از اون استفاده کرد؟ یا دقیقا این تابع کی به کارمون میاد؟ ما قبلا دستور os_evt_wait رو داشتیم. نمیشه به جای semaphore از اون استفاده کنیم؟

                          موفق باشید

                          دیدگاه


                            #88
                            پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                            متاسفانه تفهیم مورد استفاده از این موضوعات بدون استفاده از یک مثال جامع کار آسونی نیست. و با تاسف بیشتر من امروز کاری برام پیش اومده و جایی باید برم که احتمالا تا 10 روزی به اینترنت دسترسی ندارم.

                            اما بذارین یک مثال کوچیک بزنم.

                            یک برنامه داریم که از روی پورت سریال اطلاعاتی رو میگیره و در یک بافر ذخیره میکنه. همزمان تسکی هم داریم که باید این اطلاعات رو از بافر مربوطه برداره و پردازش کنه و به ماتبع اون یک سری فرمانهایی رو تشخیص بده و به تسک های دیگه ای (مثلا 4 تسک عین هم) اطلاع بده تا اونها شروع به پردازش دستورات کنن. این تسک ها باید نتایج رو از طریق همون پورت سریال (منحصر بفرد) به ارسال کننده بفرستن.

                            خوب!

                            این مسئله. قرار هم نیست از چیزایی مثل message queue که در RTX موجوده استفاده کنیم.
                            چک کردن وضعیت به صورت سنتی مجازه اما در راه حل نهایی جایی نداره. شما باشین چکار میکنین؟ یک کد مجازی بنویسین.
                            تا اگر تونستم و وقت شد نتیجه رو براتون توضیح بدم.

                            موفق باشین.
                            توضیح این نکته هم ضروریه که این تیپ مسائل به کرات در ساختارهای حجیم تر و ماشین های پرقدرت تر پیش میاد.
                            بنابراین فکر نکنین دارین فقط با RTX و ARM سر و کله میزنین.

                            یک راهنمایی:
                            سمافور یک عنصر شمارشی هست. mutex یک عنصر تعلق پذیری و event یک عنصر شرطی.
                            راهنمایی دوم:
                            تحلیل کامل مسئله مهمتر از حل اونه. پس نخوایین خیلی سریع دست به کد بشین.

                            دیدگاه


                              #89
                              پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                              آقا واقعا ممنون از هر دوتون که ترکوندین :applause: :applause:

                              پس میتونیم برای همزمان سازی تسک ها هم از رویدادها استفاده کنیم هم سمافور.
                              فرق رویداد با سمافور هم اینه که رویداد شرطیه و فقط برای تسکها میتونه استفاده بشه.
                              ولی سمافور شمارشیه و هم برای تسک ها و هم سایر منابع سیستم میشه استفاده کرد.

                              بحث سنگینیه ولی با بحث هایی آکادمیکی که کردین خیلی خوب تفهیم شد :nerd:
                              تمرینو کسی حل کرده - بدین ما هم یه کپی بگیریم .


                              دیدگاه


                                #90
                                پاسخ : سیستم عامل بی درنگ RTX برای ARM7/9 و Cortex-M

                                تمرینو کسی حل کرده - بدین ما هم یه کپی بگیریم
                                حتما! فرمایش دیگه ای نیست؟

                                بذارین مسیر های منطقی برنامه رو در بیاریم و از هم تفکیک کنیم:

                                یک برنامه داریم که از روی پورت سریال اطلاعاتی رو میگیره و در یک بافر ذخیره میکنه
                                پس قاعدتا ما اینجا یک بافر داریم که برای دسترسی راحتتر میتونیم از بافر حلقوی استفاده کنیم که این بافر میتونه شامل چند تا بایت اطلاعات بشه. (معلوم نیست چند تا و بسته به شرایط برنامه و کلی اما و اگر ممکنه تغییر کنه) (اینا رو که پررنگ کردم منظور خاصی دارم میخوام بگم طراحی ما باید ترجیحا این موارد رو هم پوشش بده). فعلا اینجا هم نمیخوام از ساختارهایی مثل mailbox هم استفاده کنم.

                                همزمان تسکی هم داریم که باید این اطلاعات رو از بافر مربوطه برداره و پردازش کنه و به ماتبع اون یک سری فرمانهایی رو تشخیص بده و به تسک های دیگه ای (مثلا 4 تسک عین هم) اطلاع بده
                                تا اینجا ما دو عامل متفاوت داریم که ممکنه در بعضی اوقات به بافر حلقوی ما دسترسی پیدا کنن. یکی بفرم فقط خوندنی و یکی بفرم فقط نوشتنی. این دو عامل یکی وقفه نرم افزاری فوق الذکر هست و دیگری اون تابعی که با استفاده از امکانات RTX به صورت تسک تعریف میکنین.
                                در هنگام دسترسی یک عامل به این بافر حلقوی؛ عملیات خواندن و نوشتن اطلاعات منجر به یک عمل میشه که ممکنه با اون یکی عامل در یک مورد تلاقی کنه. پدیت کردن متغیر های مربوط به ابتدا و انتهای بافر حلقوی؛ بنا براین در این هنگام بایستی از مورد تعلق پذیری برای اطمینان از عدم مداخله عامل دوم استفاده بشه و این میشه همون mutex. از طرف دیگه تسک خواننده (آواز نه! اطلاعات) نبایستی مرتبا برای گاهی از وجود اطلاعاتی برای پردازش به این بافر سرکشی کنه. بنا براین برای اطلاع از اینکه آیا اطلاعاتی برای پردازش موجوده یا نه باید از مکانیسمی برای این عمل استفاده کنه. اما از طرفی یادمون باشه که معلوم نیست که تسک "خواننده" کی وقت میکنه اطلاعات رو از داخل بافر برداره. بنابراین نمیدونیم چه تعداد اطلاعاتی برای پردازش در هر لحظه در بافر موجوده. گفتیم تعداد! پس احتیاج به شیئی داریم که برامون عمل شمارش انجام بده. بهش میگیم سمافور.

                                بذارین کد مجازی این دو قسمت رو اینجوری بنویسیم:

                                isr:
                                begin
                                c = get data from UART
                                if data_queue has at least one empty room
                                aquire ownership of queue
                                put <c> into queue
                                release ownership
                                release semaphore by 1
                                endif
                                end


                                process_task:
                                begin
                                forever
                                wait for semaphore infinitedly
                                // there are at least one data byte to be processed
                                aquire queue ownership
                                get data from queue and place into <a>
                                release queue ownership
                                process data <a>
                                end
                                end


                                اما مسئلتن!
                                در RTX سرویسی مثل isr_mut_wait نداریم. بنابراین باید دعا کنیم که در هنگام دسترسی به این بافر از طریق روال وقفه مشکلی برای تسک ها پیش نمیاد. (تداخلی پیش نمیاد). ولی چون عادت نداریم که کارهامون رو بر اساس اما و اگر پیش ببریم؛ بجای این منطق "تعلق" در اینجا و استفاده از بافر حلقوی؛ کارمون رو راحت میکنیم و از mailbox استفاده میکنیم که امکانی مثل isr_mbx_send رو برامون فراهم کرده.

                                بقیه اش با خودتون!
                                :rolleyes:

                                نکته مهم همون استفاده از منطق شمارشی سمافور هست که باز هم جای دیگه حتما با بافر حلقوی و نه mailbox باید پیاده سازی بشه. غیر از این مورد میشد بجای مورد تعلق بافر که بر سر عدم وجود سرویسش گیر کردیم از فعال و غیر فعال کردن وقفه ها استفاده کرد. تا ایجاد تعلق رو پیاده سازی کنیم. توجه کنین که فقط یک وقفه و فقط یک تسک به این بافر دسترسی پیدا میکنن.

                                دیدگاه

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