جدول المحتويات:
- الخطوة 1: الاختبار الأولي للجهاز
- الخطوة 2: الأساسيات
- الخطوة 3: الأساسيات - Windows
- الخطوة 4: ما هي الأساسيات
- الخطوة 5: ملف الرابط
- الخطوة 6: جدول المتجهات
- الخطوة 7: إصدار التجميع لبرنامج "Hello World"
- الخطوة 8: تجميع الكود
- الخطوة 9: ربط البرنامج
- الخطوة 10: اختبار الاتصال بـ STM32 Nucleo-64
- الخطوة 11: لنستخدم GDB مع Linux
- الخطوة 12: دعنا نكرر ، مع Windows و Flash برنامجنا
- الخطوة 13: التفليش بنظام Linux - مكافأة أكثر: د
- الخطوة 14: دعنا نتعمق قليلاً
- الخطوة 15: أخيرًا ، نظرة سريعة على البرنامج قيد التشغيل
- الخطوة 16: أردنا إنشاء صفيف للقراءة فقط في Flash
فيديو: الجزء 1 ARM Assembly TI RSLK Robotics Learning Curriculum Lab 7 STM32 Nucleo: 16 Steps
2024 مؤلف: John Day | [email protected]. آخر تعديل: 2024-01-30 07:38
يركز هذا Instructable على وحدة التحكم الدقيقة STM32 Nucleo. الدافع وراء ذلك لتكون قادرًا على إنشاء مشروع تجميع من العظام. سيساعدنا هذا على التعمق في فهم مشروع MSP432 Launchpad (TI-RSLK) الذي كان موضوعًا للعديد من Instructables بالفعل.
لا توجد مساعدة كبيرة عبر الإنترنت لإنشاء مشروع تجميع فقط لـ MSP432 ، باستخدام Code Composer Studio. حتى الآن كنا نقوم فقط بالنسخ / اللصق من مشروع تجميع موجود مسبقًا. لقد خدمنا هذا النهج بشكل جيد.
ومع ذلك ، الآن ، بالنسبة للمختبر 7 ، واجهتنا مشكلة صغيرة. أو على الأقل زوبعة مؤقتة. يقدم المختبر 7 آلات الحالة المحدودة ، وأول ما نواجهه هو الحاجة إلى إنشاء مجموعة من القيم واستخدامها. نظرًا لأن دورة TI تستخدم بشكل أساسي برمجة C - فهذه ليست مشكلة. لكن هذه Instructables ركزت على التجميع ، وليس C.
علاوة على ذلك ، نظرًا لأن المصفوفة ذات قيم للقراءة فقط ، فسيكون من الجيد وضعها في ذاكرة فلاش ، وليس ذاكرة الوصول العشوائي.
يبدو أن هناك الكثير من المساعدة عبر الإنترنت لمشاريع التجميع باستخدام STM32 MCU ، وبالتالي ، نبدأ بهذا Instructable ، بهدف استخدام ما تم تعلمه ، لتطبيقه بعد ذلك على MSP432 و Code Composer Studio.
في الطريق إلى هذا الهدف ، حصلنا أيضًا على خبرة مع وحدة تحكم دقيقة أخرى شائعة.
الخطوة 1: الاختبار الأولي للجهاز
مرة أخرى ، لماذا تختار STM32 Nucleo على وجه الخصوص؟
بكل صراحه؟ لأنني كنت أبحث عن مقالات جيدة حول مشاريع تجميع المعادن العارية لوحدات تحكم ARM ، وقد صادفت هذه السلسلة. وأيضًا لأن STM32 يبدو أنه MCU مشهور.
لقد أجريت بعض الأبحاث (هناك الكثير من الإصدارات للاختيار من بينها - انظر الصورة أعلاه) ، ولكن في النهاية أصبح ما يمكنني الحصول عليه بالفعل ، لأنني كنت سأستخدم Amazon (في الولايات المتحدة).
يأتي في حزمة بسيطة ولكنها احترافية ، مع بعض تعليمات بدء التشغيل. كان من المضحك بعض الشيء أن نرى أن العرض التوضيحي الذي تم حرقه في وحدة التحكم كان تقريبًا بالضبط ما فعلناه في Instructables السابقة - يومض مصباح LED ويغير السرعة وفقًا للضغط على زر.
يبدو أن لوحة التطوير هذه تشبه إلى حد بعيد MSP432 من حيث وجود 2 LED وزر ضغط مستخدم واحد. يحتوي MSP432 على زري مستخدم.
كما ترون في الصور ، لقد شعرت بالدهشة بعض الشيء لأن اللوحة بها USB صغير وليس micro USB. اضطررت إلى نفاد لشراء سلك.
اختبار جيد آخر هو أنه عند توصيله بجهاز الكمبيوتر الخاص بك (أنا أستخدم مربع Linux) ، فإنه يظهر في مدير الملفات الخاص بي ، كنظام ملفات يسمى "NODE_F303RE". الفتح الذي يكشف عن ملفين ، أحدهما HTML والآخر نص.
هذا كل شيء ، ولكن على الأقل تقول أيضًا أن الاتصال يبدو سهلاً للغاية.
الآن نحن جاهزون للبدء.
سأحاول عدم تكرار أي من المعلومات الجيدة من سلسلة مقالات IVONOMICON Bare Metal ، ولكن بدلاً من ذلك سأقوم بتكرارها.
الخطوة 2: الأساسيات
أول شيء نحتاجه هو مترجم.
وبعد ذلك ، نحتاج إلى مصحح أخطاء:
devchu @ chubox: ~ $ sudo apt-get install gdb-arm-none-eabiReading لقوائم الحزم … تم بناء شجرة التبعية قراءة معلومات الحالة … تم الانتهاء سيتم تثبيت الحزم الجديدة التالية: تمت ترقية gdb-arm-none-eabi 0 ، 1 حديثًا مثبتة ، 0 للإزالة و 8 لم تتم ترقيتها. تحتاج إلى الحصول على 722 كيلوبايت من المحفوظات. بعد هذه العملية ، سيتم استخدام 7،738 كيلو بايت من مساحة القرص الإضافية. احصل على: 1 https://us.archive.ubuntu.com/ubuntu xenial / universe amd64 gdb-arm-none-eabi amd64 7.10-1ubuntu3 + 9 [2، 722 kB] تم جلب 2، 722 كيلو بايت في 1 ثانية (1، 988 كيلو بايت / ثانية) تحديد الحزمة غير المحددة مسبقًا gdb-arm-none-eabi. (جارٍ قراءة قاعدة البيانات … تم تثبيت 262428 ملفًا وأدلة.) جارٍ التحضير لفك حزم … / gdb-arm-none-eabi_7.10-1ubuntu3 + 9_amd64.deb … تفريغ حزم gdb-arm-none-eabi (7.10-1ubuntu3 + 9) … المعالجة مشغلات لـ man-db (2.7.5-1) … إعداد gdb-arm-none-eabi (7.10-1ubuntu3 + 9) …
الخطوة 3: الأساسيات - Windows
افترضت الخطوة أعلاه أننا نستخدم Linux. ماذا لو كنا نستخدم Windows؟
يمكنك الذهاب إلى موقع arm Developer ، وهناك العديد من خيارات التنزيل المتاحة. أنا أستخدم جهاز Windows 8.
أثناء التثبيت ، اخترت تثبيته على محرك الأقراص الجذر "C: \" بدلاً من Program Files لمجرد أنني أستخدم أيضًا cygwin ، وكان من الأسهل إنشاء رابط من الحاوية المحلية إلى مجلد جذر C: أكثر من كل العبث في المسار إلى Program Files (بمسافات ، إلخ).
وبالتالي ، فإن بيئة ومسار cygwin ، وما إلى ذلك ، تبدو كما يلي:
C: / cygwin64 / home / bin / arm-none-eabi-gcc ، حيث يمثل arm-none-eabi-gcc رابطًا لـ C: / GNUToolsArmEmbedded / 7.2018.q2.update / bin / arm-none-eabi- مجلس التعاون الخليجي.
بعد ذلك قمت بإنشاء مجلد "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 ، أي ما يمثله مجلس التعاون الخليجي في دول مجلس التعاون الخليجي.
تم اقتراح تثبيت حزمة آخر هو "libnewlib-arm-none-eabi". ما هذا؟
Newlib هي مكتبة C ومكتبة للرياضيات مخصصة للاستخدام على الأنظمة المضمنة. إنها مجموعة من أجزاء مكتبة متعددة ، كل ذلك بموجب تراخيص البرامج المجانية التي تجعلها قابلة للاستخدام بسهولة على المنتجات المضمنة.
وأخيرًا الحزمة "libstdc ++ - arm-none-eabi". هذا واضح جدا. إنها مكتبة C ++ للمترجم المتقاطع ؛ لوحدات التحكم الدقيقة المدمجة في ARM.
الخطوة 5: ملف الرابط
لنقم بإنشاء نص رابط.
سيكون أحد الأجزاء الرئيسية أو الكتلة في هذا الملف هو أمر الذاكرة.
- من sourceware.org:
يسمح التكوين الافتراضي للرابط بتخصيص كل الذاكرة المتوفرة. يمكنك تجاوز هذا باستخدام الأمر MEMORY يصف الأمر MEMORY موقع وحجم كتل الذاكرة في الهدف. يمكنك استخدامه لوصف مناطق الذاكرة التي يمكن للرابط استخدامها ، ومناطق الذاكرة التي يجب تجنبها. يمكنك بعد ذلك تخصيص أقسام لمناطق ذاكرة معينة ، حيث يقوم الرابط بتعيين عناوين الأقسام بناءً على مناطق الذاكرة ، وسيحذر من المناطق التي أصبحت ممتلئة للغاية. لن يقوم الرابط بتبديل الأقسام لتلائم المناطق المتاحة. قد يحتوي نص الرابط على العديد من استخدامات الأمر MEMORY ، ومع ذلك ، يتم التعامل مع جميع كتل الذاكرة المحددة كما لو تم تحديدها داخل أمر MEMORY واحد.:
ذاكرة
{الاسم [(attr)]: الأصل = الأصل ، LENGTH = len…}
المثال في المقال:
/ * تحديد نهاية ذاكرة الوصول العشوائي والحد الأقصى لذاكرة المكدس * // * (4KB SRAM على خط STM32F031x6 ، 4096 = 0x1000) * / / * (تبدأ ذاكرة الوصول العشوائي عند العنوان 0x20000000) _estack = 0x20001000 ؛
ذاكرة
{FLASH (rx): الأصل = 0x08000000 ، الطول = 32 كيلو بايت من ذاكرة الوصول العشوائي (rxw): الأصل = 0x20000000 ، الطول = 4K}
لذلك نحتاج إلى معرفة مقدار FLASH (لبرنامجنا وثوابتنا ، إلخ) ومقدار ذاكرة الوصول العشوائي (للاستخدام بواسطة البرنامج ؛ الكومة والمكدس ، إلخ) للوحة الخاصة بنا. هذا يصبح مثيرا بعض الشيء.
تقول البطاقة الصغيرة اللطيفة التي تأتي مع Nucleo أن بها ذاكرة فلاش 512 كيلو بايت ، و SRAM 80 كيلو بايت. ومع ذلك ، عند توصيله بـ USB ، يتم تثبيته كنظام ملفات يحتوي على ملفين ، ويشير كل من مدير الملفات و GParted إلى أنه يحتوي على أكثر من 540 كيلو بايت من المساحة. (الرامات الذاكرة العشوائية في الهواتف والحواسيب؟).
ولكن ، في محاولة لحذف الملفين باستخدام مدير الملفات ، وفصل الجهاز ثم إعادة توصيله ، لا يزال يظهر الملفين. (وتعرف مدير الملفات على شيء ما بسبب وجود رمز "قفل" صغير على كل ملف.
لذلك دعونا نذهب مع الأرقام الموجودة على البطاقة. والآن نأخذ المثال أعلاه ونحوله إلى لوحة محددة لدينا.
قد ترغب في استخدام شيء مثل محول الذاكرة عبر الإنترنت ، للانتقال من KB العام إلى عدد محدد من البايتات.
ثم قد ترغب في استخدام عشري على الإنترنت لتحويل سداسي عشري.
/ * تحديد نهاية ذاكرة الوصول العشوائي والحد الأقصى لذاكرة المكدس * /
/ * (4KB SRAM على خط STM32F031x6 ، 4096 = 0x1000) * // * المثال * /
/ * الخطوة 1: (80 كيلوبايت SRAM على STM32F303RE ، 81920 = 0x14000) * // * لوحتنا * /
/ * الخطوة 2 ، أضف الحجم السداسي إلى عنوان البداية السداسي عشرية (أدناه). * /
/ * (ذاكرة الوصول العشوائي تبدأ على العنوان 0x20000000) * /
_estack = 0x20001000 ؛ /* المثال */
_estack = 0x20014000 ؛ / * مجلسنا * /
ذاكرة {
FLASH (rx): الأصل = 0x08000000 ، الطول = 512 كيلو
ذاكرة الوصول العشوائي (rxw): الأصل = 0x20000000 ، الطول = 80 كيلو
}
دعنا نسمي الملف أعلاه "linker.script.ld".
الخطوة 6: جدول المتجهات
سنقوم الآن بإنشاء ملف تجميع صغير (مع توجيهات) للقيام ببعض معالجة المقاطعة الأساسية للغاية. سنتبع مثال المقالة وننشئ ملفًا باسم "core. S".
مرة أخرى ، ها هو مثال لمحتويات الملف ، لكنني أجريت تغييرًا على السبورة الخاصة بنا:
// تحدد هذه التعليمات سمات شرائحنا و
// لغة التجميع التي سنستخدمها:.syntax unified / * انظر أدناه بعد منطقة الكود هذه * / /*.cpu cortex-m0 * / / * قم بالتعليق على هذا السطر من المثال * /.cpu cortex-m4 / * أضف بدلاً من ذلك قشرة مجلسنا. انظر الصورة أعلاه في هذه الخطوة * / /*.fpu softvfp * / / * قم بالتعليق على هذا السطر من المثال * /.fpu vfpv4 / * أضف بدلاً من ذلك مجلسنا ؛ لديها FPU * /.thumb // مواقع الذاكرة العالمية..global vtable.global reset_handler / * * جدول المتجه الفعلي. * يتم تضمين فقط حجم ذاكرة الوصول العشوائي ومعالج "إعادة التعيين" ، من أجل التبسيط. * /.type vtable،٪ object vtable:.word _estack.word reset_handler.size vtable،.-vtable
حسنًا.. لا توجيه ". محاذاة"
ومع ذلك ، هذا ليس حرجًا. المزيد عن ذلك (ربما) لاحقًا.
.syntax موحد
.syntax [موحد | منقسم]
يحدد هذا التوجيه صيغة مجموعة التعليمات كما هو موضح في قسم ARM-Instruction-Set
9.4.2.1 بناء جملة مجموعة التعليمات هناك تركيبان مختلفان قليلاً يدعمان تعليمات ARM و THUMB. يستخدم الإعداد الافتراضي ، المقسم ، النمط القديم حيث كان لتعليمات ARM و THUMB تراكيب منفصلة خاصة بها. بناء الجملة الجديد الموحد ، والذي يمكن تحديده من خلال التوجيه.syntax.
.fpu vfpv4
يمكن لمترجم دول مجلس التعاون الخليجي إنتاج ثنائيات مع العديد من الخيارات فيما يتعلق بالنقطة العائمة: ناعم - مناسب للتشغيل على وحدة المعالجة المركزية بدون FPU - يتم إجراء الحسابات في البرنامج بواسطة برنامج التحويل البرمجي softfp - مناسب للتشغيل على وحدة المعالجة المركزية مع FPU أو بدونه - سيستخدم FPU إذا كان موجودًا. بالنسبة لحالتنا المحددة (سيتعين عليك إجراء البحث الخاص بك) ، تتوافق وحدة FPU الخاصة باللوحة المعينة مع vfpv4. قد تضطر إلى اللعب بهذا. أو حتى اتركه في softfp.
.thumb (مقابل.arm)
تحتوي وحدة التحكم الدقيقة ARM هذه في الواقع على مزيج من مجموعات التعليمات. واحد هو ARM ، والآخر هو THUMB. أحد الاختلافات هو تعليمات 16 بت مقابل إرشادات 32 بت. وبالتالي ، فإن هذا التوجيه يخبر المترجم أن يتعامل مع التعليمات اللاحقة على أنها إما THUMB أو ARM.
سنأخذ ما تبقى من الملف كما هو لأن هذه التعليمات لم تتعمق بعد في برمجة التجميع المدفوعة بالمقاطعة.
الخطوة 7: إصدار التجميع لبرنامج "Hello World"
يمكن أن ينتقل ما يلي أيضًا إلى ملف "core. S" الذي تم إنشاؤه مسبقًا. هذا ، مرة أخرى ، من المثال في المقالة.
/ * * معالج إعادة التعيين. استدعاء عند إعادة تعيين. * /.type reset_handler،٪ function reset_handler: // اضبط مؤشر المكدس على نهاية المكدس. // يتم تحديد قيمة "_estack" في نص الرابط الخاص بنا. 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.
إذا كنت تتابع مع Instructables بخصوص MSP432 ودورة / مختبرات TI-RSLK ، فيجب أن يكون كل البرنامج أعلاه مألوفًا لك.
الشيء الوحيد الذي يمكنني رؤيته هو استخدام "=" عند تحميل "DEADBEEF" لتسجيل R7. لم نستخدم ذلك.
يحتوي الملف "core. S" المرفق هنا الآن على المصدر الكامل.
الخطوة 8: تجميع الكود
حان الوقت للقيام ببعض مهام سطر الأوامر. شيء حقيقي ، أخيرًا.
ومع ذلك ، نحن لسنا هناك تمامًا. علينا مرة أخرى تعديل الأمر الوارد في المقالة ، وتعديله حسب حالتنا.
هذا هو رمز المثال:
مجمع arm-none-eabi-gcc -x-with-cpp -c -O0 -mcpu = cortex-m0 -mthumb -Wall core. S -o core.o
إذا انتقلنا إلى موقع gnu.org الخاص بـ GCC ، (في هذه الحالة الإصدار 7.3) ،
x
- x لتحديد اللغة. وإلا إذا كان no -x ، فسيحاول المترجم التخمين باستخدام امتداد الملف. (في حالتنا *. S).
يحدد المثال أعلاه من المقالة المُجمّع مع cpp ، لكن يمكننا فقط عمل المُجمّع.
ج
يقول -c ترجمة ولكن لا تربط.
O0
-O هو ضبط مستوى التحسين. يشير استخدام -O0 (oh-zero) إلى "تقليل وقت الترجمة وجعل التصحيح ينتج عنه النتائج المتوقعة. هذا هو الإعداد الافتراضي".
mcpu = القشرة- m0
تحدد وحدة المعالجة المركزية -mcpu اسم المعالج الهدف. في حالتنا ، سيكون cortex-m4.
الإبهام
يحدد الإبهام -mthumb الاختيار بين إنشاء الكود الذي ينفذ حالات ARM و THUMB.
حائط
-الجدار بالطبع شائع جدًا ومعروف. يتم تشغيل جميع أعلام التحذير.
أخيرًا ، في نهاية الأمر ، لدينا ملف الإدخال core. S وملف الإخراج core.o.
هذا هو سطر الأوامر الجديد الناتج ليناسب حالتنا المحددة.
arm-none-eabi-gcc -x المجمع -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
لقد رأيت معظم ما سبق. يوجد أدناه ما هو جديد.
النوعية = nosys.specs
هذا واحد من الصعب بعض الشيء شرحه.
يتعلق الأمر بـ "الاستضافة شبه" و "إعادة الاستهداف" ، ويتعلق بالإدخال / الإخراج. كما أن لها علاقة باستدعاءات النظام والمكتبات.
عادةً ، لا توفر الأنظمة المضمنة أجهزة إدخال / إخراج قياسية. قد يؤثر ذلك على استدعاءات النظام أو المكتبة (مثال: printf ()).
يعني Semihosting أن مصحح الأخطاء (انظر صورة الخطوة 11 مع جزء مصحح الأخطاء محاط بدائرة باللون الأحمر) له قناة خاصة ويستخدم بروتوكول الاستضافة شبه ، ويمكنك رؤية إخراج printf () على الجهاز المضيف (عبر مصحح الأخطاء).
من ناحية أخرى ، فإن إعادة الاستهداف تعني أن مكالمات النظام أو المكتبة نفسها تعني شيئًا آخر. يفعلون شيئًا آخر ، وهذا أمر منطقي بالنسبة للنظام المضمن. بمعنى ما ، على سبيل المثال لـ printf () ، هناك تطبيق جديد ، تنفيذ مُعاد توجيهه لتلك الوظيفة.
بعد قولي هذا كله ، فإن --specs = nosys.specs يعني أننا لن نقوم باستضافة شبه. هذا يعني عادةً أننا نعيد الاستهداف. هذا يقودنا إلى العلم التالي.
نوستدليب
يتم استخدام خيار الرابط -nostdlib لربط برنامج يهدف إلى تشغيل مستقل. -nostdlib يتضمن الخيارات الفردية -nodefaultlibs و -nostartfiles. فيما يلي نناقش الخيارين بشكل منفصل ، ولكن الاستخدام الأكثر شيوعًا هو مجرد nostdlib للتسوق الشامل. عند ربط برنامج مستضاف ، يتم ربط مكتبات النظام القياسية مثل libc افتراضيًا ، مما يتيح للبرنامج الوصول إلى جميع الوظائف القياسية (printf ، و strlen والأصدقاء). خيار الرابط - nodefaultlibs يعطل الارتباط بهذه المكتبات الافتراضية ؛ المكتبات الوحيدة المرتبطة هي بالضبط تلك التي قمت بتسميتها صراحةً للرابط باستخدام العلامة -l.
lgcc
libgcc.a هي مكتبة قياسية توفر إجراءات فرعية داخلية للتغلب على أوجه القصور في أجهزة معينة. على سبيل المثال ، لا يتضمن معالج ARM تعليمات القسمة. يتضمن إصدار ARM من libgcc.a وظيفة قسمة ويصدر المترجم استدعاءات لهذه الوظيفة عند الحاجة.
ت
هذه مجرد طريقة لإخبار الرابط باستخدام هذا الملف كبرنامج نصي للرابط. في حالتنا ، اسم الملف هو 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
مهمتك الأولى ، إذا اخترت قبولها ، هي جعل نظامك يرى لوحة التطوير الخاصة بك.
باستخدام Windows
بالنسبة لنظام التشغيل Windows ، قررت تثبيت 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
نحن نعلم الآن أنه يمكننا التحدث / الاستعلام عن لوحة التطوير الخاصة بنا.
باستخدام لينكس
بالنسبة إلى نظام التشغيل Linux ، لا تحتاج حقًا إلى سائق. لكن بالنسبة إلى Debian ، سيتعين عليك بناء أدوات st من المصدر.
استنساخ بوابة
تأكد من تثبيت 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 install libusb-dev
يمكن أن يتسبب libusb dev المفقود في حدوث مشكلات في 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 programmers serial: 3036364146463530343935363537 openocd: "\ x30 / x36 / x36 / x41 / x46 / x46 / x35 / x30 / x34 / x39 / x35 / x35 / x36 / x35 / x37 "فلاش: 524288 (حجم الصفحة: 2048) sram: 65536 chipid: 0x0446 descr: F303 جهاز عالي الكثافة devchu @ chubox: ~ / Development / stlink $./build/Release/st- info --probe تم العثور على 0 مبرمجين stlink devchu @ chubox: ~ / Development / stlink $
الخطوة 11: لنستخدم GDB مع Linux
إذا كنت تحاول كل هذا ، وقد وصلت إلى هذا الحد - رائع! ممتاز. دعنا نمرح قليلا الآن.
عندما تشتري لوحات تطوير ARM هذه ، سواء كانت MSP432 Launchpad من Texas Instruments ، أو هذه اللوحة التي نناقشها الآن ، Nucleo-F303 (STM32 Nucleo-64) ، فإنها تصل عادةً مع برنامج قيد التشغيل ، عادةً بعض البرامج الوامضة التي تتضمن أيضًا الضغط على مفتاح لتغيير معدل وميض (مؤشرات) LED.
قبل أن نفرط في الكتابة بسرعة ، دعونا نرى ما الذي يمكن رؤيته والقيام به.
باستخدام Linux ، افتح Terminal ، وقم بتغيير دليل مشروع stlink git الذي أنشأناه للتو ، وابحث عن أداة st-util.
devchu @ chubox: ~ / Development / stlink $ find. -الاسم شارع الاستخدام
./build/Release/src/gdbserver/st-util
قم بتشغيل تلك الأداة. نظرًا لأننا سبق أن اختبرنا اتصالنا بـ st-info --probe ، يجب أن نحصل على بعض المخرجات مثل:
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 ، معرف Core هو 2ba01477. 2018-10-20T18: 33: 23 INFO gdb-server.c: الاستماع عند *: 4242…
هذا هو خادم GDB قيد التشغيل الآن ، وهو يرى لوحة التطوير الخاصة بنا ، والأهم من ذلك ، أنه يستمع على المنفذ 4242 (المنفذ الافتراضي).
نحن الآن جاهزون لإطلاق عميل GDB.
في Linux ، افتح Terminal آخر ، أدخل هذا:
arm-none-eabi-gdb -tui
هذا تمامًا مثل تشغيل سطر الأوامر gdb بدقة ، ولكنه ينتج بدلاً من ذلك محطة قائمة على النص (أعتقد أنه يستخدم الشتائم).
لدينا عميل GDB وخادم GDB قيد التشغيل. ومع ذلك ، فإن العميل غير متصل بالخادم. في الوقت الحالي ، لا يعرف شيئًا عن Nucleo (أو مجلس الإدارة الذي تختاره). علينا أن نقول ذلك. في المحطة ، يجب أن يكون موجهك الآن "(gdb)". يدخل:
هدف المساعدة
سوف يعطيك قائمة. لاحظ أن الشخص الذي نريده هو هدف بعيد المدى - استخدم جهاز كمبيوتر بعيد عبر خط تسلسلي.
ولكن علينا أيضًا تحديد الموقع. لذلك ، في موجه (gdb) ، أدخل:
(gdb) الهدف المضيف المحلي البعيد البعيد: 4242
يجب أن تحصل على رد مثل هذا:
(gdb) الهدف المضيف المحلي البعيد البعيد: 4242
التصحيح عن بعد باستخدام المضيف المحلي: 4242 0x080028e4 in ؟؟ ()
في هذه الأثناء ، في المحطة التي تشغل st-util gdbserver ، حصلنا على هذا:
2018-10-20T18: 42: 30 INFO gdb-server.c: تم العثور على سجلات نقاط توقف 6 ساعات
2018-10-20T18: 42: 30 INFO gdb-server.c: GDB متصل.
الخطوة 12: دعنا نكرر ، مع Windows و Flash برنامجنا
خطوات تشغيل st- تفتح محطتين (cygwin ، DOS cmd ، أو Windows Powershell) ، ابحث عن موقع st-util ، وقم بتشغيله. في المحطة الأخرى ، قم بتشغيل عميل arm-none-eabi-gdb. الاختلاف الوحيد هو أن الوضع -tui (عرض النص المستند إلى المحطة الطرفية) غير مدعوم على الأرجح.
إذا نجح ما سبق في Windows ، فربما يتعين عليك التوقف (العميل فقط). في هذه المرحلة ، ستحتاج بطريقة ما إلى تشغيل عميل GDB حيث يكون ملف الإنشاء ("core.out") ، أو إضافة المسار بالكامل إلى هذا الملف كوسيطة لعميل GDB.
لقد قمت بتبسيط حياتي باستخدام cygwin وإنشاء روابط من دليل $ HOME // bin المحلي الخاص بي إلى مكان تواجد هاتين الأداتين.
حسنًا ، لقد قمنا بالتجميع والربط تمامًا كما كان من قبل ، ولدينا ملف main.elf جاهز ليتم وميضه.
لدينا st- استخدام الجري في نافذة واحدة. نعيد تشغيل عميل GDB ، وهذه المرة نقوم بما يلي:
arm-none-eabi-gdb main.elf
نتركه يبدأ ، وانتظر موجه (gdb) ، ونفّذ أمر الاتصال نفسه بخادم GDB (st-util) ، ونحن مستعدون لفلاش الملف القابل للتنفيذ. إنه مضاد للغاية للمناخ:
(gdb) تحميل
عند التشغيل باستخدام محطات cygwin ، هناك مشكلة معروفة تتعلق بعدم إخراج أوامر وحدة التحكم في بعض الأحيان. لذلك في حالتنا ، كانت النافذة التي تشغل الخادم صامتة تمامًا. الشخص الذي يقوم بتشغيل العميل ، حيث قمنا بتشغيل الحمل ، أخرج هذا:
نص قسم التحميل ، الحجم 0x1c lma 0x8000000 عنوان البدء 0x8000000 ، حجم التحميل 28 معدل النقل: 1 كيلوبايت / ثانية ، 28 بايت / كتابة.
الخطوة 13: التفليش بنظام Linux - مكافأة أكثر: د
الخطوة 14: دعنا نتعمق قليلاً
إذا وصلت إلى هنا ، فهذا ممتاز. هيا لنذهب.
لماذا لا تنظر داخل ملف main.elf ، الملف القابل للتنفيذ؟ قم بتشغيل ما يلي:
arm-none-eabi-objdump -d main.elf
يجب أن ترى ناتجًا مثل هذا:
main.elf: تنسيق الملف elf32-littlearm
تفكيك القسم. النص:
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 هذه بها ذاكرة وصول عشوائي تبدأ من 0x20000000 ، وأن ذاكرة FLASH تبدأ من 0x08000000.
وبالتالي ، يمكننا أن نرى أن البرنامج موجود بالفعل في ذاكرة فلاش.
بعد ذلك ، أعلاه ، ولكن في وقت لاحق ، عندما كنا نناقش جزء "Hello World" ، كان هناك بيان حيث نقوم بتحميل قيمة حرفية فورية وثابتة ("0xDEADBEEF") في سجل MCU الأساسي ("R7").
البيان كان:
LDR R7 ، = 0xDEADBEEF
في الكود الخاص بنا ، هذا هو المكان الوحيد الذي نذكر فيه DEADBEEF. لا مكان اخر. ومع ذلك ، إذا نظرت إلى الإرشادات المفككة / المعاد بناؤها أعلاه ، وما إلى ذلك ، فهناك المزيد من المعلومات المتعلقة بـ DEADBEEF مما كنا نظن أننا فعلناه.
لذلك ، قرر المترجم / الرابط بطريقة ما أن يقوم بشكل دائم بميض قيمة DEADBEEF إلى عنوان FLASH ، في الموقع 0x8000018. وبعد ذلك ، قام المترجم بتغيير تعليمات LDR أعلاه لتكون:
LDR R7 ، [الكمبيوتر ، رقم 8]
حتى أنه ولّد تعليقًا لنا. كم هو جميل. ويخبرنا أن نأخذ قيمة عداد البرنامج الحالي (سجل الكمبيوتر الشخصي) ، ونضيف 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 0 x0 0 r11 0x0 0 r12 0x0 0 sp 0x20014000 0x20014000 lr 0xffffffff 4294967 0x0000 جهاز الكمبيوتر 0x8000008 0x8000008 cpsr
ولكن بعد ذلك ، في موجه (gdb) ، أدخل:
(gdb) تابع
وضرب بسرعة CTRL-C. يجب أن يوقف البرنامج. أدخل أمر "سجلات المعلومات" مرة أخرى.
هذه المرة ، يبدو الأمر مختلفًا:
(gdb) سجلات المعلومات
r0 0x350ffa 3477498 r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0 x0 0 r6 0x0 0 r7 0xdeadbeef 3735928559 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0 x0 0 r1210 0x0 0 sp 0x20014000 0x20014000 lrfffffff29 c 4200 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 // يقوم بتحميل قيمة الموقع نفسها (العنوان الأول) ،
// ليست البيانات.. // هذا ما نريده.
MOV R2 ، # 0 // R2 سيحتفظ بالعد للتأكد من أننا لا نغادر
// نهاية المصفوفة. LDR R3 ، = myarrsize // R3 ستكون مكافئة لـ 'myarrsize'.
// ستحتفظ R0 ببياناتنا
الحلقة_الرئيسية:
LDR R0 ، [R1] // قم بتحميل البيانات المشار إليها بواسطة R1 ("myarray") في R0. CMP R2 ، R3 // هل نحن في حد المصفوفة؟ BEQ main_loop // إذا كنا كذلك ، فقد انتهينا ، لذلك سنقوم بالتكرار إلى الأبد.
ADD R2، # 1 // وإلا يمكننا الاستمرار في التكرار خلال المصفوفة.
إضافة R1 ، # 4 // أضف 4 لتسجيل R1 ، لذلك يشير بشكل صحيح إلى التالي
// عنوان..
B main_loop // Loop back.
يمر الفيديو بكل هذا ، وهناك خطأ فيه. إنه جيد؛ يظهر أنه من المهم تشغيل التعليمات البرمجية وتصحيحها. يُظهر حالة كلاسيكية للخروج من نهاية المصفوفة.
موصى به:
الجزء 3: GPIO: ARM Assembly: Line Follower: TI-RSLK: 6 Steps
الجزء 3: GPIO: ARM Assembly: Line Follower: TI-RSLK: مرحبًا. هذه هي الدفعة التالية حيث نواصل استخدام تجميع ARM (بدلاً من لغة ذات مستوى أعلى). مصدر إلهام Instructable هذا هو Lab 6 من مجموعة أدوات تعلم نظام Texas Instruments Robotics System ، أو TI-RSLK. سنستخدم الميكروفون
رسم متحرك على شاشة LCD مقاس 16 × 2 I2c باستخدام Nucleo STM32: 4 خطوات
الرسوم المتحركة على شاشة LCD 16x2 I2c باستخدام STM32 Nucleo: مرحبًا يا أصدقاء ، هذا برنامج تعليمي يوضح كيفية عمل رسوم متحركة مخصصة على شاشة LCD مقاس 16 × 2 i2c. هناك عدد قليل جدًا من الأشياء اللازمة للمشروع ، لذلك إذا كان لديك وصول إلى الرمز ، يمكنك الانتهاء في غضون ساعة واحدة. بعد اتباع هذا البرنامج التعليمي ، ستكون قادرًا على
التشفير الروتاري مع STM32 Nucleo Board: 12 خطوة
التشفير الروتاري مع STM32 Nucleo Board: هذا هو البرنامج التعليمي للحصول على موضع التشفير الدوار ، وهو نوع تدريجي من التشفير. .ولكن إذا كنت
ROS MoveIt Robotic Arm الجزء 2: وحدة تحكم الروبوت: 6 خطوات
ROS MoveIt Robotic Arm الجزء 2: وحدة تحكم الروبوت: https://github.com/AIWintermuteAI/ros-moveit-arm.git في الجزء السابق من المقالة ، أنشأنا ملفات URDF و XACRO لذراعنا الآلي وأطلقنا RVIZ للتحكم في ذراع آلية في بيئة محاكاة ، هذه المرة سنفعل ذلك بحقيقة
الجزء 2 - تجميع GPIO ARM - RGB - المكالمات الوظيفية - المفاتيح: 6 خطوات
الجزء 2 - تجميع GPIO ARM - RGB - المكالمات الوظيفية - المفاتيح: في الجزء 1 ، تعلمنا كيفية تبديل مؤشر LED أحمر واحد على لوحة تطوير MSP432 LaunchPad من Texas Instruments ، باستخدام التجميع بدلاً من C / C ++. في هذا Instructable ، نحن ستفعل شيئًا مشابهًا - تحكم في RGB LED الموجود أيضًا على هذا sam