مقدمه
در سیستمهای توکار (Embedded Systems)، دو عامل حیاتی هستند:
- مصرف توان پایین (Power Efficiency)
- پایداری و قابلیت اشکالزدایی (Debugging Capability)
در کاربردهایی مانند دستگاههای قابلحمل، حسگرهای IoT یا گرههای باتریخور، کاهش مصرف انرژی به اندازهی پردازش سریع اهمیت دارد.
از طرف دیگر، در محیط چندوظیفهای RTOS باید بتوان عملکرد تسکها، اولویتها و زمانبندی را پایش و تحلیل کرد تا از رفتار غیرمنتظره جلوگیری شود. همچنین در سیستمهای بلادرنگ، مدیریت توان و امکان اشکالزدایی دقیق باید بهصورت همزمان در نظر گرفته شود، زیرا هر دو مستقیماً بر پایداری و عمر مفید دستگاه اثر میگذارند.
در واقع، طراح باید بتواند بین سرعت پاسخدهی سیستم و مصرف انرژی تعادل ایجاد کند.
ابزارهای مانیتورینگ و Trace مانند SystemView یا FreeRTOS Debugger کمک میکنند تا نقاط پرمصرف یا تأخیرهای ناخواسته در زمان اجرا شناسایی شوند.
به این ترتیب، مهندس میتواند تصمیم بگیرد چه زمانی میکروکنترلر را به حالت Sleep ببرد و در عین حال رفتار دقیق Taskها را زیر نظر داشته باشد.
حالتهای توان در STM32
STM32 سه سطح اصلی از مدیریت توان را دارد:
| حالت | توضیح |
| Run Mode | CPU و تمام پریفرالها فعال هستند. |
| Sleep Mode | CPU متوقف میشود ولی پریفرالها (مثل UART، DMA، Timer) فعال میمانند. |
| Stop / Standby Mode | اکثر پریفرالها و کلاکها خاموش میشوند؛ فقط وقفهها یا RTC میتوانند MCU را بیدار کنند. |
در RTOS، حالت Sleep معمولاً بهصورت خودکار از طریق Idle Task Hook یا Tickless Idle Mode مدیریت میشود.
حالت Idle Task در RTOS
هر سیستم FreeRTOS یا CMSIS-RTOS v2 یک Idle Task دارد که همیشه در پسزمینه اجرا میشود.
وقتی هیچ تسکی آمادهی اجرا نباشد، Scheduler این تسک را اجرا میکند. Idle Task در واقع بهعنوان «پسزمینهی سیستم» عمل میکند و زمانی اجرا میشود که هیچ تسک دیگری در حالت Ready نباشد.
این تسک معمولاً پایینترین اولویت را دارد و میتواند برای اجرای کارهای سبک، مثل آزادسازی حافظه یا بررسی سلامت سیستم استفاده شود.
در کاربردهای کممصرف، از Idle Task برای اجرای دستوراتی مانند __WFI() یا HAL_PWR_EnterSLEEPMode() استفاده میشود تا CPU در زمان بیکاری وارد حالت Sleep شود.
همچنین میتوان از آن برای شمارش زمان بیکاری سیستم و محاسبهی CPU Utilization (درصد استفاده از پردازنده) بهره گرفت، که در تحلیل عملکرد سیستمهای بلادرنگ بسیار مفید است.
میتوان از این تسک برای وارد کردن سیستم به حالت کممصرف استفاده کرد:
در فایل freertos.c، تابع Idle Hook را اضافه کن:
void vApplicationIdleHook(void)
{
// CPU وارد حالت Sleep شود تا مصرف توان کاهش یابد
__WFI(); // Wait For Interrupt (دستور سختافزاری ARM)
}CubeMX خودش vApplicationIdleHook() را در صورتی که در تنظیمات FreeRTOS فعال کنی، اضافه میکند.
حالت Tickless Idle Mode
در حالت معمولی، SysTick Interrupt هر ۱ میلیثانیه اتفاق میافتد و باعث مصرف توان مداوم میشود.
در حالت Tickless Idle، RTOS وقتی هیچ تسکی آماده نیست، وقفهی SysTick را غیرفعال میکند و CPU را تا زمان وقوع رویداد بعدی به خواب میبرد. در این حالت، تایمر سیستم بهصورت پویا تنظیم میشود تا تنها زمانی فعال شود که یک تسک باید بیدار شود یا رویدادی در صف زمانبندی قرار دارد.
بهعبارت دیگر، RTOS مدت زمان خواب را محاسبه کرده و قبل از ورود به Sleep، تایمر را طوری پیکربندی میکند که دقیقاً در زمان مورد نیاز وقفهی بیداری را ایجاد کند.
این روش باعث میشود مصرف توان بهشدت کاهش یابد، زیرا CPU و بسیاری از پریفرالها در زمان بیکاری غیرفعال میشوند.
البته در طراحی سیستم باید دقت شود که پریفرالهایی مانند UART یا DMA که به زمانبندی دقیق نیاز دارند، از Tickless Idle تأثیر منفی نگیرند.
تنظیم در CubeMX:
Middleware → FreeRTOS → Configuration → Enable Tickless Idle
سپس پارامتر configUSE_TICKLESS_IDLE در FreeRTOSConfig.h برابر 1 میشود.
مزیت:
مصرف توان در حالت بیکاری تا ۸۰٪ کاهش مییابد.
مدیریت توان تسکها
در CMSIS-RTOS v2 میتوان تسکها را موقتاً متوقف کرد تا CPU به حالت Sleep برود:
تعلیق و ازسرگیری Task:
osThreadSuspend(AdcTaskHandle); // متوقف کردن تسک
// ...
osThreadResume(AdcTaskHandle); // از سرگیری تسکخواب نرمافزاری تسک:
osDelay(1000); // تسک برای ۱ ثانیه Block میشود، CPU میتواند Sleep بروددر واقع مدیریت توان تسکها در RTOS یکی از مؤثرترین روشها برای کنترل مصرف انرژی در سامانههای چندوظیفهای است.
با تعلیق (Suspend) یا تأخیر (Delay) تسکهایی که در حال حاضر نیازی به اجرا ندارند، میتوان از بیکار ماندن بیهدف CPU جلوگیری کرد.
این کار علاوهبر کاهش توان مصرفی، موجب میشود تسکهای حیاتی در زمان مناسبتر به اجرا برسند و Scheduler منابع را بهصورت بهینهتر تخصیص دهد.
همچنین با ترکیب این روش با حالتهای Sleep و Stop، میتوان مصرف انرژی را تا چندین برابر کاهش داد بدون آنکه عملکرد بلادرنگ سیستم مختل شود.
مثال عملی – حالت کممصرف در CubeMX با CMSIS-RTOS v2
در CMSIS-RTOS v2 میتوان تسکها را موقتاً متوقف کرد تا CPU به حالت Sleep برود:
سناریو:
سیستم دمای محیط را هر ۵ ثانیه اندازهگیری میکند، بقیهی زمان در حالت Sleep میماند.
- تنظیمات:
- ADC برای اندازهگیری دما (Internal Channel یا Sensor)
- UART برای ارسال داده
- FreeRTOS → CMSIS-RTOS v2
void StartAdcTask(void *argument)
{
uint16_t temp;
for(;;)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
temp = HAL_ADC_GetValue(&hadc1);
char msg[20];
int n = sprintf(msg, "Temp=%u\r\n", temp);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, n, 100);
osDelay(5000); // ۵ ثانیه خواب → CPU در حالت Sleep خواهد بود
}
}در زمان osDelay، Scheduler تسک را Block میکند و Idle Task اجرا میشود،
در نتیجه دستور __WFI() از Idle Hook باعث ورود MCU به Sleep Mode میگردد.
اشکالزدایی (Debug) در RTOS
در CMSIS-RTOS v2 میتوان تسکها را موقتاً متوقف کرد تا CPU به حالت Sleep برود:
در STM32CubeIDE، وقتی FreeRTOS فعال است میتوان با ابزار FreeRTOS Task List وضعیت Taskها را در زمان اجرا دید:
Window → Show View → FreeRTOS → Task List
نمایش میدهد:
- نام تسک
- وضعیت (Running, Blocked, Suspended)
- زمان اجرا (Runtime %)
- Stack Usage
ا ستفاده از SEGGER SystemView
SEGGER SystemView ابزاری حرفهای برای Trace و تحلیل رفتار RTOS است.
میتواند زمان اجرای هر Task، وقفه، Semaphore، Queue و Event را با دقت میکروثانیه ثبت کند.
ر اهاندازی در CubeMX و Keil / CubeIDE:
- از مسیر Utilities → SystemView بستهی SEGGER را اضافه کن.
- در FreeRTOSConfig.h فعال کن:
#define configUSE_TRACE_FACILITY 1
#define configUSE_TIMERS 1
#define configGENERATE_RUN_TIME_STATS 13. در ابتدای main.c بنویس:
SEGGER_SYSVIEW_Conf();
SEGGER_SYSVIEW_Start();4. برنامه را اجرا کن و در نرمافزار SystemView گزینه Start Recording را بزن.
مشاهدهی زمانبندی و وقفهها در SystemView
در SystemView نمودارهای زیر را میبینی:
- Task Timeline: ترتیب اجرای Taskها
- Interrupt View: زمان و مدت اجرای ISRها
- CPU Load Graph: درصد استفاده از CPU
- Event Log: زمان دقیق ارسال Semaphore، Queue، Delay و Resume
تشخیص خطای Stack Overflow
وقتی اندازهی پشتهی یک Task کوچکتر از نیاز واقعی باشد، محتویات حافظه خراب میشود و سیستم ناپایدار میگردد.
برای تشخیص این خطا باید در FreeRTOSConfig.h تنظیم کنی:
#define configCHECK_FOR_STACK_OVERFLOW 2و سپس تابع خطای Stack Overflow را بنویس:
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
printf("Stack overflow in task: %s\r\n", pcTaskName);
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_SET);
while(1); // توقف سیستم برای بررسی
}در CMSIS-RTOS v2 هم همین رفتار به صورت داخلی پشتیبانی میشود؛ در CubeMX کافی است گزینهی
“Enable Stack Overflow Hook” را فعال کنی.
مدیریت مصرف توان همراه با Debug
گاهی هنگام فعالسازی حالت Sleep، اشکالزدایی از طریق JTAG متوقف میشود.
برای جلوگیری از این موضوع در مرحلهی توسعه، میتوان این خط را افزود:
HAL_DBGMCU_EnableDBGStopMode();
HAL_DBGMCU_EnableDBGSleepMode();این باعث میشود در حالت Stop یا Sleep، ارتباط Debug قطع نشود.
جمعبندی
- در سیستمهای چندوظیفهای RTOS، مدیریت توان باید با Scheduler هماهنگ باشد.
- استفاده از Idle Hook یا Tickless Idle Mode سادهترین راه برای ورود خودکار به حالت Sleep است.
- ابزارهای Debug مانند CubeIDE RTOS Viewer و SEGGER SystemView کمک میکنند تا رفتار واقعی سیستم تحلیل و بهینهسازی شود.
- تشخیص خطاهای Stack Overflow و مانیتورینگ زمان اجرا برای پایداری سیستم حیاتی است.
- ترکیب مدیریت توان و Debug اصولی، منجر به ساخت سیستمهای پایدار، کممصرف و دقیق میشود.
منابع
Mastering the FreeRTOS Kernel – Richard Barry
SEGGER SystemView and STM32CubeIDE Documentation
Hands-On RTOS with Microcontrollers – Brian Amos UM1722 – Developing Applications on STM32Cube with RTOS – STMicroelectronics