تابع printf در stm32 موضوع این مقاله می باشد . یکی از مواردی که برای اشکال زدایی کدها بسیار مفید می باشد استفاده از پورت سریال uart و تابع printf برای چاپ یک رشته یا متغیر جهت نمایش خروجی توابع و بخش های مختلف برنامه می باشد .
برای اشکال زدایی یا debuging به این روش یکی از پورتهای UART میکروکنترلر اشغال می شود و همچنین نیاز به سخت افزار مجزا مثل مبدل usb to serial و استفاده از یک کابل USB و سیم کشی دیگر فقط برای استفاده از UART می باشد .
یک راه سادهتر برای debuging یا اشکالزدایی میکروکنترلر STM32 با تابع printf با استفاده از خود پروگرامر ST-Link وجود دارد و نیازی به اضافه کردن پورت UART و سخت افزار اضافی دیگری نیست.
اگر یک پروگرامر ST-Link (اصلی یا کپی) دارید، اشکالزدایی میکروکنترلرهای STM32 خود با تابع printf آسانتر خواهد بود. دلیل این امر این است که ST یک ساختار اشکالزدایی و ردیابی انعطافپذیر را در نرمافزار و بیشتر MCUهای STM32 خود با نام ITM گنجانده است. تنها چیزی که نیاز دارید پینهای اصلی Serial Wire Debug (SWD) و یک پین خروجی سیم سریال اضافی (SWO) Serial Wire Output است.
ARM امکان استفاده از تابع printf مانند خروجی سریال را با استفاده از رابط ITM را فراهم میکند. این مقاله نحوهی استفاده از تابع printf را با استفاده از پروگرامر ST LINK و ITM Stimulus Ports شرح میدهد.
موضوعاتی که در این مقاله به آنها پرداخته خواهد شد :
ITM چیست؟
(Instrumentation Trace Macrocell) ITM یک بلوک اختیاری و یک منبع ردیابی(Trace) اختیاری مبتنی بر برنامه است که در پیادهسازیهای خاص Cortex-M یافت میشود. معمولاً میکروکنترلرهای با هسته Cortex-M3، M4 و M7 شامل ITM هستند، در حالی که Cortex-M0 و M0+ این ویژگی را ندارند. ITM به عنوان یک منبع ردیابی(TRACE) مبتنی بر برنامه عمل میکند و از اشکالزدایی به سبک printf برای ردیابی رویدادهای سیستم عامل و برنامه پشتیبانی میکند.
SWV چیست؟
وقتی از هر دو پین SWD و SWO استفاده میکنید، آماده ورود به حالت اشکالزدایی Serial Wire Viewer (SWV) هستید. SWV ردیابی و تحلیل پیشرفته سیستم را به صورت real-time ارائه میدهد که همتای حالت اشکالزدایی SWD آن قادر به انجام آن نیست. علاوه بر این، برخلاف SWD، با SWV بدون نیاز به توقف در طول وضعیت اشکالزدایی، دادههای real-time را دریافت میکنید.
ITM (Instrumentation Trace Macrocell) به برنامهها اجازه میدهد تا از طریق پورتها، دادهها را روی خط پین SWO بنویسند. با این کار، میتوانید تابع printf را برای نوشتن در یک کنسول در حالت SWV با استفاده از ویژگی ITM هدایت کنید.
چه نوع سختافزار ST-Link برای Trace مورد نیاز است؟
- Nucleo
سختافزار بورد توسعه Nucleo آماده راهاندازی SWV است زیرا معمولاً ST-Link بصورت یکپارچه روی بورد آن وجود دارد . برای فعال کردن این ویژگی، ممکن است لازم باشد برخی از پدهای روی برد را پل بزنید. - ST-Link clone
متاسفانه، کلونهای ST-Link V2 (برخلاف بردهای اصلی NUCLEO)، برای رفتن به حالت ردیابی اشکالزدایی SWV آماده نیستند. این کلونها فقط پینهای SWD را خروجی میدهند و پین SWO ندارند.
افزودن پشتیبانی Trace به پروگرامر ST-Link v2
وقتی صحبت از برنامهنویسی میکروکنترلرهای ST میشود، من ترجیح میدهم بجای بورد توسعه Nucleo ، یک پروگرامر کلون st-link که یک دانگل خوب در جعبه آلومینیومی با ابعادی کوچک بهمراه مقداری سیم است را با قیمتی ارزان تهیه کنم.
Trace یک ویژگی بسیار جالب است. یکی از کاربردهای رایج، هدایت جریان stdout توسط تابع printf در stm32 به پورت صفر محرک(stimulus port 0) برای چاپ اطلاعات اشکالزدایی است.
همه نسخههای اخیر ST-Link v2 از ویژگی Trace پشتیبانی میکنند ، SWO Trace یک ویژگی بسیار مفید است که با افزودن این ویژگی به پروگرامر کلون ST-Link v2 خود از این به بعد یک دانگل بسیار مفیدتر در اختیار دارید .
اما برای حل مشکل نبود پایه swo در پروگرامر کلون ST-Link v2 ، باید داخل پروگرامر ST-Link پایه ای که به عنوان SWO عمل میکند را پیدا کنید و آن را بیرون بیاورید. معمولاً این کلونهای ST-Link فقط STM32F103 هستند. عملکرد SWO همانطور که در زیر مشاهده میکنید در PA10 قرار دارد.
من نتوانستم شماتیک یک پروگرامر مستقل کلون ST-Link v2 پیدا کنم، بنابراین فرض کردم که دقیقاً مشابه پروگرامر موجود روی برد دیسکاوری خواهد بود. PA10 برای SWO استفاده میشود، بنابراین مرحله بعدی بسیار سرراست خواهد بود.
من مسیر پین ۵ ولتی را درست بعد از via بریدم و مقداری سیم رابط به PA10 لحیم کردم. همچنین یک مقاومت بین ۲۲ تا 100 اهمی را برای محافظت از جریان اتصال کوتاه اضافه کردم تا در صورت بروز مشکل جدی پروگرامر یا میکروکنترلر stm32 آسیب نبیند.
در ابتدا میخواستم از پین SWIM استفاده کنم، چون به STM8 علاقهای ندارم و استفاده از این پایه فقط نیاز به لحیمزدایی یک مقاومت بدون بریدن هیچ مسیری داشت ، اما دسترسی به پین ۵ ولتی آسانتر بود.
توجه : اگر چیپ داخل پروگرامر ST-Link v2 clone شما فیک یا کپی باشد یعنی تولید شده توسط شرکت ST نباشد و توسط شرکت های چینی تولید شده باشد ،این پروگرامر توسط نرم افزار STM32CubeIDE شناسایی نخواهد شد و شما هر گونه عملیات پروگرم کردن و اشکال زدایی و Trace را نمی توانید انجام دهید و از پروگرامر فقط در نرم افزار هایی مثل نسخه قدیمی STM-Link Utility و Keil (تست شده توسط سایت میکرونیک) می توانید استفاده کنید .
اگر چیپ پروگرامر st-link شما با عبارت STM32F103 شروع شده باشد ، چیپ اصلی و اورجینال و توسط شرکت ST تولید شده است . اما اگر عبارت ابتدای روی چیپ با حروفی دیگر شروع شده باشد چیپ فیک می باشد . تصویر زیر یک نمونه پروگرامر ST-Link v2 clone با چیپ فیک می باشد .
آموزش تبدیل پروگرامر فیک به اورجینال قابل شناسایی و بروزرسانی در stm32cubeide بزودی روی سایت قرار خواهد گرفت .
استفاده از printf در STM32CubeIDE
یک پروژه و نمونه کد آماده کنید ، کد زیر را کپی کرده و در فایل main.c خود قرار دهید. در صورت ابهام، این کد از فایل syscalls.c آمده است.
تابع write_ که توسط تابع printf در stm32 فراخوانی خواهد شد را باید تغییر دهیم. تابع io_putchar__ را با تابع ()ITM_SendChar جایگزین کنید. تابع ()ITM_SendChar کاراکترهای ()printf را به ITM Port 0 ارسال میکند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* USER CODE BEGIN 0 */ int _write(int file, char *ptr, int len) { (void)file; int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { //__io_putchar(*ptr++); ITM_SendChar(*ptr++); } return len; } /* USER CODE END 0 */ |
همچنین فایل stdio.h را نیز اضافه کنید، زیرا این فایل برای عملکرد تابع pintf در stm32 و عدم تولید هشدارهای اشکالزدایی غیرضروری مورد نیاز است.
1 2 3 4 |
/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */ |
اکنون میتوانید تابع printf را در فایل اصلی خود وارد کنید.
1 2 3 4 5 6 7 8 9 10 11 |
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { printf("Hello www.micronik.ir \n"); HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ |
قبل از اینکه بتوانید با استفاده از SWV اشکالزدایی کنید، باید Trace Asynch Sw را در Debug on SYS در System Core فعال کنید. این کار تمام پینهای مورد نیاز برای SWV را تنظیم میکند.
سپس، در مسیر Run -> Debug Configurations، به تب Debugger بروید. Serial Wire Viewer (SWV) را فعال کنید و سپس فرکانس کلاک سیستم خود را با Core Clock مورد استفاده توسط SWV مطابقت دهید.
شما باید نمایشگر سیم سریال (SWV) را فعال کنید. مرتبطترین تنظیم ، Core Clock است. شما باید فرکانس ساعت صحیح را که در برنامه خود مقداردهی اولیه میکنید، پیکربندی کنید.
برای اینکه بتوانید تابع printf خود را در کنسول نمایش دهید، باید به پنجره کنسول داده SWV ITM دسترسی داشته باشید. در حالی که هنوز در حالت اشکالزدایی (Debug) هستید (در حالت مکث)، به مسیر Window -> Show View -> SWV ITM Data Console بروید.
پنجره کنسول SWV ITM را از طریق دکمه پیکربندی زیر پیکربندی کنید.
سپس، پورت 0 از پورتهای ITM Stimulus را تیک بزنید. معمولاً از این پورت برای تغییر مسیر کاراکترهای تولید شده توسط تابع printf در stm32 استفاده میشود. برای ادامه، OK را فشار دهید.
برای اجرای SWV، باید به یاد داشته باشید که روی دکمه Start Trace کلیک کنید.
پس از آن، میتوانید با فشردن دکمهی Resume به جلسهی اشکالزدایی خود ادامه دهید. اکنون باید دادههای اشکالزدایی تابع printf در stm32 خود را مشاهده کنید.
استفاده از printf در keil
تابع printf یکی از توابع موجود در کتابخانه stdio می باشد . بنابراین ابتدا باید stdio.h را به ابتدای برنامه اضافه کنید . در نرم افزار keil نیازی به اضافه کردن تابع write_ به برنامه نمی باشد .
سپس به منوی Manage Run-Time Environment بروید و گزینه Compiler->I/O را انتخاب کنید و تیک گزینه های STDERR , STDIN , SDTOUT را به حالت انتخاب درآورید و از زبانه کشویی گزینه ITM را انتخاب کنید . این کار باعث می شود خروجی تابع printf به واحد ITM هدایت یا Redirect شود .
بعد از redirect کردن تابع printf ، حالا باید ردیابی یا Trace را فعال کنید . منوی Options for Target را انتخاب کنید و به مسیر Debug->Settings بروید ، در مرحله بعد منوی Trace را انتخاب کنید .
تیک گزینه Trace Enable را انتخاب کنید و فرکانسی که برای میکرو تنظیم کرده اید در قسمت Core Clock وارد کنید . از قسمت ITM Stimulus Ports تیک قسمت Port 0 را به حالت انتخاب در آورید و در پایان گزینه OK را بزنید .
با زدن گزینه Start/Stop Debug session وارد حالت اشکال زدایی یا دیباگ شوید ، اکنون باید رشته ای را که توسط تابع printf درون برنامه نوشتید در بخش Debug (printf) Viewer مشاهده نمایید .
استفاده از printf در STM32 ST-Link Utility
از منوی ST-LINK گزینه Printf via SWO viewer را انتخاب کنید ، پنجره Serial Wire Viewer(swv) باز می شود . گزینه System clock را برابر فرکانس کاری میکروکنترلر قرار دهید و Stimulus port را 0 انتخاب کنید و در پایان گزینه START را بزنید .