از فایل برنامه تا چشمکزدن LED
در درس 5 یک قالب پایه ساختیم که حلقهٔ اصلی آن خالی بود. اکنون میخواهیم 2 خط به آن اضافه کنیم، برنامه را بسازیم و بدانیم برای نوشتن آن روی برد کدام فایل لازم است. انتظار ما چشمکزدن نشانگر کاربر PB6 با فرکانس حدود 1 Hz است؛ روشنبودن نشانگر تغذیه جای این نتیجه را نمیگیرد.
3 مرحله را جدا دنبال کنید: ساخت فایل روی رایانه، پروگرام حافظهٔ تراشه و مشاهدهٔ اجرای برنامه. برای مرحلهٔ سختافزاری، برد GB100ST V2.0 با STM32F303CBT6، یک ST-LINK یا پروب سازگار با راهنمای مشخص، کابل داده و تغذیهٔ مناسب برد لازم است. برای کنترل ولتاژ هدف مولتیمتر مفید است. ساخت بدون برد ممکن است؛ مشاهده و پروگرام به برد واقعی نیاز دارند.
کد نمونه و فایلهای ساختهشده در پایان قابل دریافتاند. ابتدا روی رایانه ساخت را بررسی میکنیم؛ نتیجهٔ اجرای برد را در کاربرگ جدا ثبت خواهید کرد.
Debug و Release را با فرمان واقعی بشناسیم
یک سورس میتواند با تنظیمهای متفاوت ساخته شود. Debug معمولاً برای بررسی برنامه و Release برای خروجی نهایی در نظر گرفته میشود، اما این نامها خودشان سطح بهینهسازی را تعیین نمیکنند. پرچمهای فرستادهشده به کامپایلر را در گزارش جاری ساخت بخوانید.
در پروژهٔ این درس، پرچمهای C در Debug برابر -O0 -g3 هستند: بیشتر بهینهسازیها غیرفعال و اطلاعات دیباگ درخواست شدهاند. این انتخاب هم تناظر کامل یکبهیک هر خط C با یک دستور ماشین را تضمین نمیکند. در Release از -Os -g0 استفاده شده؛ اولی اندازهٔ کد را هدف میگیرد و دومی درخواست اطلاعات دیباگ آن کامپایل را غیرفعال میکند. برنامهٔ دارای رفتار تعریفشده باید منطق مورد نظر را حفظ کند، اما زمان اجرا و شکل خروجی میتوانند تغییر کنند.
در هر دو ساخت -Wall -Werror داریم: گروهی از هشدارهای مهم فعال و هشدارهای فعال خطا حساب میشوند. هیچ سطح بهینهسازی برای همهٔ برنامهها سریعترین یا کوچکترین نیست؛ نتیجهٔ همین مثال را با گزارش واقعی مقایسه میکنیم. خروجی پروژه CMake است و پیکربندیها برای همان مسیر بررسی شدهاند.
کدام خروجی را باید پروگرام کنیم؟
کامپایلر و اسمبلر سورس را به فایلهای شیء تبدیل میکنند؛ لینکر بخشهای لازم را با توجه به نقشهٔ حافظه کنار هم میچیند. در این پروژه، CMake پس از لینک با ابزار objcopy فایلهای HEX و BIN را هم تولید میکند؛ وجود این دو خروجی، پیشفرض همهٔ پروژهها نیست.

| فایل | چه چیزی دارد؟ | هنگام استفاده |
|---|---|---|
.elf |
برنامهٔ ساختاریافته با بخشها و آدرسها؛ اطلاعات نماد و دیباگ در صورت وجود | برای ابزار پشتیبانیکننده، آدرسها از فایل خوانده میشوند |
.hex |
رکوردهای متنی داده، آدرس و checksum | آدرس در رکوردهاست؛ اندازهٔ متن روی دیسک با دادهٔ Flash برابر نیست |
.bin |
تصویر خام بایتها بدون آدرس بارگذاری | برای همین پروژه شروع Flash را 0x08000000 تعیین کنید |
.map |
گزارش متنی آدرسها، بخشها و اندازههای لینک | برای تحلیل است، نه نوشتن روی Flash |
حافظهٔ Flash مدل CB برابر 128 KiB است؛ هر KiB برابر 1024 بایت. نشانی شروع آن از دیتاشیت و اسکریپت لینکر پروژه مشخص میشود. برای BIN نشانی را حدس نزنید و برای آزمایش عمداً نشانی نادرست ننویسید؛ نگاشت آدرس صفر هم به وضعیت بوت و ابزار وابسته است و جای نشانی مشخص Flash این پروژه نیست. مرجع، DS9118 و RM0316 است.
ELF را با DWARF یکی ندانید: اولی قالب فایل و دومی قالب اطلاعات دیباگ است. بخشهای دیباگ غیرقابل بارگذاری معمولاً روی رایانه میمانند؛ صرف بزرگی ELF دلیل پرشدن Flash نیست. در فایل واقعی Release این مثال با وجود پرچم C یعنی -g0، هنوز بخش .debug_info به اندازهٔ 576 بایت وجود دارد؛ دربارهٔ همهٔ اشیای لینک فقط از روی یک پرچم C نتیجه نگیرید.
اندازهٔ فایل با مصرف حافظه فرق دارد
برای مدل CB، SRAM اصلی 32 KiB و CCM جدا 8 KiB است؛ DMA به CCM دسترسی ندارد. گزارش linker میگوید بخشها در کدام ناحیه جا گرفتهاند. رزرو حافظه در فایل، اندازهگیری بیشترین مصرف هنگام اجرا نیست.

در این ساخت، کد و ثابتهای لازم عمدتاً در Flashاند. بخش .data شامل دادههای قابل تغییر با مقدار اولیه است که تصویر اولیهشان در Flash و محل اجرای آنها در RAM است. بخش .bss برای دادههای صفرشوندهٔ آغاز برنامه است. پشته برای فراخوانیها و دادههای موقت و هیپ برای تخصیص پویا در صورت استفاده، بودجهٔ جدا لازم دارند.
| نتیجهٔ واقعی، بایت | Debug | Release |
|---|---|---|
| Flash در لینک | 8112 | 3688 |
.data |
12 | 12 |
اشیای بخش .bss |
32 | 32 |
| بخش رزرو heap/stack با همترازی | 1540 | 1540 |
| ناحیهٔ RAM در لینک | 1584 | 1584 |
| فایل ELF روی دیسک | 850060 | 19320 |
| فایل BIN این تصویر | 8112 | 3688 |
عدد 1540 شامل 4 بایت همترازی، 512 بایت حداقل heap و 1024 بایت حداقل stack است. ستون bss در خروجی خلاصهٔ GNU size این نمونه، بخشهای بدون دادهٔ ذخیرهشده را جمع میزند و 1572 نشان میدهد؛ این عدد فقط متغیرهای سراسری نیست.
RAM region = 12 + 32 + 4 + 512 + 1024 = 1584 bytes
Flash reduction in this build = 8112 – 3688 = 4424 bytes
این جدول نتیجهٔ ساخت واقعی روی رایانه است، نه اندازهگیری برد. در این نمونه ناحیهٔ RAM دو ساخت یکسان مانده؛ قانون کلی نیست که بهینهسازی فقط Flash را تغییر میدهد. برای مصرف اوج پشته یا کافیبودن رزرو آن، شاهد بیشتری لازم است.
ST-LINK را با نام سیگنال وصل کنیم
رابط SWD با 2 سیگنال داده و کلاک کار میکند، ولی نام «دوسیمه» به معنی بینیازی از زمین مشترک و مرجع تغذیه نیست. قبل از اتصال در حالت خاموش، مدل دقیق پروب و راهنمای آن و شماتیک برد V2.0 را تطبیق دهید. شماره و جهت هدر مدل دیگر یا رنگ سیم، مرجع کافی نیست.

| سیگنال | سمت برد هدف | نکته |
|---|---|---|
| SWDIO | PA13 | دادهٔ دوطرفهٔ دیباگ |
| SWCLK | PA14 | کلاک ارتباط از پروب |
| GND | زمین برد | مرجع مشترک سیگنال |
| VAPP / VTref، مطابق مدل پروب | ریل تغذیهٔ هدف، نامی 3.3 V | مرجع ولتاژ را خروجی تغذیه فرض نکنید |
| NRST | RESET / NRST | برای اتصال تحت ریست باید سیمبندی شود |
پروب استاندارد ST-LINK/V2 با بعضی پروبهای دیگر رفتار یکسانی ندارد. طبق UM1075 Rev 10، یادداشت صفحهٔ 5، خروجیهای آن حتی برای هدف کمولتاژتر در سطح 3.3 V هستند؛ وجود VAPP به معنی تبدیل خودکار متغیر سطح همهٔ خروجیها نیست. در این دوره برد نامی 3.3 V است، اما برای هر پروب دقیقاً راهنمای همان مدل را بخوانید.
ورودی نامی 5 V برد به AMS1117-3V3 میرود و با ریل 3.3 V یا مرجع هدف پروگرامر فرق دارد. 5 V را به VDD، 3V3 یا خطوط SWD ندهید؛ بیرون محدودهٔ مجاز میتواند آسیب دائمی ایجاد کند. خروجی تغذیهٔ پروب را بدون بررسی مدار به منبع دیگر متصل نکنید. نشانگر POWER فقط مسیر خودش را نشان میدهد؛ مقدار واقعی ولتاژ هدف و اتصال درست را جدا بررسی کنید.
فایل ساختهشده را به تراشه بفرستیم
ابتدا ساخت موفق و فایل همان پیکربندی را مشخص کنید. سپس اتصال پروب به رایانه، شناسایی تراشه و نوشتن حافظه را جدا ثبت کنید. مراحل زیر راهنمای خوانندهاند؛ برای تهیهٔ این درس اتصال هدف یا پروگرام انجام نشده است.

مسیر STM32CubeProgrammer
- با توجه به سیمبندی بررسیشده و تغذیهٔ هدف، پروب را وصل و در برنامه رابط ST-LINK و SWD را انتخاب کنید. فرکانس ارتباط باید با پروب و شرایط سیمبندی سازگار باشد.
- Connect را بزنید و شناسه و اطلاعات خواندهشدهٔ هدف را با تراشهٔ برد تطبیق دهید. دیدهشدن USB پروب هنوز این مرحله را ثابت نمیکند.
- در بخش Erasing & Programming، فایل همان ساخت را با Browse انتخاب کنید. HEX یا ELF آدرس دارند؛ اگر BIN همین پروژه را انتخاب میکنید، نشانی شروع را
0x08000000قرار دهید. - گزینهٔ تأیید پس از نوشتن را فعال و Start programming را اجرا کنید. گزارش واقعی را ذخیره کنید؛ از خطا رد نشوید و آن را موفقیت ننامید.
- طبق گزینههای همان اجرا، برنامه را Run یا برد را Reset کنید و نشانگر کاربر را ببینید. رفتار انتظاررفته را در کاربرگ ثبت کنید؛ Verify فقط برابری دادهٔ خواندهشده با فایل را نشان میدهد، نه درستی برنامه.
نام گزینههای برنامهریزی و تأیید از راهنمای رسمی CubeProgrammer 2.23 است؛ ظاهر و نام دقیق را با نسخهٔ نصبشدهٔ خود تطبیق دهید. برای این تمرین، پاکسازی کامل تراشه یا تغییر حفاظت پیشنیاز عادی نیست؛ محدودهٔ حافظهٔ مورد برنامهریزی و پیام ابزار را بررسی کنید.
مسیر STM32CubeIDE
از CubeIDE 2.0 به بعد، CubeMX مستقل است. بستهٔ همراه این درس CMake است و متادیتای بومی Eclipse ندارد. برای مسیر پیشنهادی IDE، از IOC کپی جدا بگیرید، خروجی STM32CubeIDE را در پوشهای جدا تولید و طبق راهنمای همان نسخه باز کنید.
پروژه و پیکربندی درست را Build کنید؛ در تنظیم اجرای Run یا Debug، پروب ST-LINK، رابط SWD و ELF همان ساخت را بررسی کنید. دانلود، ریست و شروع خودکار تابع تنظیم Launch هستند؛ صرف فشردن Run را در همهٔ پروژهها تضمین پروگرام و اجرای بیدرنگ ندانید. مسیر گرافیکی و واردکردن این خروجی در این بررسی آزمایش نشده است.
Option Bytes را فقط بخوانیم
Option Bytes تنظیمهای ماندگار تراشهاند؛ برای مثال بخشی از رفتار بوت و حفاظت از حافظه را کنترل میکنند. RDP یعنی حفاظت در برابر خواندن. برای شناخت این بخش فقط مقدارهای خواندهشده را ثبت کنید؛ در این درس هیچ تغییر RDP یا فرمان اعمال تنظیم لازم نیست.

| سطح برای F303 | معنای کلی | نکتهٔ این درس |
|---|---|---|
| Level 0 | حفاظت خواندن RDP فعال نیست؛ محدودیتهای دیگر را جدا بررسی کنید | وضعیت واقعی را فقط پس از خواندن ثبت کنید |
| Level 1 | خواندن Flash از مسیرهای مشخص محدود میشود؛ قطع کامل همهٔ ارتباطها نیست | بازگشت به 0 پاکشدن Flash را در پی دارد |
| Level 2 | حفاظت برگشتناپذیر و غیرفعالشدن دسترسی دیباگ | برای آزمایش فعال نکنید؛ امکان کاهش سطح وجود ندارد |
طبق RM0316، سطح 2 برگشتناپذیر است. آن را با سوختن فیزیکی تراشه یا توقف قطعی برنامهٔ موجود یکی ندانید؛ اجرای برنامهٔ از پیش موجود با بازکردن دسترسی دیباگ فرق دارد. وجود یک گزینهٔ عمومی reset یا recovery در ابزار هم تضمین بازکردن RDP2 این قطعه نیست. این مقاله هیچ Option Bytes واقعی را تغییر نداده یا مقدار RDP برد شما را از پیش تأیید نکرده است.
اگر اتصال برقرار نشد
پیام «Cannot connect to target» علت واحدی ندارد. متن دقیق را نگه دارید و از سمت رایانه تا هدف بررسی کنید؛ از یک پیام به سوختن تراشه یا لزوم پاکسازی کامل نرسید.

| گام | بررسی |
|---|---|
| پروب در رایانه | کابل داده، درایور رسمی و شناسایی USB؛ با ارتباط هدف فرق دارد |
| تغذیهٔ هدف | مقدار واقعی ریل هدف و زمین مشترک؛ POWER LED معیار اندازهگیری ولتاژ نیست |
| سیگنالها | SWDIO و SWCLK جابهجا نباشند؛ مرجع هدف و NRST را با راهنمای پروب تطبیق دهید |
| تنظیم ارتباط | یک فرکانس پایینترِ پشتیبانیشده را امتحان و نتیجه را ثبت کنید |
| برنامهٔ قبلی مانع دیباگ میشود | با NRST متصل، حالت Under Reset و ریست سختافزاری مناسب را بررسی کنید؛ درمان تضمینی همهٔ خطاها نیست |
| بوت و اجرا | BOOT0 در شماتیک برد بهصورت پیشفرض GND است؛ وضعیت واقعی و تنظیمهای مرتبط را بررسی کنید |
طبق مستند رسمی اتصال CubeProgrammer، Under Reset برای گرفتن کنترل پیش از اجرای دستورهای برنامه کاربرد دارد و ریست سختافزاری به اتصال NRST نیاز دارد. پایه را دائم به زمین نبندید. تغییر BOOT0 یا رفتن به بوتلودر را راه قطعی و بدون شرط همهٔ بازیابیها ندانید؛ حالت بوت به تنظیمهای مرتبط هم وابسته است. بیدلیل حافظه را پاک نکنید.
اگر پروگرام و Verify موفقاند ولی LED چشمک نمیزند، فایل انتخابشده، شروع اجرا، USER LED روی PB6 و پیکربندی GPIO را بررسی کنید. قالب HSI این درس HSE/LSE را روشن نمیکند؛ نبودن کریستال خارجی را بدون شاهد علت خطای این مقداردهی ندانید. بررسی توقف برنامه با دیباگر در درس 7 میآید.
کد چشمکزن را بسازیم و نتیجه را ثبت کنیم
قالب درس قبل PB6 را خروجی با سطح اولیهٔ Low کرده است. مدار NPN برد با High نشانگر کاربر را روشن میکند. برای تغییر متناوب وضعیت، فقط قطعهٔ واقعی زیر را در محل گفتهشده اضافه میکنیم:
فقط 2 خط زیر را در Core/Src/main.c، داخل بلوک موجود USER CODE BEGIN 3 درون حلقهٔ while (1) بنویسید؛ حلقه یا تابع تولیدشده را بازتعریف نکنید. متن از پروژهٔ واقعاً ساختهشده استخراج شده است.
HAL_GPIO_TogglePin(USER_LED_GPIO_Port, USER_LED_Pin);
HAL_Delay(500U);
در HAL همین نسخه، تابع HAL_GPIO_TogglePin ابتدا ODR، رجیستر وضعیت خروجی، را میخواند و با نوشتن BSRR وضعیت پین را برعکس میکند. این توالی را پروتکل بدون رقابت برای چند نویسندهٔ همزمان ندانید؛ در نمونه فقط حلقهٔ اصلی LED را تغییر میدهد.
HAL_Delay انتظار مسدودکننده بر پایهٔ تیک HAL است. با تیک پیشفرض 1 ms، درخواست 500 در شرط مقایسه آستانهٔ 501 تیک دارد؛ 500 پالس کلاک CPU نیست و زمان فیزیکی دقیق 501 ms هم تضمین نمیشود. فاز تیک، اجرای دستورها، وقفهها و خطای HSI بر مشاهده اثر دارند. این تأخیر فقط در حلقهٔ اصلی استفاده شده؛ اگر تیک امکان پیشروی نداشته باشد انتظار ممکن است تمام نشود.
Nominal frequency ≈ 1 / 1 s = 1 Hz
پیش از پروگرام، فرکانس حدود 1 Hz را پیشبینی کنید. سپس ساخت و مقایسهٔ Debug/Release را انجام دهید؛ بعد از پروگرام و شروع اجرای واقعی، روشن و خاموششدن USER LED را ثبت کنید. مشاهدهٔ چشمی حدود سرعت را نشان میدهد؛ برای عدد دوره، ابزار و شرایط اندازهگیری را هم بنویسید. در گزارش این مقاله فقط ساخت رایانه انجام شده است و خانههای مشاهدهٔ برد در انتظارند.
خودآزمایی
پرسش 1: چرا ELF بزرگتر از مقدار Flash گزارششده است؟
پاسخ: ELF علاوه بر دادههای قابل بارگذاری میتواند جدولها و اطلاعات دیباگ داشته باشد. مصرف Flash را از ناحیهٔ لینک و بخشهای بارگذاری بخوانید، نه اندازهٔ فایل روی دیسک.
پرسش 2: برای BIN این پروژه چه نشانی شروع لازم است؟
پاسخ: 0x08000000، طبق نقشهٔ همین پروژه. BIN خودش آدرس ندارد؛ نشانی دیگری را حدس نزنید یا برای آزمایش عمداً استفاده نکنید.
پرسش 3: چرا bss خلاصهٔ size برابر 1572 ولی اشیای .bss برابر 32 هستند؟
پاسخ: در این خروجی، بخش بدون دادهٔ heap/stack به اندازهٔ 1540 هم در جمع میآید. اندازهٔ RAM کل با data به 1584 بایت میرسد و مصرف اوج اجرا نیست.
پرسش 4: NRST در Under Reset چه نقشی دارد؟
پاسخ: پروب برای ریست سختافزاری به خط NRST نیاز دارد تا پیش از اجرای برنامه اتصال را امتحان کند؛ موفقیت برای هر خطا تضمین نمیشود.
پرسش 5: آیا Verify موفق، درستبودن چشمکزن را ثابت میکند؟
پاسخ: خیر؛ دادهٔ خواندهشده با فایل تطبیق داده شده است. منطق برنامه، شروع اجرا و زمانبندی باید جدا بررسی شوند.
پرسش 6: چرا نباید RDP2 را آزمایشی فعال کنیم؟
پاسخ: در این F303 برگشتناپذیر است و دسترسی دیباگ را از دست میدهیم؛ این درس تنها خواندن و ثبت تنظیمها را میخواهد.
تمرینها
تمرین 1، پایه: پروژهٔ همراه را در Debug و Release بسازید و پرچمهای واقعی و ناحیههای Flash و RAM را در کاربرگ بنویسید. انتظار برای همین محیط مرجع: Flash برابر 8112 و 3688 بایت و RAM هر دو 1584 بایت؛ با ابزار متفاوت، اختلاف را از نسخه و فرمان واقعی بررسی کنید، نه اینکه عدد مرجع را نتیجهٔ ساخت خود بنویسید.
تمرین 2، میانی: با Python 3 فایل verify_blink_artifacts_v2.py را اجرا کنید. پیشبینی کنید BIN و دادههای آدرسدار HEX یک برنامهاند یا نه. نتیجهٔ مورد انتظار: هش فایلها، checksum رکوردها و برابری محتوای واقعی دو قالب تأیید و وجود 576 بایت debug_info در ELF حالت Release گزارش میشود. این تمرین فقط فایلها را میخواند و هدف را پروگرام نمیکند.
تمرین 3، پیشرفته: با برد و پروب مشخص، اتصال عادی، شناسایی هدف، انتخاب فایل درست، پروگرام، Verify و شروع برنامه را طبق راهنما انجام و شاهد هر مرحله را در کاربرگ ثبت کنید. معیار پایان: ثبت نتیجهٔ واقعی و چشمک حدود 1 Hz یا متن دقیق خطای مرحلهٔ متوقفشده. تغییر RDP، نشانی اشتباه، ازکارانداختن عمدی SWD و پاکسازی کامل، بخشی از این تمرین نیستند.
شاهد ساخت و منابع همراه
پروژه با CubeMX 6.14.0، پایگاه 6.0.140 و CubeF3 V1.11.6 تولید شده است. در بازبینی 2026-11-02، منابع بدون تغییر با GCC 13.2.1 در هر دو پیکربندی CMake پاک ساخته شدند و هشدار نداشتند. 31 بررسی فایل و مدل هم اجرا شده است؛ گزارش ساخت با بررسی فایل و با آزمون روی برد سه شاهد جداست. اجرای CubeIDE، اتصال پروب به هدف، پروگرام، Option Bytes و اندازهگیری زمان در این بررسی انجام نشدهاند.
سورس، IOC، مجوزها، خروجیهای واقعی قبلی همین سورس تأییدشده، گزارشهای ساخت مجدد، مقایسهٔ اندازه و هشها و کاربرگهای خالی همراه درس هستند. آرشیو خروجیهای قبلی با ساخت تازه از نظر منبع یکسان است؛ فایلهای آن بهعنوان تازهدریافتشده از ساخت مجدد معرفی نمیشوند. برای بازتولید، نسخهها و فرمانهای README را دنبال کنید.
مراجع اصلی: DS9118 و RM0316 برای قطعه، حافظه و حفاظت؛ شماتیک V2.0 برای سیمبندی برد؛ UM1075 Rev 10 برای مدل رسمی ST-LINK/V2؛ راهنمای برنامهریزی CubeProgrammer و روشهای اتصال؛ سورس HAL با شناسهٔ 953955a برای Toggle و Delay. در درس 7، دیباگ مشاهدهٔ اجرای برنامه را ادامه میدهیم.
دانلود فایلهای همراه درس 6
پروژهٔ واقعی شامل IOC و سورس، خروجیهای ELF/MAP، گزارش ساخت، مدل و کاربرگ، مجوزها و 6 تصویر همراه اسکریپت قابل ویرایش در بسته قرار دارند. راهنمای پروژه وضعیت واقعی ساخت و آزمون را توضیح میدهد. ابتدا ZIP را استخراج و README را بخوانید.
پیوند دانلود به نسخهٔ مشخص و بازبینیشدهٔ همراه مقاله متصل است.