فهرست مطالب:

قسمت 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Step
قسمت 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Step

تصویری: قسمت 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Step

تصویری: قسمت 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Step
تصویری: Part 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo 2024, دسامبر
Anonim
Image
Image

تمرکز این دستورالعمل بر روی میکروکنترلر STM32 Nucleo است. انگیزه این امر این است که بتوانیم پروژه مونتاژ را از استخوان های برهنه ایجاد کنیم. این به ما کمک می کند تا عمق بیشتری پیدا کرده و پروژه MSP432 Launchpad (TI-RSLK) را که قبلاً موضوع چندین دستورالعمل بوده است ، درک کنیم.

برای ایجاد یک پروژه فقط مونتاژ برای MSP432 ، با استفاده از Code Composer Studio ، کمک چندانی آنلاین نمی شود. تا کنون ما فقط در حال کپی/چسباندن از یک پروژه مونتاژ قبلی هستیم. این رویکرد به خوبی به ما خدمت کرده است.

با این حال ، در حال حاضر ، برای آزمایشگاه 7 ، ما کمی مشکل داریم. یا حداقل یک سکسکه موقت. آزمایشگاه 7 ماشینهای حالت محدود را معرفی می کند و اولین چیزی که با آن مواجه می شویم نیاز به ایجاد و استفاده از آرایه ای از مقادیر است. از آنجا که دوره TI عمدتا از برنامه نویسی C استفاده می کند - این مشکلی نیست. اما این دستورالعمل ها روی مونتاژ متمرکز شده اند ، نه C.

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

به نظر می رسد کمک های بیشتری برای پروژه های مونتاژ با استفاده از STM32 MCU به صورت آنلاین وجود دارد ، بنابراین ، ما با این دستورالعمل شروع می کنیم ، با هدف استفاده از آموخته ها ، سپس به MSP432 و استودیو Code Composer اعمال می شود.

در مسیر رسیدن به این هدف ، ما با یک میکرو کنترلر محبوب دیگر نیز تجربه کسب کرده ایم.

مرحله 1: آزمایش اولیه دستگاه

آزمایش اولیه دستگاه
آزمایش اولیه دستگاه
آزمایش اولیه دستگاه
آزمایش اولیه دستگاه
آزمایش اولیه دستگاه
آزمایش اولیه دستگاه

باز هم ، چرا STM32 Nucleo را به طور خاص انتخاب می کنیم؟

صادقانه؟ زیرا من در جستجوی مقالات خوب در مورد پروژه های مونتاژ فلز برهنه برای کنترلرهای ARM بودم و با این سری برخورد کردم. و همچنین به این دلیل که به نظر می رسد STM32 یک MCU محبوب است.

من برخی تحقیقات را انجام دادم (نسخه های زیادی برای انتخاب وجود دارد - تصویر بالا را ببینید) ، اما در نهایت چیزی که واقعاً می توانم بدست آورم ، از آنجا که قصد استفاده از آمازون (در ایالات متحده) را داشتم.

این بسته در یک بسته ساده اما حرفه ای با برخی از دستورالعمل های راه اندازی ارائه می شود. کمی خنده دار بود که ببینیم نسخه ی نمایشی کنترل کننده دقیقاً همان چیزی است که ما در دستورالعمل های قبلی انجام دادیم - چراغ LED چشمک می زند و سرعت را مطابق فشار یک دکمه تغییر می دهد.

به نظر می رسد که این صفحه توسعه بسیار شبیه به MSP432 است زیرا 2 LED و یک دکمه کاربر فشار می دهد. MSP432 دارای 2 دکمه کاربر است.

همانطور که در عکسها مشاهده می کنید ، کمی تعجب کردم که برد مینی دارد و USB میکرو ندارد. مجبور شدم برای خرید طناب تمام شوم.

یک آزمایش خوب دیگر این است که وقتی آن را به رایانه خود وصل می کنید (من از جعبه لینوکس استفاده می کنم) ، در فایل منیجر من ، به عنوان یک سیستم فایل ، به نام "NODE_F303RE" نشان داده می شود. باز کردن که دو فایل را نشان می دهد ، یکی HTML و یک متن.

این تمام است ، اما حداقل می گوید اتصال بسیار آسان به نظر می رسد.

اکنون ما آماده شروع هستیم.

من سعی می کنم هیچ یک از اطلاعات خوب مجموعه مقاله IVONOMICON Bare Metal را تکرار نکنم ، بلکه آن را افزایش دهم.

مرحله 2: ملزومات

اولین چیزی که ما نیاز داریم یک کامپایلر است.

و سپس ، ما به یک اشکال زدایی نیاز داریم:

devchu@chubox: su $ sudo apt-get install gdb-arm-none-eabi خواندن فهرست های بسته… انجام شد درخت وابستگی در حال خواندن اطلاعات وضعیت… انجام شد بسته های جدید زیر نصب می شود: gdb-arm-none-eabi 0 ارتقا یافته ، 1 مورد اخیر نصب شده ، 0 برای حذف و 8 ارتقا نیافته است. باید 2 ، 722 کیلوبایت بایگانی دریافت کنید. پس از این عملیات ، 7 ، 738 کیلوبایت فضای دیسک اضافی استفاده می شود. دریافت کنید: 1 https://us.archive.ubuntu.com/ubuntu xenial/gerd amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3+9 [2، 722 kB] دریافت 2 ، 722 کیلوبایت در 1 ثانیه (1 ، 988 kB/s) انتخاب بسته قبلاً انتخاب نشده gdb-arm-none-eabi. (در حال خواندن پایگاه داده… triggers for man-db (2.7.5-1)… راه اندازی gdb-arm-none-eabi (7.10-1ubuntu3+9)…

مرحله 3: ملزومات - ویندوز

در مرحله بالا فرض بر این بود که ما از لینوکس استفاده می کنیم. اگر از ویندوز استفاده می کنیم چطور؟

می توانید به سایت arm Developer بروید و چندین گزینه بارگیری در دسترس است. من از دستگاه ویندوز 8 استفاده می کنم.

در حین نصب ، من تصمیم گرفتم آن را به درایو اصلی C: / به جای Program Files نصب کنم فقط به این دلیل که من از cygwin نیز استفاده می کنم ، و ایجاد پیوند از سطل محلی من به پوشه C: در مسیر برنامه فایلها (با فاصله ، و غیره) خراب کنید.

بنابراین ، محیط و مسیر cygwin من و غیره به نظر می رسد:

C: / cygwin64 / home / bin / arm-none-eabi-gcc ، جایی که arm-none-eabi-gcc پیوندی به C: / GNUToolsArmEmbedded / 7.2018.q2.update / bin / arm-none-eabi- است gcc

سپس یک پوشه "dev" در cygwin home ایجاد کردم ، و آنجا بود که فایل core. S را قرار دادم و فرمان کامپایلر را اجرا کردم. (برای مطالب کامپایلر به ادامه مطلب مراجعه کنید).

من دقیقاً همین کار را برای gdb (arm-none-eabi-gdb) انجام دادم.

مرحله 4: موارد ضروری چیست

بنابراین "gcc-arm-none-eabi" چیست؟

کامپایلر gnu (GCC) زبان های برنامه نویسی (مانند C) را برای دستگاهی که روی آن کار می کند به کد بومی تبدیل می کند. به عنوان مثال ، اگر بخواهید برخی از کد های C را با استفاده از GCC در دستگاه Windows خود کامپایل کنید ، برای اجرا روی دستگاه Windows ساخته می شود. فایل اجرایی تولید شده (معمولاً) روی میکروکنترلر ARM اجرا نمی شود.

بنابراین ، به منظور ایجاد برنامه هایی برای بارگیری و سوزاندن در میکروکنترلر ARM (در مورد فعلی ما که STM32 Nucelo است) ، ما باید چیز دیگری به GCC بدهیم: توانایی "کامپایل متقابل". یعنی توانایی تولید یک برنامه اجرایی ، نه برای سیستم اصلی (و پردازنده) ، بلکه برای سیستم مورد نظر (میکروکنترلر ARM). اینجاست که "gcc-arm-none-eabi" مطرح می شود.

پس "gdb-arm-none-eabi" چیست؟

پس از بارگیری و سوزاندن (فلش کردن) فایل اجرایی جدید ایجاد شده در میکرو کنترلر ، احتمالاً می خواهیم آن را اشکال زدایی کنیم-مرحله به خط کد. GDB اشکال زدایی gnu است و همچنین برای انجام کار خود به روشی نیاز دارد ، اما سیستم دیگری را هدف قرار می دهد.

بنابراین ، gdb-arm-none-eabi مربوط به GDB است ، gcc-arm-none-eabi GCC چیست.

نصب بسته پیشنهادی دیگر "libnewlib-arm-none-eabi" بود. اون یکی چیه؟

Newlib یک کتابخانه C و کتابخانه ریاضی است که برای استفاده در سیستم های تعبیه شده در نظر گرفته شده است. مجموعه ای از چندین بخش کتابخانه است که همگی تحت مجوز نرم افزار رایگان هستند و به راحتی آنها را در محصولات تعبیه شده قابل استفاده می کنند.

و در نهایت ، بسته "libstdc ++-arm-none-eabi". آن یکی کاملاً واضح است ؛ این کتابخانه C ++ برای کامپایلر متقابل است. برای میکرو کنترلرهای تعبیه شده ARM

مرحله 5: فایل Linker

فایل Linker
فایل Linker
فایل Linker
فایل Linker

بیایید یک اسکریپت linker ایجاد کنیم.

یک بخش یا بلوک کلیدی در این فایل ، فرمان MEMORY خواهد بود.

--- از sourceware.org:

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

حافظه

{name [(attr)]: ORIGIN = مبدا ، LENGTH = len…}

مثال در مقاله:

/* پایان RAM و محدودیت حافظه پشته* //* (4KB SRAM در خط STM32F031x6 ، 4096 = 0x1000)*//* (RAM از آدرس 0x20000000 شروع می شود) _estack = 0x20001000 ؛

حافظه

{FLASH (rx): ORIGIN = 0x08000000 ، LENGTH = 32K RAM (rxw): ORIGIN = 0x20000000 ، LENGTH = 4K}

بنابراین ما باید بفهمیم چقدر FLASH (برای برنامه و ثابت های ما و غیره) و چه مقدار RAM (برای استفاده توسط برنامه ؛ heap and stack و غیره) برای برد خاص ما. این کمی جالب می شود.

کارت کوچک خوب همراه با Nucleo می گوید که دارای حافظه فلش 512 کیلوبایت و SRAM 80 کیلوبایت است. با این حال ، با اتصال آن به USB ، به عنوان یک سیستم فایل با دو فایل نصب می شود و هم مدیر فایل و هم GParted نشان می دهند که بیش از 540 کیلوبایت فضا دارد. (رم؟).

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

بنابراین اجازه دهید با ارقام روی کارت برویم. بنابراین اکنون ما مثال بالا را می گیریم و آن را به برد خاص خود تبدیل می کنیم.

ممکن است بخواهید از چیزی مانند این مبدل حافظه آنلاین استفاده کنید تا از KB عمومی به تعداد بایت خاصی بروید.

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

/ * انتهای RAM و محدوده حافظه stack را تعریف کنید */

/* (4KB SRAM در خط STM32F031x6 ، 4096 = 0x1000)* //* مثال*/

/ * مرحله 1: (80KB SRAM در STM32F303RE ، 81920 = 0x14000) * // * برد ما */

/* مرحله 2 ، اندازه hex را به آدرس شروع hex (در زیر) اضافه کنید. */

/ * (RAM از آدرس 0x20000000 شروع می شود) */

_estack = 0x20001000 ؛ /* مثال */

_estack = 0x20014000 ؛ / * تخته ما */

MEMORY {

فلاش (rx): ORIGIN = 0x08000000 ، LENGTH = 512K

RAM (rxw): ORIGIN = 0x20000000 ، LENGTH = 80K

}

فایل بالا را "linker.script.ld" صدا کنیم.

مرحله 6: جدول بردار

جدول بردار
جدول بردار

اکنون ما قصد داریم یک فایل مونتاژ کوچک (با دستورالعمل ها) برای انجام برخی از موارد بسیار مهم در ایجاد وقفه ایجاد کنیم. ما مثال مقاله را دنبال می کنیم و فایلی با نام "core. S" ایجاد می کنیم.

دوباره ، در اینجا مثال محتویات فایل آمده است ، اما من تغییراتی را در صفحه خاص ما ایجاد کردم:

// این دستورالعمل ها ویژگی های تراشه و

// زبان اسمبلی که استفاده خواهیم کرد:. Syntax unified /*بعد از این ناحیه کد را در زیر مشاهده کنید در عوض قشر برد ما را اضافه کنید تصویر بالا را در این مرحله مشاهده کنید * / /*.fpu softvfp * / / *این خط مثال را توضیح دهید * /.fpu vfpv4 / *به جای آن تابلوی ما را اضافه کنید ؛ دارای FPU */.thumb // مکان های حافظه جهانی است..global vtable.global reset_handler / * * جدول بردار واقعی. * فقط اندازه RAM و کنترل کننده "بازنشانی" * برای سادگی گنجانده شده است. */.type vtable ،٪ object vtable:.word _estack.word reset_handler. اندازه vtable ،.-vtable

هوم.. نه ".align" دستورالعمل

با این حال ، این مهم نیست. در مورد آن (شاید) بعداً بیشتر توضیح دهید.

. نحو متحد

. نحو [متحد | تقسیم شده]

این دستورالعمل دستورالعمل مجموعه دستورالعمل را همانطور که در بخش ARM-Instruction-Set توضیح داده شده است تنظیم می کند

9.4.2.1 دستورالعمل مجموعه نحو دو نحو کمی متفاوت از دستورات ARM و THUMB پشتیبانی می کنند. به طور پیش فرض ، تقسیم شده ، از سبک قدیمی استفاده می کند که دستورالعمل ARM و THUMB نحوهای جداگانه خود را داشت. نحو جدید ، یکپارچه ، که می تواند از طریق دستور Syntax انتخاب شود.

.fpu vfpv4

کامپایلر GCC می تواند باینری ها را با چندین گزینه در مورد نقطه شناور تولید کند: نرم - مناسب برای اجرا بر روی CPU ها بدون FPU - محاسبات در نرم افزار توسط softpp تولید شده توسط کامپایلر - مناسب برای اجرا در CPU ها با FPU یا بدون FPU - در صورت وجود از FPU استفاده می کند به برای مورد خاص ما (شما باید تحقیقات خود را انجام دهید) ، FPU این برد خاص با vfpv4 مطابقت دارد. شاید مجبور باشید با این بازی کنید. یا حتی آن را در softfp بگذارید.

انگشت شست (در مقایسه با.arm)

این میکروکنترلرهای ARM ترکیبی از مجموعه دستورالعمل ها هستند. یکی ARM و دیگری THUMB. یک تفاوت در دستورالعمل های 16 بیتی در مقایسه با دستورالعمل های 32 بیتی است. بنابراین ، این دستورالعمل به کامپایلر می گوید که دستورالعمل های بعدی را به عنوان THUMB یا ARM در نظر بگیرد.

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

مرحله 7: نسخه مونتاژ برنامه 'Hello World'

موارد زیر همچنین می توانند وارد فایل "core. S" شوند که قبلاً ایجاد شده است. این ، دوباره ، از مثال مقاله است.

/ * * کنترل تنظیم مجدد. با تنظیم مجدد تماس گرفت. */.type reset_handler ،٪ function reset_handler: // نشانگر پشته را در انتهای پشته تنظیم کنید. // مقدار '_estack' در اسکریپت linker ما تعریف شده است. LDR r0 ، = _estack MOV sp، r0

// برخی از مقادیر ساختگی را تنظیم کنید. وقتی این مقادیر را می بینیم

// در اشکال زدایی خود ، می دانیم که برنامه ما // در تراشه بارگیری شده و در حال کار است. LDR r7 ، = 0xDEADBEEF MOVS r0 ، #0 main_loop: // 1 را برای ثبت 'r0' اضافه کنید. ADDS r0 ، r0 ، #1 // حلقه عقب. B main_loop.size reset_handler،.-reset_handler

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

اگر دستورالعمل های مربوط به MSP432 و دوره/آزمایشگاه های TI-RSLK را دنبال کرده اید ، تقریباً همه برنامه های فوق باید برای شما آشنا باشد.

تنها چیزی که می بینم استفاده از "=" هنگام بارگیری "DEADBEEF" در ثبت R7 است. ما از آن استفاده نکرده بودیم

فایل "core. S" ضمیمه شده در اینجا حاوی منبع کامل است.

مرحله 8: تدوین کد

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

با این حال ، ما کاملاً آنجا نیستیم. ما مجدداً باید دستور داده شده در مقاله را تغییر دهیم و آن را به وضعیت خود تغییر دهیم.

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

arm -none -eabi -gcc -x assembler -with -cpp -c -O0 -mcpu = cortex -m0 -mthumb -Wall core. S -o core.o

اگر برای GCC به سایت gnu.org برویم (در این مورد نسخه 7.3) ،

ایکس

-x برای تعیین زبان است. در غیر این صورت اگر -x نباشد ، کامپایلر سعی می کند با استفاده از پسوند فایل حدس بزند. (در مورد ما ، *. S).

مثال بالا از مقاله assembler-with-cpp را مشخص می کند ، اما ما فقط می توانیم اسمبلر را انجام دهیم.

ج

-c می گوید کامپایل کنید اما پیوند ندهید.

O0

-O برای تعیین سطح بهینه سازی است. با استفاده از -O0 (oh -zero) می گوید "زمان کامپایل را کاهش دهید و اشکال زدایی نتایج مورد انتظار را تولید کنید. این به طور پیش فرض است".

mcpu = قشر-m0

-mcpu نام پردازنده مورد نظر را مشخص می کند. در مورد ما ، cortex-m4 خواهد بود.

معلوم

-mthumb انتخاب بین کد تولید کننده ای که حالت ARM و THUMB را اجرا می کند ، مشخص می کند.

دیوار

-Wall البته بسیار رایج و شناخته شده است. همه پرچم های هشدار را روشن می کند.

سرانجام ، در پایان فرمان ما فایل ورودی core. S و فایل خروجی core.o.

در اینجا خط فرمان جدید ایجاد شده برای متناسب با مورد خاص ما آمده است.

arm -none -eabi -gcc -x assembler -c -O0 -mcpu = cortex -m4 -mthumb -Wall core. S -o core.o

و آن را گردآوری کرد.

مرحله 9: پیوند دادن برنامه

به طور مستقیم از مثال موجود در مقاله ، این را داریم:

arm -none -eabi -gcc core.o -mcpu = cortex -m0 -mthumb -Wall --specs = nosys.specs -nostdlib -lgcc -T./STM32F031K6T6.ld -o main.elf

بیشتر موارد بالا را دیده اید. در زیر موارد جدید است.

specs = nosys.specs

توضیح این مورد کمی مشکل است.

این مربوط به "semihosting" و "retargeting" و مربوط به ورودی / خروجی است. همچنین به تماس های سیستم و کتابخانه ها مربوط می شود.

به طور معمول ، سیستم های تعبیه شده دستگاه های ورودی/خروجی استاندارد را ارائه نمی دهند. این امر بر تماس های سیستم یا کتابخانه تأثیر می گذارد (به عنوان مثال: printf ()).

Semihosting به معنای اشکال زدایی است (تصویر مرحله 11 را ببینید با قسمت اشکال زدایی که با رنگ قرمز حلقه شده است) دارای یک کانال ویژه است و از پروتکل semihosting استفاده می کند و می توانید خروجی printf () را در دستگاه میزبان (از طریق اشکال زدایی) مشاهده کنید.

از سوی دیگر ، هدف گیری مجدد به این معنی است که همان تماس های سیستم یا کتابخانه معنای دیگری دارد. آنها کار دیگری انجام می دهند ، که برای سیستم تعبیه شده منطقی است. به یک معنا ، برای printf () بگویید ، یک پیاده سازی جدید وجود دارد ، پیاده سازی مجدد آن تابع.

با گفتن همه اینها ، --specs = nosys.specs به این معنی است که ما نیمه مهمان نیستیم. این معمولاً به این معنی است که ما دوباره در حال هدف گیری مجدد هستیم. این ما را به پرچم بعدی می رساند.

nostdlib

از گزینه linker -nostdlib برای پیوند دادن برنامه ای که قصد اجرای مستقل دارد استفاده می شود. -nostdlib دلالت بر گزینه های فردی -nodefaultlibs و -nostartfiles دارد. در زیر ما دو گزینه را جداگانه مورد بحث قرار می دهیم ، اما معمولی ترین استفاده فقط nostdlib برای خرید یک مرحله ای است. هنگام اتصال برنامه میزبانی شده ، کتابخانه های سیستم استاندارد مانند libc به طور پیش فرض به هم متصل می شوند و به برنامه دسترسی به تمام توابع استاندارد (printf ، استرلن و دوستان) گزینه linker -nodefaultlibs ارتباط با آن کتابخانه های پیش فرض را غیرفعال می کند. تنها کتابخانه های مرتبط دقیقاً همان کتابخانه هایی هستند که شما با استفاده از پرچم -l به صراحت در پیوند دهنده نامگذاری می کنید.

lgcc

libgcc.a یک کتابخانه استاندارد است که زیر روال های داخلی را برای غلبه بر کاستی های ماشین های خاص ارائه می دهد. به عنوان مثال ، پردازنده ARM دستور تقسیم را شامل نمی شود. نسخه ARM libgcc.a شامل یک تابع تقسیم است و کامپایلر در صورت لزوم به آن تابع تماس می دهد.

T

این فقط راهی است که به پیوند دهنده بگویید از این فایل به عنوان اسکریپت پیوند دهنده استفاده کند. در مورد ما ، نام فایل linker.script.ld است.

o main.elf

سرانجام ، ما به پیوند دهنده می گوییم نام فایل تصویری خروجی نهایی که در دستگاه ما رایت می شود/چشمک می زند ، چگونه خواهد بود.

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

arm -none -eabi -gcc core.o -mcpu = cortex -m4 -mthumb -Wall --specs = nosys.specs -nostdlib -lgcc -T./linker.script.ld -o main.elf

ما مطمئن می شویم که فایل اسکریپت و فایل core.o هر دو در یک دایرکتوری هستند ، جایی که ما خط فرمان بالا را اجرا می کنیم.

و بدون مشکل پیوند می خورد.

یک چک

سپس اجرا می کنیم:

arm-none-eabi-nm main.elf

و دریافت می کنیم:

devchu@chubox: ~/Development/Atollic/TrueSTUDIO/STM32_workspace_9.1 $ arm-none-eabi-nm main.elf 20014000 A _estack 08000010 t main_loop 08000008 T reset_handler 08000000 T vtable

به نظر خوب میاد. دستور arm-none-eabi-nm راهی برای فهرست نمادها در فایل های شی است.

مرحله 10: آزمایش اتصال به STM32 Nucleo-64

اتصال به STM32 Nucleo-64
اتصال به STM32 Nucleo-64
اتصال به STM32 Nucleo-64
اتصال به STM32 Nucleo-64

در صورت انتخاب پذیرش ، اولین ماموریت شما این است که سیستم خود را به صفحه توسعه خود مشاهده کنید.

استفاده از ویندوز

برای ویندوز ، تصمیم گرفتم TrueSTUDIO را از Atollic (نسخه رایگان) نصب کنم. این یک نصب بدون درد بود و به طور خودکار درایور را نصب کرد ، بنابراین من می توانم از st-link برای آزمایش اتصال استفاده کنم. هنگامی که TrueSTUDIO را نصب کردم و مدیر دستگاه دستگاه را دید ، ابزارهای texan/stlink را که توسط مقاله Bare Metal که ما دنبال کرده بودیم پیشنهاد دادم. من مجدداً پوشه را مستقیماً زیر "C: \" قرار دادم ، و دوباره پیوندهایی از سطل خانه cygwin محلی خود به دستورات ایجاد کردم.

ln -s /c/STM32. MCU/stlink-1.3.0-win64/bin/st-info.exe ~/bin/st-info

به عنوان یک آزمایش اولیه برای اینکه ببینیم آیا واقعاً می توانیم با دستگاه ارتباط برقرار کنیم ، اجرا کردم:

st-info --probe

و برگشت:

1 برنامه نویس stlink پیدا شد

بنابراین در حال حاضر ما می دانیم که می توانیم از تابلوی توسعه خود صحبت کنیم.

استفاده از لینوکس

برای لینوکس ، شما واقعاً نیازی به درایور ندارید. اما برای دبیان ، باید ابزارهای st را از منبع ایجاد کنید.

git clone

مطمئن شوید libusb-1.0-0-dev را نصب کرده اید.

لیست مناسب | grep -E "*libusb.*dev*"

باید ببینی:

libusb-1.0-0-dev/xenial ، اکنون 2: 1.0.20-1 amd64 [نصب شده]

یا چیزی شبیه به آن.

برای نصب آن:

sudo apt-get install libusb-1.0-0-dev

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

sudo apt-get libusb-dev را نصب کنید

برنامه نویس libusb گم شده صحیح می تواند باعث ایجاد مشکل در cmake شود.

خطای CMake: متغیرهای زیر در این پروژه استفاده می شوند ، اما روی NOTFOUND تنظیم شده اند. لطفاً آنها را تنظیم کنید یا مطمئن شوید که در فایل های CMake به درستی تنظیم و آزمایش شده اند: LIBUSB_INCLUDE_DIR (ADVANCED)

تغییر به فهرست اصلی پروژه (… blah /blah /stlink). "آزاد کردن" را انجام دهید.

پس از ساخت ، ابزارها باید تحت ".. /build /Release" قرار گیرند.

سپس می توانید "st-info --probe" را اجرا کنید. در اینجا خروجی با Nucleo متصل است ، پس نه.

devchu@chubox: ~/Development/stlink $./build/Release/st-info --probeFound 1 برنامه نویس stlink: 303636414646353034393535363537 openocd: "\ x30 / x36 / x36 / x41 / x46 / x46 / x35 / x30 / x30 / x34 / x39 / x35 / x35 / x36 / x35 / x37 "flash: 524288 (اندازه صفحات: 2048) sram: 65536 chipid: 0x0446 descr: F303 high density device devchu@chubox: ~/Development/stlink $./build/Release/st- info --probe پیدا شد 0 stlink programmers devchu@chubox: ~/Development/stlink $

مرحله 11: اجازه دهید از GDB با لینوکس استفاده کنیم

بیایید از GDB با لینوکس استفاده کنیم
بیایید از GDB با لینوکس استفاده کنیم
بیایید از GDB با لینوکس استفاده کنیم
بیایید از GDB با لینوکس استفاده کنیم

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

وقتی این تخته های توسعه ARM را خریداری می کنید ، خواه MSP432 Launchpad از Texas Instruments باشد ، یا این موردی که ما در حال حاضر در مورد آن صحبت می کنیم ، Nucleo-F303 (STM32 Nucleo-64) ، معمولاً معمولاً با یک برنامه در حال اجرا ، معمولاً وارد می شوند. برخی از برنامه های چشمک زن که شامل فشار دادن یک کلید برای تغییر میزان نوردهی LED (ها) است.

قبل از اینکه ما در نوشتن بیش از حد سریع باشیم ، بیایید ببینیم چه چیزهایی برای دیدن و انجام وجود دارد.

با لینوکس ، یک ترمینال باز کنید ، فهرست پروژه stlink git را که ایجاد کردیم تغییر دهید و ابزار st-util را پیدا کنید.

devchu@chubox: ~/Development/stlink $ find. -نام st-util

./build/Release/src/gdbserver/st-util

آن ابزار را اجرا کنید. از آنجا که قبلاً اتصال خود را با st-info-probes آزمایش کرده ایم ، باید خروجی هایی مانند این را دریافت کنیم:

devchu@chubox: ~/Development/stlink $./build/Release/src/gdbserver/st-util

st-util 1.4.0-50-g7fafee2 2018-10-20T18: 33: 23 INFO common.c: بارگیری پارامترهای دستگاه…. 2018-10-20T18: 33: 23 INFO common.c: دستگاه متصل است: F303 دستگاه با چگالی بالا ، شناسه 0x10036446 2018-10-20T18: 33: 23 INFO common.c: اندازه SRAM: 0x10000 بایت (64 کیلوبایت) ، فلش: 0x80000 بایت (512 کیلوبایت) در صفحات 2048 بایت 2018-10-20T18: 33: 23 INFO gdb-server.c: شناسه تراشه 00000446 ، شناسه اصلی 2ba01477 است. 2018-10-20T18: 33: 23 INFO gdb-server.c: گوش دادن در *: 4242…

این سرور GDB در حال اجرا است و صفحه توسعه ما را می بیند و مهمتر از همه ، در پورت 4242 (پورت پیش فرض) گوش می دهد.

اکنون ما آماده ایم که سرویس گیرنده GDB را روشن کنیم.

در لینوکس ، ترمینال دیگری را باز کنید ، این را وارد کنید:

arm-none-eabi-gdb -tui

این دقیقاً مانند اجرای خط فرمان gdb است ، اما در عوض یک ترمینال مبتنی بر متن تولید می کند (حدس من این است که از نفرین استفاده می کند).

ما سرویس گیرنده GDB و سرور GDB را در حال اجرا داریم. با این حال ، سرویس گیرنده به سرور متصل نیست. در حال حاضر هیچ چیز در مورد Nucleo ما (یا هیئت مدیره انتخابی شما) نمی داند. ما باید به آن بگوییم. در ترمینال ، درخواست شما اکنون باید "(gdb)" باشد. وارد:

هدف کمک

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

اما ما همچنین باید مکان را به آن بدهیم. بنابراین ، در دستور (gdb) ، عبارت زیر را وارد کنید:

(gdb) target localhost از راه دور: 4242

شما باید پاسخی به شرح زیر دریافت کنید:

(gdb) target localhost از راه دور: 4242

اشکال زدایی از راه دور با استفاده از localhost: 4242 0x080028e4 in ؟؟ ()

در همین حال ، در ترمینالی که st-util gdbserver را اجرا می کند ، این را دریافت کردیم:

2018-10-20T18: 42: 30 INFO gdb-server.c: 6 رجیستر نقطه شکست hw پیدا شد

2018-10-20T18: 42: 30 INFO gdb-server.c: GDB متصل است.

مرحله 12: بیایید با Windows و برنامه خود را تکرار کنیم

بیایید تکرار کنیم ، با ویندوز و برنامه خود را فلش کنیم
بیایید تکرار کنیم ، با ویندوز و برنامه خود را فلش کنیم
بیایید تکرار کنیم ، با ویندوز و برنامه خود را فلش کنیم
بیایید تکرار کنیم ، با ویندوز و برنامه خود را فلش کنیم
بیایید تکرار کنیم ، با ویندوز و برنامه خود را فلش کنیم
بیایید تکرار کنیم ، با ویندوز و برنامه خود را فلش کنیم

مراحل اجرای st-util gdbserver و کلاینت arm-none-eabi-gdb اساساً مشابه مراحل قبل است. شما دو پایانه (cygwin ، DOS cmd یا Windows Powershell) را باز می کنید ، محل st-util را پیدا کرده ، آن را اجرا کنید. در ترمینال دیگر ، کلاینت arm-none-eabi-gdb را اجرا کنید. تنها تفاوت این است که حالت -tui (نمای متن مبتنی بر ترمینال) به احتمال زیاد پشتیبانی نمی شود.

اگر موارد بالا در ویندوز کار می کرد ، احتمالاً مجبور خواهید بود که آن را متوقف کنید (فقط مشتری). در این مرحله ، به نحوی باید کلاینت GDB را در جایی که فایل build شما قرار دارد اجرا کنید ("core.out") ، یا کل مسیر آن فایل را به عنوان آرگومان به کلاینت GDB اضافه کنید.

من زندگی خود را با استفاده از cygwin و ایجاد پیوندهایی از فهرست محلی $ HOME // bin به محل اقامت هر دو ابزار ساده کردم.

خوب ، ما مانند گذشته کامپایل و پیوند داده ایم ، و فایل main.elf را آماده نمایش داده ایم.

ما st-util را در یک پنجره اجرا می کنیم. ما سرویس گیرنده GDB را دوباره راه اندازی می کنیم ، این بار این کار را انجام می دهیم:

arm-none-eabi-gdb main.elf

ما اجازه می دهیم تا شروع به کار کند ، منتظر اعلان (gdb) باشید ، همان دستور اتصال خود را به سرور GDB (st-util) انجام دهید و ما آماده فلش کردن فایل اجرایی هستیم. این بسیار ضد آب و هوا است:

(gdb) بار

در حال اجرا با پایانه های cygwin ، یک مشکل شناخته شده وجود دارد که بعضی اوقات دستورات کنسول خروجی نمی گیرند. بنابراین در مورد ما ، پنجره ای که سرور را اجرا می کند کاملاً بی صدا بود. کسی که کلاینت را اجرا می کند ، جایی که بار را اجرا می کنیم ، این را خروجی می دهد:

بخش بارگیری.متن ، اندازه 0x1c lma 0x8000000 آدرس شروع 0x8000000 ، اندازه بار 28 نرخ انتقال: 1 کیلوبایت بر ثانیه ، 28 بایت/نوشتن.

مرحله 13: فلش کردن با لینوکس - پاداش بیشتر: D

فلش کردن با لینوکس - پاداش بیشتر: D
فلش کردن با لینوکس - پاداش بیشتر: D

مرحله 14: بیایید کمی عمیق تر شیرجه بزنیم

اگر به اینجا رسیدید ، عالی است. بیایید پیش برویم.

چرا به داخل فایل main.elf ، اجرایی نگاه نمی کنید؟ موارد زیر را اجرا کنید:

arm-none-eabi-objdump -d main.elf

شما باید یک خروجی شبیه به این ببینید:

main.elf: فرمت فایل elf32-littlearm

جداسازی بخش.text:

08000000:

8000000: 00 40 01 20 09 00 00 08.@. ….

08000008:

8000008: 4802 ldr r0، [pc، #8]؛ (8000014) 800000a: 4685 mov sp، r0 800000c: 4f02 ldr r7، [pc، #8]؛ (8000018) 800000e: 2000 movs r0، #0

08000010:

8000010: 3001 r0 اضافه می کند ، #1 8000012: e7fd b.n 8000010 8000014: 20014000.word 0x20014000 8000018: deadbeef.word 0xdeadbeef

از خروجی فوق چه قطعات کوچکی می توانیم بدست آوریم؟

اگر هنگام بحث و ایجاد فایل linker.script.ld به یاد می آورید ، اظهار داشتیم که این دستگاه های ARM دارای RAM هستند که از 0x20000000 شروع می شوند و حافظه FLASH از 0x08000000 شروع می شود.

بنابراین ، ما می توانیم ببینیم که در واقع برنامه به گونه ای است که همه در حافظه FLASH قرار دارد.

سپس ، در مرحله بالا ، اما در مرحله بعد ، هنگامی که ما در مورد بخش "سلام جهان" بحث می کردیم ، گزاره ای وجود داشت که در آن مقدار فوری ، ثابت و واقعی ("0xDEADBEEF") را در یک هسته اصلی MCU ("R7") بارگذاری می کنیم.

بیانیه این بود:

LDR R7 ، = 0xDEADBEEF

در کد ما ، این تنها جایی است که ما حتی DEADBEEF را ذکر می کنیم. هیچ جای دیگر. و با این وجود ، اگر به دستورالعمل های جدا شده/بازسازی شده و غیره نگاه کنید ، موارد بیشتری در مورد DEADBEEF وجود دارد که ما فکر می کردیم.

بنابراین ، کامپایلر/پیوند دهنده به نحوی تصمیم گرفت که مقدار DEADBEEF را به صورت FLASH در محل 0x8000018 به طور دائم فلش کند. و سپس ، کامپایلر دستورالعمل LDR فوق ما را به صورت زیر تغییر داد:

LDR R7 ، [PC ، #8]

حتی برای ما نظر ایجاد کرد. چقدر زیبا. و به ما می گوید که مقدار شمارنده فعلی برنامه (ثبت PC) را بگیرید ، 0x8 را به آن مقدار اضافه کنید ، و آنجاست که DEADBEEF سوزانده شده است ، و این مقدار را دریافت کرده و آن را در R7 وارد کنید.

بنابراین این بدان معناست که شمارنده برنامه (PC) به آدرس 0x8000010 ، که شروع main_loop است ، اشاره می کند و مقدار DEADBEEF پس از پایان main_loop در دو آدرس قرار دارد.

مرحله 15: در نهایت ، نگاهی اجمالی به برنامه در حال اجرا

حتی اگر GDB را ترک کردید ، فقط دوباره فرمان را وارد کنید. شما حتی مجبور نیستید هیچ فایلی به آن بدهید. ما دیگر چشمک نمی زنیم ، فقط آن را اجرا می کنیم.

پس از اتصال مجدد سرویس گیرنده GDB به سرور GDB ، در خط فرمان (gdb):

(gdb) اطلاعات ثبت می شود

شما باید چیزی شبیه به این را ببینید:

r0 0x0 0

r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 sp 0x20014000 0x20014000 lr 0xff8000000000000000000000000000000

اما سپس ، در اعلان (gdb) ، عبارت زیر را وارد کنید:

(gdb) ادامه دهید

و خیلی سریع CTRL-C را فشار داد. این باید برنامه را متوقف کند. دوباره دستور "info registers" را وارد کنید.

این بار ، متفاوت به نظر می رسد:

(gdb) اطلاعات ثبت می شود

r0 0x350ffa 3477498 r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0xdeadbeef 3735928559 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0ff 00x00x00x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 16777216

چی شد؟ دقیقاً همان چیزی که می خواستیم. DEADBEEF در R7 بارگذاری شد و R0 (بسیار سریع) در حال افزایش است. در صورت تکرار ، دوباره R0 را با مقدار دیگری مشاهده خواهید کرد.

مرحله 16: ما می خواستیم یک آرایه فقط برای خواندن در Flash ایجاد کنیم

یکی از راه های ایجاد معادل یک آرایه با استفاده از اسمبلی و دستورالعمل ها به شرح زیر است:

.type myarray،٪ object // نام یا برچسب 'myarray' به عنوان یک نوع شی تعریف می شود.

myarray: // این شروع بیانیه "myarray" // است (از چه چیزی تشکیل خواهد شد)..word 0x11111111 // اولین عضو یا مقدار موجود در 'myarray'..word 0x22222222 // مقدار دوم (آدرس های مجاور)..word 0x33333333 // و غیره.size myarray،.-myarray // کامپایلر/اسمبلر اکنون می داند که انتهای یا // مرز "myarray" کجاست.

اکنون که آن را در حافظه FLASH تنظیم کرده ایم ، می توانیم از آن در برنامه استفاده کنیم. در زیر قسمتی آمده است:

LDR R1 ، myarray // این داده های موجود در محل اول "myarray" را بارگیری می کند. " // این چیزی نیست که ما می خواهیم.

LDR R1 ، = myarray // این مقدار مکان را بارگذاری می کند (آدرس 1) ،

// نه داده ها.. // این همان چیزی است که ما می خواهیم.

MOV R2 ، #0 // R2 یک شمارش را حفظ می کند تا مطمئن شویم که راه نیفتاده ایم

// انتهای آرایه. LDR R3 ، = myarrsize // R3 معادل "myarrsize" خواهد بود.

// R0 داده های ما را نگه می دارد

main_loop:

LDR R0 ، [R1] // داده هایی را که R1 ('myarray') به آن اشاره کرده اند در R0 بارگذاری کنید. CMP R2، R3 // آیا در محدوده آرایه هستیم؟ BEQ main_loop // اگر تمام شدیم ، کارمان تمام شد ، بنابراین فقط برای همیشه حلقه می زنیم.

ADD R2 ، #1 // در غیر این صورت ، می توانیم از طریق آرایه تکرار کنیم.

ADD R1 ، #4 // 4 را برای ثبت R1 اضافه کنید ، بنابراین به درستی به بعدی اشاره می کند

// نشانی..

B main_loop // برگشت به عقب.

ویدیو همه اینها را می گذراند و اشکالی در آن وجود دارد. خوبه؛ نشان می دهد که کد اجرا و اشکال زدایی مهم است. این یک مورد کلاسیک از خروج از انتهای یک آرایه را نشان می دهد.

توصیه شده: