در قسمت دوازدهم آموزش میکروکنترلر STM32F4 به ابزارهای ارتباطی بین Thread ها پرداختیم. در این قسمت از آموزش میکروکنترلر STM32F4 به مبحث مهم و کاربردی تایمر ها و سرویس وقفه میپردازیم. با سیسوگ همراه باشید.
تایمر
گروه تابعهای مدیریت تایمر، امکان ساختن و کنترل تابعهای تایمر را در سیستم فراهم میکند. یک تابع تایمر، وقتی که یک دوره زمانی تمام شود فراخوانی میشود. به دو شکل یکباره و متناوب میتوان تابعهای تایمر را تنظیم کرد. تابعهای تایمر متناوب تا وقتی که متوقف شوند یا پاک شوند به کار خود ادامه میدهند. یک تایمر را میتوان شروع کرد، بازنشانی کرد و یا متوقف کرد.
تایمرها در ریسمان oSTimerThread اداره میشوند. تابعهای فراخوانی، زیر کنترل این ریسمان اجرا میشوند و میتوانند تابعهای سیستم عامل را فراخوانی کنند.
تعاریف تایمر
تعریف Timer object:
1 | #define oSTimerDef(name, function) |
دسترسی به تایمر تعریف شده:
1 | #define oSTimer(name)&os_timer_def_##name |
ساختمان شمارشی
1 2 3 4 | enum os_timer_type { oSTimerOnce = 0, oSTimerPeriodic = 1 } |
توابع تایمر
راه اندازی یک تایمر
گامهای زیر برای راهاندازی تایمر نیاز است:
تعریف تایمر
1 2 3 | oSTimerDef(one_shot, STart_machine); // when the timer expires, the function STart_machine is called oSTimerDef(periodic, toggle_power); // when the timer expires, the function toggle_power is called oSTimerId one_shot_id, periodic_id; |
نمونه سازی و شروع تایمر در یک ریسمان سیستم عامل
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | one_shot_id = oSTimerCreate(oSTimer(one_shot), oSTimerOnce, (void *)0); // creates a one-shot timer; // (void*)0 is passed as an argument to the callback function periodic_id = oSTimerCreate(oSTimer(periodic), oSTimerPeriodic, (void *)5); // creates a periodic timer; // (void*)5 is passed as an argument to the callback function oSTimerSTart(one_shot_id, 500); oSTimerSTart(periodic, 1500); #include "cmsis_os.h" DigitalOut LEDs[4] = { DigitalOut(LED1), DigitalOut(LED2), DigitalOut(LED3), DigitalOut(LED4) }; void blink(void conST *n) { LEDs[(int)n] = !LEDs[(int)n]; } oSTimerDef(blink_0, blink); oSTimerDef(blink_1, blink); oSTimerDef(blink_2, blink); oSTimerDef(blink_3, blink); int main(void) { oSTimerId timer_0 = oSTimerCreate(oSTimer(blink_0), oSTimerPeriodic, (void *)0); oSTimerId timer_1 = oSTimerCreate(oSTimer(blink_1), oSTimerPeriodic, (void *)1); oSTimerId timer_2 = oSTimerCreate(oSTimer(blink_2), oSTimerPeriodic, (void *)2); oSTimerId timer_3 = oSTimerCreate(oSTimer(blink_3), oSTimerPeriodic, (void *)3); oSTimerSTart(timer_0, 2000); oSTimerSTart(timer_1, 1000); oSTimerSTart(timer_2, 500); oSTimerSTart(timer_3, 250); osDelay(osWaitForever); } |
روال سرویس وقفه
میتوان از CMSIS-RTOS در روالهای وقفه استفاده کرد و تنها دو نکته را باید رعایت کرد:
- موتکس نباید استفاده کرد.
- توقف در روال وقفه مجاز نیست. (همه زمانهای پایان باید برابر صفر تنظیم شود.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include "cmsis_os.h" osMessageQDef(queue, 5, message_t); osMessageQId queue; DigitalOut myled(LED1); void queue_isr() { osMessagePut(queue, (uint32_t)2, 0); myled = !myled; } void queue_thread(void conST *args) { while (true) { osMessagePut(queue, 1, 0); osDelay(1000); } } oSThreadDef(queue_thread, osPriorityNormal, DEFAULT_STACK_SIZE); int main (void) { queue = osMessageCreate(osMessageQ(queue), NULL); oSThreadCreate(oSThread(queue_thread), NULL); Ticker ticker; ticker.attach(queue_isr, 1.0); while (true) { osEvent evt = osMessageGet(queue, osWaitForever); if (evt.STatus != osEventMessage) { printf("queue->get() returned %02x STatus\n\r", evt.STatus); } else { printf("queue->get() returned %d\n\r", evt.value.v); } } } |
کدهای وضعیت و خطا
همه مقدارهایی که تابع های سیستم عامل باز میگردانند به ترتیب زیر هستند. این مقدارها در ساختمان شمارشی زیر تعریف شدهاند.
- osOK : تابع کامل شده است؛ خطایی رخ نداده است.
- osEventSignal : تابع کامل شده است؛ رخداد سیگنال، روی داده است.
- osEventMessage : تابع کامل شده است؛ رخداد پیام، روی داده است.
- osEventMail : تابع کامل شده است؛ رخداد نامه، روی داده است.
- osEventTimeout : تابع کامل شده است؛ زمان-پایان روی داده است.
- osErrorParameter : خطای پارامتر، یک پارامتر اجباری گم شده است یا با شیء نادرست بیان شده است.
- osErrorResource: منابع موجود نیست: یک منبع بیان شده در دسترس نیست.
- osErrorTimeoutResource : منبع در زمان داده شده در دسترس نیست. یک منبع بیان شده در بازه زمانی مطلوب در دسترس نبود.
- osErrorISR : در محتوای روال وقفه مجاز نیست. این تابع را نمی توان در روال وقفه فراخوانی کرد.
- osErrorISRRecursive : تابع چند بار از همان روال وقفه فراخوانی شده است.
- osErrorPriority : سیستم نمی تواند الویت را تعیین کند یا ریسمان اولویت غیرقانونی دارد.
- osErrorNoMemory : سیستم کمبود حافظه دارد: امکان دادن حافظه یا نگه داشتن آن برای این فرایند وجود ندارد.
- osErrorValue : مقدار یک پارامتر خارج از محدوده است.
- osErrorOS : خطای ناشناخته سیستم عامل: خطای هنگام-اجرا ولی با هیچکدام از پیام های خطا همخوانی ندارد.
در قسمت چهاردهم آموزش میکروکنترلر STM32F4 به مبحث سیستمِ فایلِ FatFs بر روی کارت SD خواهیم پرداخت. با سیسوگ همراه باشید.