Electoday 2025

ไมโครคอนโทรลเลอร์ => ARM Processors => Topic started by: empirejrz on December 28, 2017, 07:54:17 PM

Title: การใช้งาน RTOS บน Cube MX
Post by: empirejrz on December 28, 2017, 07:54:17 PM
มีท่านใดใช้งาน FreeRTOS ใน Cubx mx บ้างครับ ผมอยากทราบว่า เวลาใช้งาน FreeRTOS แล้ว Systick. ต้องเปลี่ยนไปใช้ TIM. ใช่ไหมครับ
Title: Re: การใช้งาน RTOS บน Cube MX
Post by: dec on December 29, 2017, 02:20:26 AM
Cube MX มันจะมี option ให้ปรับ HAL tick ไปใช้ TIM แทนครับ

ซึ่งเป็นวิธีที่ผมไม่ชอบซักเท่าไหร่ เพราะการ Delay ที่เกิดจาก HAL_Delay
จะไม่เกิดการ Block ทำให้เสียเวลาโปรเซสไปเปล่า ๆ และยังเปลือง TIM ไปอีก 1 ตัว

แต่ function เกี่ยวกับ HAL tick แทบทั้งหมดเป็น weak symbol เราสามารถ override ได้
เพราะฉะนั้นถ้าต้องใช้ HAL Lib ร่วมกับ FreeRTOS จริงๆ
ผมมักจะแก้ให้ HAL tick กับ FreeRTOS ใช้ SysTick เหมือนกัน

โดยขั้นแรกสร้างไฟล์ .c เพิ่ม 1 ไฟล์ มี code ประมาณนี้

#include "stm32l4xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"

static uint8_t hal_tick_enable = 1;

void HAL_SuspendTick(void)
{
  hal_tick_enable = 0;
}

void HAL_ResumeTick(void)
{
  hal_tick_enable = 1;
}

uint8_t HAL_GetTickState(void)
{
  return hal_tick_enable;
}

void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart;
  uint32_t wait;

  if(xTaskGetSchedulerState() != taskSCHEDULER_RUNNING)
  {
    tickstart = HAL_GetTick();
    wait = Delay;
   
    /* Add a period to guaranty minimum wait */
    if (wait < HAL_MAX_DELAY)
      wait++;
   
    while((HAL_GetTick() - tickstart) < wait);
  }
  else
  {
    vTaskDelay(Delay/portTICK_PERIOD_MS);
  }
}


แล้วในไฟล์ stm32xxxx_it.c ก็แก้ SysTick_Handler เป็นประมาณนี้

#include "stm32l4xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"

extern uint8_t HAL_GetTickState(void);
extern void xPortSysTickHandler(void);

...

void SysTick_Handler(void)
{
  if(HAL_GetTickState())
    HAL_IncTick();
 
  if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    xPortSysTickHandler();
}

..
Title: Re: การใช้งาน RTOS บน Cube MX
Post by: empirejrz on December 29, 2017, 04:01:18 AM
แล้วมันจะมีผลอะไรไหมครับ ใช้ Systick. เหมือนกัน เวลาเกิด Interrupt ขึน มันจะไปชนกะ Task. RTOS. หรือเปล่าครับ
Title: Re: การใช้งาน RTOS บน Cube MX
Post by: dec on December 29, 2017, 05:56:11 PM
มีผลกระทบ 2 อย่าง เท่าที่ผมนึกออกนะครับคือ

1. ถ้าเราไปหยุดการทำงานของ FreeRTOS Kernel (vTaskEndScheduler) มันจะหยุด SysTick ด้วย
ทำให้ HAL Tick เป็นง่อยไปด้วย แต่ใน Embedded คงไม่หยุด Kernel กันครับ จะใช้งานกรณี
ใช้ FreeRTOS บน PC

2. ถ้าเราต้องการให้ HAL Tick และ FreeRTOS Tick มีคาบต่างกันแบบหารกันไม่ลงตัว

เช่น FreeRTOS Tick ทำงานที่ 1ms แต่ HAL Tick ทำงานที่ 0.7ms แบบนี้จะลำบาก
เพราะต้องหาคาบที่เป็นค่าหารร่วม ซึ่งก็คือ 0.1ms จะทำให้ SysTick ต้องทำงานถี่มากกว่าที่จำเป็น
กรณีนี้แยก HAL Tick ไปใช้ TIM แทนจะดีกว่า แต่โดยปกติผมจะใช้ 1ms เท่ากัน
(1ms เป็นค่า Default ของทั้ง HAL Tick และ FreeRTOS Tick)

ส่วนเวลาเกิด Interrupt ขึ้น มันจะไปชนกะ Task. RTOS. หรือเปล่านั้น ส่วนใหญ่
มันอยู่ที่การเขียน Code ซะมากกว่าครับ ตัว HAL Tick เองไม่ได้มีผลกระทบอะไรเท่าไหร่ครับ
แค่ count ตัวแปรเฉยๆ ส่วน FreeRTOS ก็เอามา count ตัวแปร,
คอยสั่ง Wake Context Switch และเช็คพวก Timeout กับ Event ทั้งหลาย

โดยปกติ Task กับ Interrupt ทำงานแยกกันโดยสิ้นเชิงอยู่แล้ว โดย Task
จะมี Priority ต่ำกว่า Interrupt เวลาเกิด Interrupt ใดๆ ขึ้น ทุก Task
จะหยุดทำงานเหมือนกับถูกแช่แข็ง รวมทั้งตัว FreeRTOS เองก็หยุดการทำงานด้วย
ระหว่างนี้ CPU จะไป Process Interrupt แทน ระหว่างที่อยู่ใน Interrupt นี้จะทำอะไรก็ได้
เขียน Code ให้มันไปแก้ค่าตัวแปรของ Task ก็ได้ แอบไป Free memory ทิ้งก็ได้
เดี๋ยวพอออกจาก Interrupt ปั๊บ พวก Task หลุดจากการถูกแช่แข็ง ก็จะบันเทิงเอง ;D

ปล. เนื่องจาก FreeRTOS หยุดการทำงานในเวลาที่เกิด Interrupt ขึ้นแน่นอนว่า
      มันจะทำให้ API ที่เกี่ยวกับ FreeRTOS ส่วนใหญ่ใช้ไม่ได้ FreeRTOS เลยต้องทำ
      API สำหรับใช้ใน Interrupt โดยเฉพาะให้
      (API จริงๆ ของ FreeRTOS นะ ไม่ใช่ CMSIS OS)
Title: Re: การใช้งาน RTOS บน Cube MX
Post by: empirejrz on December 29, 2017, 11:11:30 PM
ขอบคุณครับ. ผมเข้าใจขึ้นเยอะเลย