در مقاله دوم آموزش رزبری پای، بهمعرفی ساختار CPU نحوه اجرای برنامه در رزبری پای پرداختیم. در این مقاله قصد داریم نحوه نصب و کانفیگ ابزارهای لازم جهت کامپایل کدهای نوشتهشده برای بردهای رزبری پای را آموزش دهیم.
همانطور که قبلا توضیح دادیم، پلتفرم سختافزاری رزبری پای مبتنی بر پردازندههای ARM است و نمیتوان از کامپایلرهای x86 مثل ویژوال استودیو برای کامپایل کدهای زربری استفاده کرد.
معرفی کامپایلرهای موجود:
واضح است برای تبدیل کدهای نوشتهشده به بیت کدهای قابلفهم توسط پردانده، نیاز به ابزاری است که اصطلاحاً به آن کامپایلر میگویند. کامپایلری که برای تبدیل کدهای رزبری پای موردنیاز است باید قابلیت کامپایل برای پلتفرم ARM را داشته باشد. کمپایلرهای زیادی وجود ندارند که دارای چنین قابلیتی باشند. کامپایلرهایی که قادر به پشتیبانی پلتفرم ARM باشند، (معروفترین آنها) به شرح زیر هستند:
- ARM Keil
- ARM IAR
- GCC
بله، تقریبا همین سه مورد! ممکن است فکرکنید که خب Atmel Studio یا CooCox و خیلی از ابزارهای دیگر قابلیت کامپایل برای ARM را دارند ولی باید خاطرنشان کنم که هماکنون در خصوص کامپایلر صحبت میکنیم و موارد ذکرشده فقط ویرایشگر کد هستند و خود دارای کامپایلر نیستند. بهعنوان نمونه SEGGER Embedded Studio و حتی Atmel Studio از GCC استفاده میکنند.
از چه کامپایلری استفاده کنیم؟
تصمیمگیری در خصوص کامپایلر مورداستفاده با توجه به لیست معرفیشده چندان دشوار نیست. کامپایلر Keil و IAR هردو غیر رایگان هستند و برای استفاده از آنها باید لایسنس آنها را خریداری کرد. ما در سیسوگ سعی میکنیم که به معرفی و استفاده از ابزارهای متنباز و رایگان بپردازیم. با توجه به پولی بودن کامپایلرهای Keil و IAR از آنها چشمپوشی کرده و آموزشهای خود را بر اساس کامپایلر رایگان GCC ادامه میدهیم. اما در نظر داشته باشید که انتخاب کامپایلر رایگان GCC از روی ناچاری نیست. یکیاز دلایل انتخاب این کامپایلر، انعطافپذیری زیاد و برتری آن نسبت به کامپایلر Keil است. شاید نتوان گفت که از IAR قویتر است اما به جرئت میتوان گفت که چیزی از آن کم ندارد و عملکردی بسیار نزدیک به یکدیگر دارند. کامپایلر GCC چنان قدرتمند است که حتی ARM Keil امکان استفاده از آن را در محیط خود، به کاربر میدهد و کاربر میتواند بسته به نیاز از ویرایشگر Keil و کامپایلر GCC استفاده کند.
از طرفی رایگان و متنباز بودن کامپایلر GCC، باعث شده است که افراد زیادی در سراسر جهان از آن استفاده کنند و در بهینهسازی این کامپایلر مشارکت داشته باشند. باتوجهبه طیف وسیع استفادهکنندههای این کامپایلر، اگر احیاناً در قسمتی دچار مشکل شدید بهراحتی با جستجو در اینترنت میتوانید منشأ مشکل را پیدا و آنرا حل کنید. ازطرفی بیشتر سورسهای منتشرشده، با استفادهاز این کامپایلر انجام شدهاند.
چگونگی نصب کامپایلر GCC:
نصب و راهاندازی GCC کار پیچیده ای نیست و بهراحتی قابل انجام است. اگر از لینوکس استفاده میکنید، لبخند بزنید چرا که برای نصب و پیکربندی کافی ست فقط خط زیر را در ترمینال تایپ کنید:
sudo apt-get install gcc-arm-embedded
دقت داشته باشید که دستورفوق برای نصب برروی توزیعهای مبتنی برای بیان است. اما کاربران ویندوز نیاز است که یکی دو مرحله بیشتر طی کنند. ولی جای نگرانی نیست. مراحل خیلی ساده هستند و میتوان بهراحتی آنها را انجام داد. در مرحلهی اول بامراجعه به سایت GCC ARM Embedded ، آخرین نسخه مبتنی بر ویندوز خود را دریافت کنید.
نکته: دقت کنید که حتما نسخه نصبی را دانلود کنید.
بعداز دانلود فایل نصبی کامپایلر GCC، بهراحتی مثل نصب دیگر نرمافزارها، کافیست که برروی دکمه Next کلیک کنید تا کار نصب خودکار انجام شود.
بعداز تمامشدن مراحلنصب، برای بررسی نصب صحیح میتوان دستورزیر را در خطفرمان (Command Prompt ویندوز یا ترمینال لینوکس) وارد کرد:
arm-none-eabi-gcc -v
درصورت نصب صحیح برنامههای موردنیاز، بااجرای دستور فوق، خروجی مطابق زیر خواهد بود:
Using built-in specs. COLLECT_GCC=arm-none-eabi-gcc COLLECT_LTO_WRAPPER=c:/program\ files\ (x86)/gnu\ tools\ arm\ embedded/4.9\ 2015 q1/bin/../lib/gcc/arm-none-eabi/4.9.3/lto-wrapper.exe Target: arm-none-eabi Configured with: /home/build/work/GCC-4-9-build/src/gcc/configure --build=i686-l inux-gnu --host=i686-w64-mingw32 --target=arm-none-eabi --prefix=/home/build/wor k/GCC-4-9-build/install-mingw --libexecdir=/home/build/work/GCC-4-9-build/instal l-mingw/lib --infodir=/home/build/work/GCC-4-9-build/install-mingw/share/doc/gcc -arm-none-eabi/info --mandir=/home/build/work/GCC-4-9-build/install-mingw/share/ doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-4-9-build/install-mingw /share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-4-9-build/instal l-mingw/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --disable-decim al-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libqu admath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared - -disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-headers=yes -- with-newlib --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build /work/GCC-4-9-build/install-mingw/arm-none-eabi --with-libiconv-prefix=/home/bui ld/work/GCC-4-9-build/build-mingw/host-libs/usr --with-gmp=/home/build/work/GCC- 4-9-build/build-mingw/host-libs/usr --with-mpfr=/home/build/work/GCC-4-9-build/b uild-mingw/host-libs/usr --with-mpc=/home/build/work/GCC-4-9-build/build-mingw/h ost-libs/usr --with-isl=/home/build/work/GCC-4-9-build/build-mingw/host-libs/usr --with-cloog=/home/build/work/GCC-4-9-build/build-mingw/host-libs/usr --with-li belf=/home/build/work/GCC-4-9-build/build-mingw/host-libs/usr --with-host-libstd cxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m ,cortex-m7,armv7-r Thread model: single gcc version 4.9.3 20150303 (release) [ARM/embedded-4_9-branch revision 221220] ( GNU Tools for ARM Embedded Processors)
این خروجی یعنی تمام کارهای مربوط به نصب و پیکربندی بهدرستی انجام شده است.
نوشتن اولین برنامه
همیشه سختترین قسمت کار، نوشتن اولین برنامه است؛ چرا که پارامترهای زیادی وجود دارد که ممکناست در کارنکردن یک برنامه دخیل باشند و پیداکردن مشکل را سخت کنند. برایهمین هم است که معمولاً اولین برنامه را در سادهترین حالت ممکن انتخاب میکنند. در دنیای کامپیوتر برنامه شروع را Hello world مینامند و بهسادگی کد زیر است:
main( ) { printf("hello, world"); }
ما در دنیای الکترونیک وضع مقداری فرق دارد. پیادهسازی فرمان printf خود مستلزم آگاهی بسیار زیادی از اجزاء سختافزاری و نرمافزاری است. بههمین دلیل معمولاً برنامه شروع در دنیای الکترونیک خیلی متفاوت از آن چیزی است که در دنیای کامپیوتر وجود دارد. در دنیای الکترونیک برای شروع با هر سختافزار و یا میکروکنترلر، ابتدا سعی میشود یک برنامه چشمکزن نوشته شود. یعنی برنامهای که با صفر و یک کردن یکی از پورتهای موجود بر روی سختافزار، بتوان به صحت اجرای برنامه پی برد. در واقع سادهترین برنامهای که میتوان نوشت، برنامه یک چشمکزن است. برای همین است که در اکثر بردهای آموزشی، حداقل یک LED وجود دارد که میتوان وضعیت آن را با استفاده از پردازنده مرکزی کنترل کرد. سختافزار رزبری پای نیز از این قاعده جدا نبوده و خوشبختانه یک LED به نام ACT بر روی آن تعبیه شده است.
برای شروع، باید بدانیم که این LED به کدام پایه از پردازنده متصل شده است. با توجه به سختافزارهای متفاوت در ورژنهای مختلف برد رزبری، لازم است که یکی را بهعنوان سختافزار پیشفرض در نظر بگیریم و آموزش را براساس آن جلو ببریم. باتوجهبه قدیمیشدن ورژن 1 و کمیابشدن آن در بازار، سختافزار پیشفرض را Raspberry pi 2 در نظر میگیریم. قبلاز هرچیز برای دانستن وضعیت اتصال ACT LED، باید شماتیک برد را داشته باشیم. خوشبختانه شماتیک آن توسط تیم توسعهی رزبری پای در دسترس قرار گرفته است. برای دانلود شماتیک میتوانید به سایت رزبری پای مراجعه کنید.
همانطور که در تصویر فوق مشاهده میکنید، ACT LED که در شماتیک بهصورت Status LED از آن نام برده شده به GPIO16 از پردازنده متصل شده است. در گام بعدی برای اینکه بتوانیم وضعیت یک GPIO را کنترل کنیم لازم است با ساز و کار مربوط به آن آشنا شویم و در واقع نیاز به دیتاشیت پردازنده داریم که خوشبختانه آن نیز در دسترس قرار گرفته است. باتوجهبه اطلاعات بهدستآمده در خصوص سختافزار و همچنین رجیسترهای کنترلی پردازنده، بهراحتی میتوان برنامه موردنظر را نوشت. در این بخش از مقاله بیش از این وارد جزئیات نوشتن و عملکرد برنامه نمیشویم. در مقالات بعدی با توضیحات بیشتر، به نحوه پیادهسازی و کار با رجیستر های پردازنده خواهیم پرداخت.
/* The base address of the GPIO peripheral (ARM Physical Address) */ #define GPIO_BASE 0x3F200000UL #define LED_GPFSEL GPIO_GPFSEL4 #define LED_GPFBIT 21 #define LED_GPSET GPIO_GPSET1 #define LED_GPCLR GPIO_GPCLR1 #define LED_GPIO_BIT 15 /** GPIO Register set */ volatile unsigned int* gpio; /** Simple loop variable */ volatile unsigned int tim; /** Main function - we'll never return from here */ int main(void) __attribute__((naked)); int main(void) { /* Assign the address of the GPIO peripheral (Using ARM Physical Address) */ gpio = (unsigned int*)GPIO_BASE; /* Write 1 to the GPIO16 init nibble in the Function Select 1 GPIO peripheral register to enable GPIO16 as an output */ gpio[LED_GPFSEL] |= (1 << LED_GPFBIT); /* Never exit as there is no OS to exit to! */ while(1) { for(tim = 0; tim < 500000; tim++) ; /* Set the LED GPIO pin low ( Turn OK LED on for original Pi)*/ gpio[LED_GPCLR] = (1 << LED_GPIO_BIT); for(tim = 0; tim < 500000; tim++) ; /* Set the LED GPIO pin high ( Turn OK LED off for original Pi)*/ gpio[LED_GPSET] = (1 << LED_GPIO_BIT); } }
چگونگی کامپایل برنامه
برنامه فوق را با اسم blinkact.c ذخیره میکنیم. برای کامپایل برنامه قبل از هر مسئلهای نیاز است که یکسری تنظیمات را در خصوص پلتفرم مورداستفاده انجام بدهیم که خوشبختانه باتوجهبه کامند لاین بودن کامپایلر GCC، تمام تنظیمات مربوطه بهصورت پارامترهای ورودی دریافت می کند. برای کامپایل برنامه فقط کافی است که دستور زیر را یا در ترمینال یا کامند پرامپت اجرا کنیم:
arm-none-eabi-gcc -O0 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a -mtune=cortex-a7 -nostartfiles -g blinkact.c -o kernel.elf
کلید -mtune=cortex-a7 به کامپایلر میگوید که کد موردنظر را برای پردازندههای خانوادهی Cortex-a7 کامپایل کند و کلید -march=armv7-a به نوع معماری این خانواده اشاره دارد. بعد از اجرای دستور فوق، برنامه کامپایل شده و خروجی kernel.elf ایجاد میشود. فایلهای elf، حاوی اطلاعات زیادی در خصوص کتابخانههای مورداستفاده، پارامترهایی جهت خطایابی و همچنین اطلاعات اجرایی هستند. برای استخراج کدهای اجرایی نیاز است که دستور زیر را اجرا کنیم:
arm-none-eabi-objcopy kernel.elf -O binary kernel.img
بعد از اجرای دستور فوق، فایل اجرایی kernel.img ایجاد میشود. هماکنون برنامه آماده اجرا است.
منبع: سیسوگ
[…] مداری که اینجا طراحی کردیم رو خیلی دربهداغون نکرده باشید؛ چون […]
[…] مقالهی سوم آموزش رزبری پای، به پیکربندی و نصب ابزار موردنیاز برای کامپایل برنامه […]