اطلاعیه

Collapse
No announcement yet.

extern "C" void DMA_IRQHandler (void); یعنی چی

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

    extern "C" void DMA_IRQHandler (void); یعنی چی

    extern "C" void DMA_IRQHandler (void);
    این که بالا نوشتم یعنی چی؟
    --------------------------------------------------------------------
    نمیخام بدونم چکا میکنه میخام بدونم این فرم تعریف یعنی چی!
    انجام پروژه هاي برنامه نويسي اندرويد
    [glow=red,2,300]نرم افزار نقشه هاي پاور کامپيوتر اندوريد[/glow]
    http://cafebazaar.ir/app/?id=com.atxdroid

    #2
    پاسخ : extern "C" void DMA_IRQHandler (void); یعنی چی

    بطور خیلی دم دستی و ساده یعنی:
    "این تابع در یک سورس به زبان C نوشته شده."

    برای اطلاع کاملتر یخده باید قصه حسن کچل گفت:
    وقتی شما یک سورس رو کامپایل میکنین بسته به اینکه چه زبانی استفاده شده باشه؛ اسامی متغیر ها و توابع بفرم خاصی برمیگردن و در فایلهای obj برای ارجاعات بعدی ذخیره میشن. مثلا زبان پاسکال تمامی کاراکتر های اسم تابع رو بصورت حروف بزرگ در نظر میگیره. یا زبان C یک کاراکتر _ به ابتدای اسم تابع اضافه میکنه. اما ++C رویه دیگه ای داره. این کامپایلر میاد و با استفاده از اسم تابع و یک فرمول خاص با استفاده از تعداد و نوع پارامتر ها یک اسم عجق وجق تولید میکنه. حالا اگر شما یک تابعی رو به زبانی غیر از ++C بنویسین و یا از کامپایلر ++C در حالتی مثل یک کامپایلر C برای کامپایل استفاده کنین (چیزی که معمولا برای لایبرری های استاندارد استفاده میشه) این توابع توسط linker برای تولید فایل اجرایی نهایی قابل شناخت نیستن. چون از دو روش اسم گذاری متفاوت برای یک تابع دارین استفاده میکنین. یک روش در زمان کامپایل خود تابع و یک روش برای استفاده از اون تابع. به همین علت بایستی توابعی که در حالت کامپایل به زبان C کامپایل شده اند و از قاعده اسم گذاری C تبعیت میکنند رو در سورس ++C به این فرم معرفی کنین تا کامپایلر ++C از قاعده اسم گذاری C برای صدا کردن این توابع استفاده کنه و در زمان link بتونه ارجاعات به این توابع رو شناسایی کنه. معمولا هم این فرم به این صورتی که شما نوشتین استفاده نمیشه. بلکه در فایل هدر مربوطه به این فرم استفاده میشه:


    #ifdef __cplusplus
    extern "C" {
    #endif

    int printf(const char *fmt, ...);

    #ifdef __cplusplus
    };
    #endif


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

    دیدگاه


      #3
      پاسخ : extern "C" void DMA_IRQHandler (void); یعنی چی

      جلل خالق :eek:
      چه چیز ها
      والا تا اونجای من میدونم تو کیل باید c++ نوشت تا جواب بده حالا چه لزوممی داره بیام بگیم این تابع زبان سی میباشد؟

      یه سوال دیگه
      کد:
      UART_Init((LPC_UART_TypeDef *)LPC_UART0, &UARTConfigStruct);
      داستان اون ستاره چیه؟
      نگین که پویتره چون من :angry: میکنم!
      انجام پروژه هاي برنامه نويسي اندرويد
      [glow=red,2,300]نرم افزار نقشه هاي پاور کامپيوتر اندوريد[/glow]
      http://cafebazaar.ir/app/?id=com.atxdroid

      دیدگاه


        #4
        پاسخ : extern "C" void DMA_IRQHandler (void); یعنی چی

        متاسفانه کامپایلر ++C دو کامپایلر در یک پک هست. یک کامپایلر خاص ++C بر اساس یک کامپایلر C. به همین خاطر بایستی کامپایلر ++C این قابلیت رو باید داشته باشه از فایلهای obj کامپایلر C استفاده کنه. مثلا اصل روتین printf یا روتین strcpy که احتیاجی نداره به ++C نوشته بشه. از طرفی شما دارین با حالت ++C کار میکنین. شاید من عشقم کشید در حالت C باهاش کار کنم. اونوقت تکلیف یک تابع با اسمی مثل (تو مایه های) strcpy@v$q$q چیه؟ در حالت C اسم این تابع در فایل obj چیزی مثل strcpy_ هست.
        ممکنه بگین چرا کامپایلر ++C این کار مسخره رو انجام میده. میدونین چرا؟ چون یک خصوصیت ویژه ++C به این کار بستگی داره.تا حالا به این مورد برخوردین که overloading در حد تابع؛ چطوری در ++C پیاده شده؟ با استفاده از این اسم عجق وجق (یا بهتره بگیم بقول خودش mangled) میتونه در زمان لینک بفهمه که آیا این تابعی که مثلا یک int برمیگردونه و دو تا پارامتر از نوع * char داره کجا هست و با تابع هم اسم ولی پارامتر های متفاوت اشتباه نشه؟
        این آدرس رو ببینین:
        http://en.wikipedia.org/wiki/Name_mangling

        ----

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

        حالا چرا این اراجیف رو گفتم؟
        در تابع شما (من نمیدونم این تابع چیه ولی طبق همین یک خط تز میدم. چون روش های مرسوم اینه. معمولا به افسر التماس میکنیم که چیزی رو ندیده بگیره. پس اگر کسی رو دیدین که داره به افسر راهنمایی التماس میکنه میشه به احتمال قوی به این مورد شک برد) بنظر میاد که پارامتر اول یک اشاره گر به نوع LPC_UART_TypeDef باید به عنوان آرگومان بهش پاس بشه. ولی مقدار LPC_UART0 از این نوع نیست. حالا من میام به تابع التماس میکنم که این آرگومان LPC_UART0 رو به فرمی ببینه که مثلا از نوع * LPC_UART_TypeDef باشه. به چه درد میخوره؟ من نمیدونم LPC_UART0 چی تعریف شده. ممکنه یک آدرس (یک عدد) باشه که در اونجا یک ساختار فرضی از جنس LPC_UART_TypeDef وجود داره. من که نمیتونم طبق قرارداد یک عدد رو به جای یک اشاره گر استفاده کنم. گرچه این دو تا در اصل یکی هستن. پس با این کار به کامپایلر التماس میکنم که به LPC_UART0 همونجوری نگاه کنه که انگاری این عدد در اصل یک اشاره گر به نوع LPC_UART_TypeDef هست. مثل اینکه به افسر بگم: آقاجون فرض کن من یه آمبولانس هستم. چون مریض دارم.
        اگر افسر این رو قبول کنه از این به بعد پیکان من با یک آمبولانس فرقی نمیکنه. و اگر فرض کنیم این دید افسر در همه جا نافذ باشه؛ پس بیمارستان هم همونطوری با پیکان فکسنی من برخورد میکنه که با یک آمبولانس آرم دار وزارت بهداشت.

        حالا چرا گفتم این یک کار خطرناک هست؟ چون یک نوع در یک زبان طرز برخورد با یک حافظه رو مشخص میکنه. مثلا float و int هر دوتاشون 4 بایتی هستن. ولی یکی رو میتونیم شیفت بدیم و اون یکی رو نه. حالا اگر من چیزی رو به فرمی به یک تابع ارسال کنم که قابلیت اون کار رو نداشته باشه دردسر پیش میاد. مثلا بیام آدرس یک int رو با همین فرم بجای یک اشاره گر به نوع LPC_UART_TypeDef به تابع پاس کنم. کامپایلر اینو قبول میکنه اما بعدا پوست از کله ام کنده میشه. درست مثل اینکه به افسر بگم من مریض دارم ولی یک جسد توی ماشین داشته باشم.

        توجه کنین که در هر دو حالت افسر نمیتونه چک کنه آیا من راست میگم یا نه.

        دیدگاه


          #5
          پاسخ : extern "C" void DMA_IRQHandler (void)zzz یعنی چی

          چند مدت پیش یه بحثی بود که تشکر رو لول بندی کنن که هنوز نشده ولی اگه بود من این رو میزدم
          تـــــــــــــــــــــــــــــــــــــــــــــــــ ــــــــــــشـــــــــــــــــــــــــــــــــــــ ـــــــــــــــــکــــــــــــــــــــــــــــــــ ـــــــــــــــــــــــــــــــر

          یه ابهام برام پیش اومده
          extern "C"
          یعنی این که این رو سی ببین؟
          خوب حالا بخایم بگیم سی پلاس پلاس ببین باید چکار کنیم؟


          در مورد اون تابع هم بگم که
          نه خوتون ببینین

          کد:
          typedef struct
          {
           union {
           __I uint8_t RBR;
           __O uint8_t THR;
           __IO uint8_t DLL;
              uint32_t RESERVED0;
           };
           union {
           __IO uint8_t DLM;
           __IO uint32_t IER;
           };
           union {
           __I uint32_t IIR;
           __O uint8_t FCR;
           };
           __IO uint8_t LCR;
              uint8_t RESERVED1[7];
           __I uint8_t LSR;
              uint8_t RESERVED2[7];
           __IO uint8_t SCR;
              uint8_t RESERVED3[3];
           __IO uint32_t ACR;
           __IO uint8_t ICR;
              uint8_t RESERVED4[3];
           __IO uint8_t FDR;
              uint8_t RESERVED5[7];
           __IO uint8_t TER;
          } LPC_UART_TypeDef;

          کد:
          #define LPC_UART0       ((LPC_UART_TypeDef   *) LPC_UART0_BASE  )


          که این هم
          کد:
          UARTConfigStruct
          ربط داره به این
          کد:
          UART_CFG_Type UARTConfigStruct;

          و

          کد:
          /********************************************************************//**
          * @brief UART Configuration Structure definition
          **********************************************************************/
          typedef struct {
           uint32_t Baud_rate;  		/**< UART baud rate */
           UART_PARITY_Type Parity;  	/**< Parity selection, should be:
          							  - UART_PARITY_NONE: No parity
          							  - UART_PARITY_ODD: Odd parity
          							  - UART_PARITY_EVEN: Even parity
          							  - UART_PARITY_SP_1: Forced "1" stick parity
          							  - UART_PARITY_SP_0: Forced "0" stick parity
          							  */
           UART_DATABIT_Type Databits;  /**< Number of data bits, should be:
          							  - UART_DATABIT_5: UART 5 bit data mode
          							  - UART_DATABIT_6: UART 6 bit data mode
          							  - UART_DATABIT_7: UART 7 bit data mode
          							  - UART_DATABIT_8: UART 8 bit data mode
          							  */
           UART_STOPBIT_Type Stopbits;  /**< Number of stop bits, should be:
          							  - UART_STOPBIT_1: UART 1 Stop Bits Select
          							  - UART_STOPBIT_2: UART 2 Stop Bits Select
          							  */
          } UART_CFG_Type;

          یه بار فکر نکنی من خودم این ها رو نوشتم!
          اصل داستان من میخام از تابع lpc17xx_uart.h استفاده کنم که نمیدونم چطوری پس توی سایت ها گشتم و یه کد دیدم که اون هم ظاهرا با gcc arm میشه کامپایلش کرد که من بر اساس اون شروع کردم به نوشتن توی کیل که به این خط رسیدم و کیل که ارور میگیره و حالا که میخام ترجمه اش کنم نمی دونم چی نوشته!

          اگه نیاز هست بگین اون فایل ها رو هم اپ کنم

          با تشکر
          محسن فاریابی
          امضا
          :biggrin:
          -----------------------------------------------------------------------------------------
          دیدی داشت یادم میرفت
          کد:
          IO uint8_t DLL__;
          داستان اون اندر لاین ها چیه؟ oo:
          انجام پروژه هاي برنامه نويسي اندرويد
          [glow=red,2,300]نرم افزار نقشه هاي پاور کامپيوتر اندوريد[/glow]
          http://cafebazaar.ir/app/?id=com.atxdroid

          دیدگاه


            #6
            پاسخ : extern "C" void DMA_IRQHandler (void); یعنی چی

            شما وقتی با کامپایلر در حالت ++C کار میکنی میتونی کد C رو هم کامپایل کنی. اما عکسش نمیشه. بنا براین این حرف بی معنی هست. اما اگر قراره این کد بفرم اسم گذاری ++C استفاده بشه این عبارت "extern "C رو بالا و پایینش نذار. میشه همون منگول بازی ++C.
            راجع به سورست هم نمیدونم قضیه چیه. اینجا بذار من بتونم با کیل یک تست کنم. ببینم مشکل ممکنه از چی باشه.
            شاید هم مشکل رو نتونستم حل کنم ولی یه چیزی از خودم درآوردم! کی به کیه؟!! :mrgreen:

            دیدگاه


              #7
              پاسخ : extern "C" void DMA_IRQHandler (void); یعنی چی

              این پروژه ای که من با کیل سر هم کردم و فایل های که مربوط به اون پروژه ای هست که نمیدونم با چی باید کامپایل بشه
              http://up1.iranblog.com/images/n6urkfigk8rux9ssd.rar

              http://up1.iranblog.com/images/7lq9i7phmgbz6xq3hn3l.zip

              فایل های پست اول این رو هم باید اضاف کنی
              http://www.eca.ir/forum2/index.php?topic=57070.0

              منتظر جواب سبزتان هستم!
              میخام uart رو راه بندازم!
              :nerd: :nerd: :nerd: :nerd: :nerd:
              انجام پروژه هاي برنامه نويسي اندرويد
              [glow=red,2,300]نرم افزار نقشه هاي پاور کامپيوتر اندوريد[/glow]
              http://cafebazaar.ir/app/?id=com.atxdroid

              دیدگاه

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